Subject: [PATCH] make cygipc semaphores persistent
From: Joe Buehler <[email-masked]>
To: [email-masked]
Date: Thu, 19 Jun 2003 14:50:34 -0400

The semaphores provided by the 1.14-1 version of cygipc are not persistent -- once
all client processes close a semaphore, it disappears.  This is different than standard
UNIX semantics, in which semaphores persist until removed or system reboot.  The
attached patch fixes this, providing the standard UNIX semantics for semaphore lifetime.
(Semaphores will persist until ipc-daemon is killed).

I would appreciate it if the owner(s) of cygipc review this patch and roll it in
to the "official" distribution if it looks OK.  The basic trick is that the ipc-daemon
process needs to keep an open handle for all semaphores in a non-removed state.
It looks as though there was code in cygipc that attempted this, but it was removed in
version 1.04.

I have included a couple typo fixes in the patch also.
-- 
Joe Buehler

--- ipc-daemon.c.orig	2002-11-13 15:36:53.000000000 -0500
+++ ipc-daemon.c	2003-06-19 14:20:43.000000000 -0400
@@ -104,6 +104,9 @@
 SERVICE_STATUS ss;
 HANDLE hStopEvent = NULL;
 
+/* handles to semaphores, so they stay in existence as long as daemon is running */
+HANDLE *semaphore_handles[SEMMNI];
+
 static void msg_init (CYGWIN_IPCNT_MSGSTR *ShareAdr)
 {
 	int id, msg;
@@ -210,7 +213,7 @@
         CloseHandle ( GSemShm ) ;
       }
       GSemShm = CreateSemaphore(tight_security ? NULL : &sa, 1, 1, CYGWIN_IPCNT_SEMSHM) ;
-      if( GSemSem == NULL )
+      if( GSemShm == NULL )
       {
         log_message(stderr, LOG_ERR, "Unable to create \"Shm\" semaphore" ) ;
         goto endko ;
@@ -221,7 +224,7 @@
         CloseHandle ( GSemMsg ) ;
       }
       GSemMsg = CreateSemaphore(tight_security ? NULL : &sa, 1, 1, CYGWIN_IPCNT_SEMMSG) ; ;
-      if( GSemSem == NULL )
+      if( GSemMsg == NULL )
       {
         log_message(stderr, LOG_ERR, "Unable to create \"Msg\" semaphore" ) ;
         goto endko ;
@@ -334,7 +337,17 @@
             {
               sma = (struct semid_ds *) ((char *) LAdrSem->semary[id] +
           						(int) LAdrSem) ;
-              if (LAdrSem->state[id] == 1)
+              if (LAdrSem->state[id] == 0) /* ready to be used */
+              {
+                semaphore_handles[id] = malloc(sma->sem_nsems * sizeof(HANDLE));
+                for (Index = 0; Index < sma->sem_nsems; Index++)
+                {
+                  name_mangle(100*id+Index, LBuff) ;
+                  semaphore_handles[id][Index] = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, LBuff) ;
+                }
+                LAdrSem->state[id]  = 2 ; /* normal operation, handles allocated */
+              }
+              else if (LAdrSem->state[id] == 1) /* client requested cleanup */
               {
                 for (Index = 0; Index < sma->sem_nsems; Index++)
                 {
@@ -344,20 +357,17 @@
                     ;
                   LAdrSem->current_nb[id].current_nb[Index] = 0;
                   CloseHandle(LHandle) ;
+                  CloseHandle(semaphore_handles[id][Index]) ;
                 }
+                free(semaphore_handles[id]);
+                semaphore_handles[id] = 0;
                 LAdrSem->semary[id] = (struct semid_ds *) IPC_UNUSED ;
-                LAdrSem->state[id]  = 0 ;
+                LAdrSem->state[id]  = 0 ; /* ready to be used */
               }
-/*
-              else
+              else if (LAdrSem->state[id] == 2) /* normal operation */
               {
-                for (Index = 0; Index < sma->sem_nsems; Index++)
-                {
-                  name_mangle(100*id+Index, LBuff) ;
-                  LHandle = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, LBuff) ;
-                }
+                  /* nothing to do here currently */
               }
-*/
             }
           } /* for (id ... ) */

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/