Commit 908f317b authored by Bruce Momjian's avatar Bruce Momjian

Add Win32 semaphore implementation, rather than mimicking SysV

semaphores.

Qingqing Zhou
parent 291724df
dnl Process this file with autoconf to produce a configure script. dnl Process this file with autoconf to produce a configure script.
dnl $PostgreSQL: pgsql/configure.in,v 1.462 2006/04/29 00:51:41 momjian Exp $ dnl $PostgreSQL: pgsql/configure.in,v 1.463 2006/04/29 16:34:41 momjian Exp $
dnl dnl
dnl Developers, please strive to achieve this order: dnl Developers, please strive to achieve this order:
dnl dnl
...@@ -1269,17 +1269,22 @@ AC_FUNC_MEMCMP ...@@ -1269,17 +1269,22 @@ AC_FUNC_MEMCMP
# Select semaphore implementation type. # Select semaphore implementation type.
if test x"$USE_NAMED_POSIX_SEMAPHORES" = x"1" ; then if test "$PORTNAME" != "win32"; then
AC_DEFINE(USE_NAMED_POSIX_SEMAPHORES, 1, [Define to select named POSIX semaphores.]) if test x"$USE_NAMED_POSIX_SEMAPHORES" = x"1" ; then
SEMA_IMPLEMENTATION="src/backend/port/posix_sema.c" AC_DEFINE(USE_NAMED_POSIX_SEMAPHORES, 1, [Define to select named POSIX semaphores.])
else
if test x"$USE_UNNAMED_POSIX_SEMAPHORES" = x"1" ; then
AC_DEFINE(USE_UNNAMED_POSIX_SEMAPHORES, 1, [Define to select unnamed POSIX semaphores.])
SEMA_IMPLEMENTATION="src/backend/port/posix_sema.c" SEMA_IMPLEMENTATION="src/backend/port/posix_sema.c"
else else
AC_DEFINE(USE_SYSV_SEMAPHORES, 1, [Define to select SysV-style semaphores.]) if test x"$USE_UNNAMED_POSIX_SEMAPHORES" = x"1" ; then
SEMA_IMPLEMENTATION="src/backend/port/sysv_sema.c" AC_DEFINE(USE_UNNAMED_POSIX_SEMAPHORES, 1, [Define to select unnamed POSIX semaphores.])
SEMA_IMPLEMENTATION="src/backend/port/posix_sema.c"
else
AC_DEFINE(USE_SYSV_SEMAPHORES, 1, [Define to select SysV-style semaphores.])
SEMA_IMPLEMENTATION="src/backend/port/sysv_sema.c"
fi
fi fi
else
AC_DEFINE(USE_WIN32_SEMAPHORES, 1, [Define to select Win32-style semaphores.])
SEMA_IMPLEMENTATION="src/backend/port/win32_sema.c"
fi fi
......
/*-------------------------------------------------------------------------
*
* win32_sema.c
* Microsoft Windows Win32 Semaphores Emulation
*
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/port/win32_sema.c,v 1.1 2006/04/29 16:34:41 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "miscadmin.h"
#include "storage/ipc.h"
#include "storage/pg_sema.h"
static HANDLE *mySemSet; /* IDs of sema sets acquired so far */
static int numSems; /* number of sema sets acquired so far */
static int maxSems; /* allocated size of mySemaSet array */
static void ReleaseSemaphores(int code, Datum arg);
/*
* PGReserveSemaphores --- initialize semaphore support
*
* In the Win32 implementation, we acquire semaphores on-demand; the
* maxSemas parameter is just used to size the array that keeps track of
* acquired semas for subsequent releasing. We use anonymous semaphores
* so the semaphores are automatically freed when the last referencing
* process exits.
*/
void PGReserveSemaphores(int maxSemas, int port)
{
mySemSet = (HANDLE *)malloc(maxSemas * sizeof(HANDLE));
if (mySemSet == NULL)
elog(PANIC, "out of memory");
numSems = 0;
maxSems = maxSemas;
on_shmem_exit(ReleaseSemaphores, 0);
}
/*
* Release semaphores at shutdown or shmem reinitialization
*
* (called as an on_shmem_exit callback, hence funny argument list)
*/
static void
ReleaseSemaphores(int code, Datum arg)
{
int i;
for (i = 0; i < numSems; i++)
CloseHandle(mySemSet[i]);
free(mySemSet);
}
/*
* PGSemaphoreCreate
*
* Initialize a PGSemaphore structure to represent a sema with count 1
*/
void PGSemaphoreCreate(PGSemaphore sema)
{
HANDLE cur_handle;
SECURITY_ATTRIBUTES sec_attrs;
/* Can't do this in a backend, because static state is postmaster's */
Assert(!IsUnderPostmaster);
if (numSems >= maxSems)
elog(PANIC, "too many semaphores created");
ZeroMemory(&sec_attrs, sizeof(sec_attrs));
sec_attrs.nLength = sizeof(sec_attrs);
sec_attrs.lpSecurityDescriptor = NULL;
sec_attrs.bInheritHandle = TRUE;
/* We don't need a named semaphore */
cur_handle = CreateSemaphore(&sec_attrs, 1, 1, NULL);
if (cur_handle)
{
/* Successfully done */
*sema = cur_handle;
mySemSet[numSems++] = cur_handle;
}
else
ereport(PANIC,
(errmsg("could not create semaphore: error code %d", (int)GetLastError())));
}
/*
* PGSemaphoreReset
*
* Reset a previously-initialized PGSemaphore to have count 0
*/
void PGSemaphoreReset(PGSemaphore sema)
{
/*
* There's no direct API for this in Win32, so we have to ratchet the
* semaphore down to 0 with repeated trylock's.
*/
while (PGSemaphoreTryLock(sema));
}
/*
* PGSemaphoreLock
*
* Lock a semaphore (decrement count), blocking if count would be < 0.
* Serve the interrupt if interruptOK is true.
*/
void PGSemaphoreLock(PGSemaphore sema, bool interruptOK)
{
DWORD ret;
HANDLE wh[2];
wh[0] = *sema;
wh[1] = pgwin32_signal_event;
do
{
ImmediateInterruptOK = interruptOK;
CHECK_FOR_INTERRUPTS();
errno = 0;
ret = WaitForMultipleObjectsEx(2, wh, FALSE, INFINITE, TRUE);
if (ret == WAIT_OBJECT_0)
{
/* We got it! */
return;
}
else if (ret == WAIT_OBJECT_0 + 1)
{
/* Signal event is set - we have a signal to deliver */
pgwin32_dispatch_queued_signals();
errno = EINTR;
}
else
/* Otherwise we are in trouble */
errno = EIDRM;
ImmediateInterruptOK = false;
} while (errno == EINTR);
if (errno != 0)
ereport(FATAL,
(errmsg("could not lock semaphore: error code %d", (int) GetLastError())));
}
/*
* PGSemaphoreUnlock
*
* Unlock a semaphore (increment count)
*/
void PGSemaphoreUnlock(PGSemaphore sema)
{
if (!ReleaseSemaphore(*sema, 1, NULL))
ereport(FATAL,
(errmsg("could not unlock semaphore: error code %d", (int) GetLastError())));
}
/*
* PGSemaphoreTryLock
*
* Lock a semaphore only if able to do so without blocking
*/
bool PGSemaphoreTryLock(PGSemaphore sema)
{
DWORD ret;
ret = WaitForSingleObject(*sema, 0);
if (ret == WAIT_OBJECT_0)
{
/* We got it! */
return true;
}
else if (ret == WAIT_TIMEOUT)
{
/* Can't get it */
errno = EAGAIN;
return false;
}
/* Otherwise we are in trouble */
ereport(FATAL,
(errmsg("could not try-lock semaphore: error code %d", (int) GetLastError())));
/* keep compiler quiet */
return false;
}
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/storage/pg_sema.h,v 1.8 2006/03/05 15:58:59 momjian Exp $ * $PostgreSQL: pgsql/src/include/storage/pg_sema.h,v 1.9 2006/04/29 16:34:41 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -54,6 +54,11 @@ typedef struct PGSemaphoreData ...@@ -54,6 +54,11 @@ typedef struct PGSemaphoreData
} PGSemaphoreData; } PGSemaphoreData;
#endif #endif
#ifdef USE_WIN32_SEMAPHORES
typedef HANDLE PGSemaphoreData;
#endif
typedef PGSemaphoreData *PGSemaphore; typedef PGSemaphoreData *PGSemaphore;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment