DosSemWait

From EDM2
Jump to: navigation, search

This call blocks the current thread until an indicated semaphore clears, but does not establish ownership of the semaphore.

Syntax

DosSemWait (SemHandle, Timeout)

Parameters

SemHandle (HSEM) - input 
Reference to the semaphore.
For a system semaphore, this reference is the handle returned by a DosCreateSem or DosOpenSem request that granted the requesting thread access to the semaphore.
For a RAM semaphore, this reference is the address of a doubleword of storage, allocated and initialized to zero by the application. This sets the semaphore as unowned. Other than initializing the doubleword to zero, an application must not modify a RAM semaphore directly; instead it manipulates the semaphore with semaphore function calls.
Timeout (LONG) - input  
Action taken by the requesting thread when the semaphore is set. The values that can be specified are:
-1 - The requesting thread waits indefinitely for the semaphore to be cleared.
0 - The requesting thread returns immediately.
>0 - The requesting thread waits the indicated number of milliseconds for the semaphore to be cleared before resuming execution.

Return Code

rc (USHORT) - return
Return code descriptions are:
  • 0 NO_ERROR
  • 95 ERROR_INTERRUPT
  • 121 ERROR_SEM_TIMEOUT

Remarks

The unblocking of a thread blocked by a DosSemWait is level-triggered. That is, DosSemWait does not return until the semaphore remains clear long enough for the affected thread to be redispatched and determine that the semaphore is clear.

When an application needs to guarantee that another event has occurred before continuing, it calls DosSemSetWait. DosSemSetWait combines the functions of DosSemSet and DosSemWait and is used when there is a chance the semaphore may be cleared by a thread that gets an intervening time slice between calls by the current thread to set the semaphore and wait until it is cleared. Issuing DosSemWait on a semaphore that has been cleared has no effect; the thread continues to execute.

Bindings

C

#define INCL_DOSSEMAPHORES

USHORT  rc = DosSemWait(SemHandle, Timeout);

HSEM    SemHandle;     /* Semaphore handle */
LONG    Timeout;       /* Timeout (in milliseconds) */

USHORT  rc;            /* return code */

MASM

EXTRN  DosSemWait:FAR
INCL_DOSSEMAPHORES  EQU 1

PUSH   DWORD   SemHandle   ;Semaphore handle
PUSH   DWORD   Timeout     ;Timeout (in milliseconds)
CALL   DosSemWait

Returns WORD

Example

The following example illustrates the notification of an event between threads of different processes. Process1 creates a nonexclusive system semaphore named process1.sem and sets it. It then invokes process2 to run asynchronously. Process1 then waits, with a timeout of 4.5 seconds, for process2 to open the semaphore and clear it, thereby notifying process1 to resume. Notice that there is a small possibility of process1's missing the notification because process2 may clear the semaphore before process1 issues DosSemWait. See the example for DosSemSetWait for an alternative that would correct this.

/* ----- process1.c ---- */

#define INCL_DOSSEMAPHORES
#define INCL_DOSPROCESS

#include <os2.h>

#define SEM_NAME "\\SEM\\process1.sem" /* Semaphore name */
#define TIMEOUT 4500L                  /* Timeout period */
#define START_PROGRAM "process2.exe"   /* Name of program file */

main()
{
  HSEM          SemHandle;
  CHAR          ObjFail [50];
  PSZ           Args;
  PSZ           Envs;
  RESULTCODES   ReturnCodes;
  USHORT        rc;

  printf("Process1 now running. \n");
  rc = DosCreateSem(CSEM_PUBLIC,       /* Ownership - nonexclusive */
                    &SemHandle,        /* Semaphore handle (returned) */
                    SEM_NAME);         /* Semaphore name string */
  printf("Process1.sem created; return code is %d \n", rc);

  /*** SET the semaphore. ***/
  if((rc = DosSemSet(SemHandle)))      /* Semaphore handle */

  /****************************************/
  {
    /* Cannot set semaphore -- error processing */
  }
  /* Start a separate process */
  if(!(DosExecPgm(ObjFail,           /* Object name buffer */
                  sizeof(ObjFail),   /* Length of obj. name buffer */
                  EXEC_ASYNC,        /* Execution flag - asynchronous */
                  Args,              /* Ptr. to argument string */
                  Envs,              /* Ptr. to environment string */
                  &ReturnCodes,      /* Ptr. to resultcodes struct. */
                  START_PROGRAM)))   /* Name of program file */
    printf("Process2 started. Process1 will try to wait for notification. \n");

  /*** WAIT for a notification from process2 on process1.sem ***/
  if((rc = DosSemWait(SemHandle,     /* Semaphore handle */
                      TIMEOUT)))     /* Timeout period */

  /****************************************/
  {
    /* No notification (either interrupt or timeout); error processing */
  }
  else
  {
    /* Notification received.  Normal processing */
    printf("Process2 cleared semaphore; process1 running again. \n");
  }
}
/* ----- process2.c ----*/

#define INCL_DOSSEMAPHORES

#include <os2.h>

#define SEM_NAME "\\SEM\\process1.sem"    /* Semaphore name */

main()
{
  HSEM SemHandle;
  USHORT rc;

  /* Obtain access to semaphore created by process1 via OPEN */
  if((rc=DosOpenSem(&SemHandle,           /* Semaphore handle (returned) */
                    SEM_NAME)))           /* Semaphore Name */

  /****************************************/
  {
    /* Could not open -- error processing (switch on rc). */
  }
  else
  {
    /* Opened semaphore; normal processing.  Clear semaphore when done. */
    printf("Semaphore OPENED. \n");
    if(!(rc=DosSemClear(SemHandle)))      /* Semaphore handle */
      printf("Semaphore CLEARED. \n");
  }
}