DosCreateSem

From EDM2
Jump to: navigation, search

This call creates a system semaphore used by multiple asynchronous threads to serialize their access to resources.

Syntax

DosCreateSem (NoExclusive, SemHandle, SemName)

Parameters

NoExclusive (USHORT) - input 
Indicates whether or not the process creating the semaphore wants exclusive use of the semaphore. The meanings for the settings of this flag are:
0 - The creating process has exclusive use of the semaphore. Only threads of the creating process may alter the state of the semaphore with semaphore function calls.
1 - The creating process has nonexclusive use of the semaphore. Threads of other processes, as well as those of the creating process, may alter the state of the semaphore with semaphore function calls.
SemHandle (PHSYSSEM) - output 
Address of handle of the new system semaphore.
SemName (PSZ) - input 
Address of the name of the system semaphore. A system semaphore is defined within the file system name space as a pseudo file; thus, a semaphore has a full path name. The ASCIIZ string specifying the name must include \SEM\ as the first element of the path. For example, \SEM\RETRIEVE\SIGNAL.SEM is a valid semaphore name.
Although a system semaphore name takes the form of a file in a subdirectory called \SEM, this subdirectory does not exist. System semaphores and their names are kept in memory.
If your application provides long name support for an installable file system, a semaphore name is not restricted to the DOS 8.3 filename format.

Return Code

rc (USHORT) - return
Return code descriptions are:
  • 0 NO_ERROR
  • 87 ERROR_INVALID_PARAMETER
  • 100 ERROR_TOO_MANY_SEMAPHORES
  • 123 ERROR_INVALID_NAME
  • 183 ERROR_ALREADY_EXISTS

Remarks

A call to DosCreateSem creates a system semaphore, which can be manipulated by threads issuing semaphore function calls. Manipulation of a system semaphore is most often used to control access to a serially reusable resource. Manipulation of the semaphore is also used to signal the occurrence of an event to waiting threads.

To control access to a serially reusable resource, a process creates the system semaphore with a call to DosCreateSem. If the users of the resource are asynchronous threads of the creating process, NoExclusive=0 is specified to create an exclusive system semaphore. If the users of the resource include threads of other processes, NoExclusive=1 is specified to create a nonexclusive system semaphore.

DosCreateSem returns a semaphore handle used by the creating process and any of its threads to access the semaphore. If the semaphore is nonexclusive, a process other than the semaphore creator calls DosOpenSem for a handle to access the semaphore.

Ownership of the system semaphore is established by a successful DosSemRequest call. If another thread issues DosSemRequest while the semaphore is owned, the thread can block and wait for the semaphore to become available, or it can return immediately.

After accessing the resource, the owning thread can clear the semaphore by a call to DosSemClear. If the semaphore is an exclusive system semaphore, it has a use count associated with it, which is incremented by DosSemRequest calls and decremented by DosSemClear calls. The semaphore is not actually cleared and made available to the next thread waiting to use the resource until the semaphore has been cleared the same number of times it has been requested. This means that exclusive system semaphores can be used in recursive routines.

If a process has created a nonexclusive system semaphore and terminates while the semaphore is open, the system closes the handle to the semaphore that was returned by DosCreateSem. If the process is currently holding the semaphore when it terminates, OS/2 clears the semaphore and returns ERROR_SEM_OWNER_DIED to the next thread that gets the resource because of a DosSemRequest call. This error message alerts the holder of the semaphore that the semaphore owner may have ended abnormally; consequently, the resource is in an indeterminate state. The thread should take appropriates steps to protect the integrity of the resource. Upon completion of cleanup activity, the thread can release the semaphore by calling DosSemClear. This call resets the error condition flagged in the semaphore data structure and makes the semaphore available to the next user of the resource. The semaphore remains available to all processes that obtained handles to it with DosOpenSem requests until they call DosCloseSem to release the semaphore handles.

If a process has created an exclusive system semaphore and terminates while the semaphore is open, ownership of the semaphore is transferred to the thread executing any exit list routines. If no exit list routines have been identified to the system with DosExitList, the system closes the handle to the semaphore.

In addition to controlling access to serially reusable resources, a nonexclusive system semaphore is also used to signal an event, such as the removal of an element from a queue, to other processes. A process that sets the semaphore waits for another process to clear the semaphore, signaling the event. When the signaling process issues a DosSemClear, any waiting threads resume execution. Calls that support setting and waiting upon a nonexclusive semaphore by one or more threads are DosSemSet, DosSemWait, DosSemSetWait, and DosMuxSemWait.

Note
If a thread needs to signal another thread of the same process, a RAM semaphore is used.

Bindings

C

#define INCL_DOSSEMAPHORES

USHORT  rc = DosCreateSem(NoExclusive, SemHandle, SemName);

USHORT     NoExclusive;   /* Indicate no exclusive ownership */
PHSYSSEM   SemHandle;     /* Semaphore handle (returned) */
PSZ        SemName;       /* Semaphore name string */

USHORT     rc;            /* return code */

MASM

EXTRN  DosCreateSem:FAR
INCL_DOSSEMAPHORES  EQU 1

PUSH   WORD    NoExclusive   ;Indicate no exclusive ownership
PUSH@  DWORD   SemHandle     ;Semaphore handle (returned)
PUSH@  ASCIIZ  SemName       ;Semaphore name string
CALL   DosCreateSem

Returns WORD

Example

This example creates a semaphore named timeout.sem.

#define INCL_DOSSEMAPHORES

#define SEM_OWNERSHIP 0
#define SEM_NAME "\\SEM\\timeout.sem"

HSEM   SemHandle;
USHORT rc;

   rc = DosCreateSem(SEM_OWNERSHIP,    /* Indicate ownership */
                     &SemHandle,       /* Semaphore handle */
                     SEM_NAME);        /* Semaphore name string */

The following example illustrates the serialization of access to a shared resource between threads of the same process. The program creates a nonexclusive system semaphore named resource.sem, requests access to the semaphore, clears it, and finally closes the semaphore. For an illustration of notification of events, see the example given in DosOpenSem, DosSemSet, or DosSemWait.

#define INCL_DOSSEMAPHORES

#include <os2.h>

#define SEM_NAME "\\SEM\\resource.sem"  /* Semaphore name */
#define TIMEOUT 1500L                   /* Timeout (in milliseconds) */

main()
{
  HSEM SemHandle;
  USHORT rc;

  /* Note: the semaphore could have been created by another    */
  /*       thread.                                             */
  DosCreateSem(CSEM_PUBLIC,         /* Ownership - nonexclusive */
               &SemHandle,          /* Semaphore handle (returned) */
               SEM_NAME);           /* Semaphore name */
  if(!(rc = DosSemRequest(SemHandle,       /* Semaphore Handle */
                         TIMEOUT)))        /* Timeout Period   */
  {
    /* Semaphore obtained; resource may now be used. */
    /* Clear the semaphore after using resource.     */
    if(DosSemClear(SemHandle))
    {
      /* Semaphore exclusively owned by another process --  */
      /* cannot clear now.                                  */
    }
  }
  else
  {
    /* Semaphore not obtained: error processing (i.e. switch on rc) */
  }
  /* Semaphore no longer needed; close it */
  if(DosCloseSem(SemHandle))
  {
    /* Semaphore is still set -- cannot close now */
  }
}