diff --git a/src/backend/port/unix_latch.c b/src/backend/port/unix_latch.c index e1cb6f219e..d5d6143289 100644 --- a/src/backend/port/unix_latch.c +++ b/src/backend/port/unix_latch.c @@ -77,7 +77,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/port/unix_latch.c,v 1.3 2010/09/13 18:01:20 heikki Exp $ + * $PostgreSQL: pgsql/src/backend/port/unix_latch.c,v 1.4 2010/09/15 10:06:21 heikki Exp $ * *------------------------------------------------------------------------- */ @@ -129,8 +129,10 @@ InitLatch(volatile Latch *latch) * is initially owned by no-one, use OwnLatch to associate it with the * current process. * - * NB: When you introduce a new shared latch, you must increase the shared - * latch count in NumSharedLatches in win32_latch.c! + * InitSharedLatch needs to be called in postmaster before forking child + * processes, usually right after allocating the shared memory block + * containing the latch with ShmemInitStruct. The Unix implementation + * doesn't actually require that, but the Windows one does. */ void InitSharedLatch(volatile Latch *latch) @@ -322,29 +324,6 @@ ResetLatch(volatile Latch *latch) latch->is_set = false; } -/* - * LatchShmemSize - * Compute space needed for latch's shared memory - * - * Not needed for Unix implementation. - */ -Size -LatchShmemSize(void) -{ - return 0; -} - -/* - * LatchShmemInit - * Allocate and initialize shared memory needed for latches - * - * Not needed for Unix implementation. - */ -void -LatchShmemInit(void) -{ -} - /* * SetLatch uses SIGUSR1 to wake up the process waiting on the latch. Wake * up WaitLatch. diff --git a/src/backend/port/win32_latch.c b/src/backend/port/win32_latch.c index f6d4920e46..a36d1b6ee5 100644 --- a/src/backend/port/win32_latch.c +++ b/src/backend/port/win32_latch.c @@ -3,14 +3,16 @@ * win32_latch.c * Windows implementation of latches. * - * The Windows implementation uses Windows events. See unix_latch.c for - * information on usage. + * See unix_latch.c for information on usage. + * + * The Windows implementation uses Windows events that are inherited by + * all postmaster child processes. * * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/port/win32_latch.c,v 1.1 2010/09/11 15:48:04 heikki Exp $ + * $PostgreSQL: pgsql/src/backend/port/win32_latch.c,v 1.2 2010/09/15 10:06:21 heikki Exp $ * *------------------------------------------------------------------------- */ @@ -24,83 +26,60 @@ #include "replication/walsender.h" #include "storage/latch.h" #include "storage/shmem.h" -#include "storage/spin.h" -/* - * Shared latches are implemented with Windows events that are shared by - * all postmaster child processes. At postmaster startup we create enough - * Event objects, and mark them as inheritable so that they are accessible - * in child processes. The handles are stored in sharedHandles. - */ -typedef struct -{ - slock_t mutex; /* protects all the other fields */ - - int maxhandles; /* number of shared handles created */ - int nfreehandles; /* number of free handles in array */ - HANDLE handles[1]; /* free handles, variable length */ -} SharedEventHandles; - -static SharedEventHandles *sharedHandles; void InitLatch(volatile Latch *latch) { - latch->event = CreateEvent(NULL, TRUE, FALSE, NULL); - latch->is_shared = false; latch->is_set = false; + latch->owner_pid = MyProcPid; + latch->is_shared = false; + + latch->event = CreateEvent(NULL, TRUE, FALSE, NULL); + if (latch->event == NULL) + elog(ERROR, "CreateEvent failed: error code %d", (int) GetLastError()); } void InitSharedLatch(volatile Latch *latch) { - latch->is_shared = true; + SECURITY_ATTRIBUTES sa; + latch->is_set = false; - latch->event = NULL; + latch->owner_pid = 0; + latch->is_shared = true; + + /* + * Set up security attributes to specify that the events are + * inherited. + */ + ZeroMemory(&sa, sizeof(sa)); + sa.nLength = sizeof(sa); + sa.bInheritHandle = TRUE; + + latch->event = CreateEvent(&sa, TRUE, FALSE, NULL); + if (latch->event == NULL) + elog(ERROR, "CreateEvent failed: error code %d", (int) GetLastError()); } void OwnLatch(volatile Latch *latch) { - HANDLE event; - /* Sanity checks */ Assert(latch->is_shared); - if (latch->event != 0) + if (latch->owner_pid != 0) elog(ERROR, "latch already owned"); - /* Reserve an event handle from the shared handles array */ - SpinLockAcquire(&sharedHandles->mutex); - if (sharedHandles->nfreehandles <= 0) - { - SpinLockRelease(&sharedHandles->mutex); - elog(ERROR, "out of shared event objects"); - } - sharedHandles->nfreehandles--; - event = sharedHandles->handles[sharedHandles->nfreehandles]; - SpinLockRelease(&sharedHandles->mutex); - - latch->event = event; + latch->owner_pid = MyProcPid; } void DisownLatch(volatile Latch *latch) { Assert(latch->is_shared); - Assert(latch->event != NULL); + Assert(latch->owner_pid == MyProcPid); - /* Put the event handle back to the pool */ - SpinLockAcquire(&sharedHandles->mutex); - if (sharedHandles->nfreehandles >= sharedHandles->maxhandles) - { - SpinLockRelease(&sharedHandles->mutex); - elog(PANIC, "too many free event handles"); - } - sharedHandles->handles[sharedHandles->nfreehandles] = latch->event; - sharedHandles->nfreehandles++; - SpinLockRelease(&sharedHandles->mutex); - - latch->event = NULL; + latch->owner_pid = 0; } bool @@ -217,68 +196,3 @@ ResetLatch(volatile Latch *latch) { latch->is_set = false; } - -/* - * Number of shared latches, used to allocate the right number of shared - * Event handles at postmaster startup. You must update this if you - * introduce a new shared latch! - */ -static int -NumSharedLatches(void) -{ - int numLatches = 0; - - /* Each walsender needs one latch */ - numLatches += max_wal_senders; - - return numLatches; -} - -/* - * LatchShmemSize - * Compute space needed for latch's shared memory - */ -Size -LatchShmemSize(void) -{ - return offsetof(SharedEventHandles, handles) + - NumSharedLatches() * sizeof(HANDLE); -} - -/* - * LatchShmemInit - * Allocate and initialize shared memory needed for latches - */ -void -LatchShmemInit(void) -{ - Size size = LatchShmemSize(); - bool found; - - sharedHandles = ShmemInitStruct("SharedEventHandles", size, &found); - - /* If we're first, initialize the struct and allocate handles */ - if (!found) - { - int i; - SECURITY_ATTRIBUTES sa; - - /* - * Set up security attributes to specify that the events are - * inherited. - */ - ZeroMemory(&sa, sizeof(sa)); - sa.nLength = sizeof(sa); - sa.bInheritHandle = TRUE; - - SpinLockInit(&sharedHandles->mutex); - sharedHandles->maxhandles = NumSharedLatches(); - sharedHandles->nfreehandles = sharedHandles->maxhandles; - for (i = 0; i < sharedHandles->maxhandles; i++) - { - sharedHandles->handles[i] = CreateEvent(&sa, TRUE, FALSE, NULL); - if (sharedHandles->handles[i] == NULL) - elog(ERROR, "CreateEvent failed: error code %d", (int) GetLastError()); - } - } -} diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c index 881dae830c..666c015ded 100644 --- a/src/backend/storage/ipc/ipci.c +++ b/src/backend/storage/ipc/ipci.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.105 2010/09/11 15:48:04 heikki Exp $ + * $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.106 2010/09/15 10:06:21 heikki Exp $ * *------------------------------------------------------------------------- */ @@ -30,7 +30,6 @@ #include "replication/walsender.h" #include "storage/bufmgr.h" #include "storage/ipc.h" -#include "storage/latch.h" #include "storage/pg_shmem.h" #include "storage/pmsignal.h" #include "storage/procarray.h" @@ -118,7 +117,6 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port) size = add_size(size, SInvalShmemSize()); size = add_size(size, PMSignalShmemSize()); size = add_size(size, ProcSignalShmemSize()); - size = add_size(size, LatchShmemSize()); size = add_size(size, BgWriterShmemSize()); size = add_size(size, AutoVacuumShmemSize()); size = add_size(size, WalSndShmemSize()); @@ -219,7 +217,6 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port) */ PMSignalShmemInit(); ProcSignalShmemInit(); - LatchShmemInit(); BgWriterShmemInit(); AutoVacuumShmemInit(); WalSndShmemInit(); diff --git a/src/include/storage/latch.h b/src/include/storage/latch.h index 2c697741e4..0c0b01ca19 100644 --- a/src/include/storage/latch.h +++ b/src/include/storage/latch.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/storage/latch.h,v 1.1 2010/09/11 15:48:04 heikki Exp $ + * $PostgreSQL: pgsql/src/include/storage/latch.h,v 1.2 2010/09/15 10:06:21 heikki Exp $ * *------------------------------------------------------------------------- */ @@ -25,9 +25,8 @@ typedef struct { sig_atomic_t is_set; bool is_shared; -#ifndef WIN32 int owner_pid; -#else +#ifdef WIN32 HANDLE event; #endif } Latch; @@ -46,9 +45,6 @@ extern void SetLatch(volatile Latch *latch); extern void ResetLatch(volatile Latch *latch); #define TestLatch(latch) (((volatile Latch *) latch)->is_set) -extern Size LatchShmemSize(void); -extern void LatchShmemInit(void); - /* * Unix implementation uses SIGUSR1 for inter-process signaling, Win32 doesn't * need this.