DosSemWait
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"); } }