]> granicus.if.org Git - postgresql/commitdiff
attached is a patch that makes SysV semaphore emulation
authorBruce Momjian <bruce@momjian.us>
Wed, 17 Jan 2001 22:11:19 +0000 (22:11 +0000)
committerBruce Momjian <bruce@momjian.us>
Wed, 17 Jan 2001 22:11:19 +0000 (22:11 +0000)
using POSIX semaphores more robust on Darwin 1.2/Mac OS X
Public Beta.  this is for the version of 7.1 available
via anon cvs as of Jan 14 2001 14:00 PST.

since the semaphores and shared memory created by this
emulator are shared with the backends via fork(), their
persistent names are not necessary.  removing their
names with shm_unlink() and sem_unlink() after creation
obviates the need for any "ipcclean" function.  further,
without these changes, the shared memory (and, therefore,
the semaphores) will not be re-initialized/re-created after
the first execution of the postmaster, until reboot
or until some (non-existent) ipcclean function is executed.

this patch does the following:

   1) if the shared memory segment "SysV_Sem_Info" already
      existed, it is cleaned up.  it shouldn't be there anyways.

   2) the real indicator for whether the shared memory/semaphore
      emulator has been initialized is if "SemInfo" has been
      initialized.  the shared memory and semaphores must be
      initialized regardless of whether there was a garbage shared
      memory segment lying around.

   3) the shared memory segment "SysV_Sem_Info" is created with "O_EXCL"
      to catch the case where two postmasters might be starting
      simultaneously, so they don't both end up with the same shared
      memory (one will fail).  note that this can't be done with the
      semaphores because Darwin 1.2 has a bug where attempting to
      open an existing semaphore with "O_EXCL" set will ruin the
      semaphore until the next reboot.

   4) the shared memory segment "SysV_Sem_Info" is unlinked after
      it is created.  it will then exist without a name until the
      postmaster and all backend children exit.
   5) all semaphores are unlinked after they are created.  they'll
      then exist without names until the postmaster and all backend
      children exit.

-michael thornburgh, zenomt@armory.com

src/backend/port/darwin/sem.c

index c55090cedc2e342c04dbe3a2267736a704610ffc..7dc7b0c919402fbc715d80dbbbbe1ab76c13ffe8 100644 (file)
@@ -10,7 +10,7 @@
  *   - this required changing sem_info from containig an array of sem_t to an array of sem_t*
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/port/darwin/Attic/sem.c,v 1.1 2000/12/11 00:49:54 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/port/darwin/Attic/sem.c,v 1.2 2001/01/17 22:11:19 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -155,11 +155,13 @@ semget(key_t key, int nsems, int semflg)
                fd = shm_open(SHM_INFO_NAME, O_RDWR | O_CREAT | O_EXCL, MODE);
                if (fd == -1 && errno == EEXIST)
                {
-                       exist = 1;
-                       fd = shm_open(SHM_INFO_NAME, O_RDWR | O_CREAT, MODE);
+/*                     exist = 1; */
+                       shm_unlink(SHM_INFO_NAME);
+                       fd = shm_open(SHM_INFO_NAME, O_RDWR | O_CREAT | O_EXCL, MODE);
                }
                if (fd == -1)
                        return fd;
+               shm_unlink(SHM_INFO_NAME);
                /* The size may only be set once. Ignore errors. */
                ftruncate(fd, sizeof(struct sem_info));
                SemInfo = mmap(NULL, sizeof(struct sem_info),
@@ -174,6 +176,7 @@ semget(key_t key, int nsems, int semflg)
                        fprintf(stderr, "darwin creating sem %s to cover shared mem.\n", semname);
 #endif
                        SemInfo->sem = sem_open(semname, O_CREAT, semflg & 0777, 1);
+                       sem_unlink(semname);
                        sem_wait(SemInfo->sem);
                        /* initilize shared memory */
                        memset(SemInfo->set, 0, sizeof(SemInfo->set));
@@ -244,6 +247,7 @@ fprintf(stderr, "darwin semget failed because if (nsems != 0 && SemInfo->set[sem
                fprintf(stderr, "darwin creating sem %s to cover set %d num %dm.\n", semname, semid, semnum);
 #endif
                SemInfo->set[semid].sem[semnum] = sem_open(semname, O_CREAT, semflg & 0777, 0);
+               sem_unlink(semname);
 
 /* Currently sem_init always returns -1.
        if( sem_init( &SemInfo->set[semid].sem[semnum], 1, 0 ) == -1 )  {