DosSemSet

From EDM2
Jump to: navigation, search

This call unconditionally sets a semaphore; that is, it sets the semaphore whether or not it is already set.

Syntax

DosSemSet (SemHandle)

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.

Return Code

rc (USHORT) - return
Return code descriptions are:
  • 0 NO_ERROR
  • 100 ERROR_TOO_MANY_SEMAPHORES
  • 103 ERROR_TOO_MANY_SEM_REQUESTS

Remarks

DosSemSet usually is not required in a resource control environment using DosSemRequest and DosSemClear. It typically is used in a signaling environment implemented with DosSemWait, DosMuxSemWait, and DosSemClear. These function calls are used to block one or more threads on a set semaphore and awaken them when an event occurs.

DosSemSet cannot be issued against a system semaphore that is owned by another thread, unless the NoExclusive option was set in the original DosCreateSem request.

Bindings

C

#define INCL_DOSSEMAPHORES

USHORT  rc = DosSemSet(SemHandle);

HSEM    SemHandle;     /* Semaphore handle */
USHORT  rc;            /* return code */

MASM

EXTRN  DosSemSet:FAR
INCL_DOSSEMAPHORES  EQU 1

PUSH   DWORD   SemHandle     ;Semaphore handle
CALL   DosSemSet

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