A thread can wait on a muxwait semaphore by using DosWaitMuxWaitSem.
Any thread in the process that created a muxwait semaphore can wait for the semaphore to clear by calling DosWaitMuxWaitSem. Threads in other processes can also call DosWaitMuxWaitSem, but they must first gain access to the semaphore by calling DosOpenMuxWaitSem.
The following code fragment waits for a muxwait semaphore to clear. Assume that the handle of the semaphore has been placed into hmux already. ulTimeout is the number of milliseconds that the calling thread will wait for the muxwait semaphore to clear. If the specified muxwait semaphore is not cleared during this time interval, the request times out.
#define INCL_DOSSEMAPHORES /* Semaphore values */ #include <os2.h> #include <stdio.h> HMUX hmux; /* Muxwait semaphore handle */ ULONG ulTimeout; /* Number of milliseconds to wait */ ULONG ulUser; /* User field for the semaphore that was */ /* posted or released (returned) */ APIRET ulrc; /* Return code */ ulTimeout = 60000; /* Wait for a maximum of 1 minute */ ulrc = DosWaitMuxWaitSem(hmux, ulTimeout, &ulUser); if (ulrc == ERROR_TIMEOUT) { printf("DosWaitMuxWaitSem call timed out"); return; } if (ulrc == ERROR_INTERRUPT) { printf("DosWaitMuxWaitSem call was interrupted"); return; } if (ulrc != 0) { printf("DosWaitMuxWaitSem error: return code = %ld", ulrc); return; }
On successful return, the ulUser variable contains the user identifier of the semaphore that caused the wait to terminate. If the caller had to wait for all the semaphores within the muxwait semaphore to clear, then the value corresponds to the last semaphore within the muxwait semaphore to clear. If the caller had to wait for any semaphore with the muxwait semaphore to clear, then the value corresponds to that semaphore.
An application can use the DCMW_WAIT_ANY flag in DosCreateMuxWaitSem to block a thread until any one of the event or mutex semaphores included in the muxwait semaphore is posted or released. If the muxwait semaphore refers to mutex semaphores, the thread only gains ownership of the one mutex semaphore that was released.
An application can use the DCMW_WAIT_ALL flag in DosCreateMuxWaitSem to block a thread until all of the event or mutex semaphores included in the muxwait semaphore are posted or released. If the muxwait semaphore refers to mutex semaphores, the thread does not gain ownership of any of the mutex semaphores until they are all released. When all are released, the thread becomes owner of all the mutex semaphores included in the muxwait semaphore. If the muxwait semaphore refers to event semaphores, the thread will not run until all of the event semaphores are in the posted state at the same time. This is because event semaphores in a muxwait list are level-triggered, unlike individual event semaphores, which are edge-triggered.
For example, suppose that a thread is waiting for five event semaphores in a muxwait list to be posted. The first semaphore is posted and then reset. Next, the remaining semaphores are all posted, and they remain in the posted state. The thread that is waiting for the muxwait semaphore will not run until the first semaphore is posted again.
If an application specifies the DCMW_WAIT_ANY flag when the semaphore is created, DosWaitMuxWaitSem returns the programmer-defined identifier of the semaphore that is subsequently posted or released. If an application specifies the DCMW_WAIT_ALL flag, DosWaitMuxWaitSem returns the programmer-defined identifier of the last semaphore that was posted or released.
The ulTimeout parameter places a limit on the amount of time a thread blocks on a DosWaitMuxWaitSem request. If the time limit is reached before the semaphore has cleared, ERROR_TIMEOUT is returned. If SEM_IMMEDIATE_RETURN is specified as the time limit, DosWaitMuxWaitSem returns without blocking the thread. The thread can then go on to perform other operations and call DosWaitMuxWaitSem again later to wait for the event or mutex semaphores in the muxwait list to be posted or released. If a time limit of SEM_INDEFINITE_WAIT is specified, the thread waits (is blocked) indefinitely. If the thread is unblocked by an external event while it is waiting for the muxwait semaphore (as when a "no wait" I/O request has just been completed), DosWaitMuxWaitSem returns ERROR_INTERRUPT.
When a thread is waiting for any one of the semaphores in a muxwait list to be posted or released, the semaphores are checked in the order in which they are defined in the list.
Waiting for Multiple Event Semaphores
The following information pertains only to muxwait semaphores that consist
of multiple event semaphores:
Unlike individual event semaphores, which are edge-triggered, event semaphores in a muxwait list are level-triggered. This means that if a thread is waiting for all of the event semaphores in the muxwait list, it will not run until all of the event semaphores are in the posted state at the same time.
For example, a thread is waiting for five event semaphores in a muxwait list to be posted. The first semaphore is posted and then reset. Next, the remaining semaphores are all posted, and they remain in the posted state. The thread that is waiting for the muxwait semaphore will not run until the first semaphore is posted again.
Waiting for Multiple Mutex Semaphores
The following information pertains only to muxwait semaphores that consist
of multiple mutex semaphores:
Each mutex semaphore that returns ERROR_SEM_OWNER_DIED from the query should be closed by calling DosCloseMutexSem. Also, because semaphore handles can be reused, the mutex semaphores that are closed should be deleted from the muxwait-semaphore list by calling DosDeleteMuxWaitSem.