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/