Skip to content

Commit 908f317

Browse files
committed
Add Win32 semaphore implementation, rather than mimicking SysV
semaphores. Qingqing Zhou
1 parent 291724d commit 908f317

File tree

3 files changed

+215
-10
lines changed

3 files changed

+215
-10
lines changed

configure.in

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
dnl Process this file with autoconf to produce a configure script.
2-
dnl $PostgreSQL: pgsql/configure.in,v 1.462 2006/04/29 00:51:41 momjian Exp $
2+
dnl $PostgreSQL: pgsql/configure.in,v 1.463 2006/04/29 16:34:41 momjian Exp $
33
dnl
44
dnl Developers, please strive to achieve this order:
55
dnl
@@ -1269,17 +1269,22 @@ AC_FUNC_MEMCMP
12691269

12701270

12711271
# Select semaphore implementation type.
1272-
if test x"$USE_NAMED_POSIX_SEMAPHORES" = x"1" ; then
1273-
AC_DEFINE(USE_NAMED_POSIX_SEMAPHORES, 1, [Define to select named POSIX semaphores.])
1274-
SEMA_IMPLEMENTATION="src/backend/port/posix_sema.c"
1275-
else
1276-
if test x"$USE_UNNAMED_POSIX_SEMAPHORES" = x"1" ; then
1277-
AC_DEFINE(USE_UNNAMED_POSIX_SEMAPHORES, 1, [Define to select unnamed POSIX semaphores.])
1272+
if test "$PORTNAME" != "win32"; then
1273+
if test x"$USE_NAMED_POSIX_SEMAPHORES" = x"1" ; then
1274+
AC_DEFINE(USE_NAMED_POSIX_SEMAPHORES, 1, [Define to select named POSIX semaphores.])
12781275
SEMA_IMPLEMENTATION="src/backend/port/posix_sema.c"
12791276
else
1280-
AC_DEFINE(USE_SYSV_SEMAPHORES, 1, [Define to select SysV-style semaphores.])
1281-
SEMA_IMPLEMENTATION="src/backend/port/sysv_sema.c"
1277+
if test x"$USE_UNNAMED_POSIX_SEMAPHORES" = x"1" ; then
1278+
AC_DEFINE(USE_UNNAMED_POSIX_SEMAPHORES, 1, [Define to select unnamed POSIX semaphores.])
1279+
SEMA_IMPLEMENTATION="src/backend/port/posix_sema.c"
1280+
else
1281+
AC_DEFINE(USE_SYSV_SEMAPHORES, 1, [Define to select SysV-style semaphores.])
1282+
SEMA_IMPLEMENTATION="src/backend/port/sysv_sema.c"
1283+
fi
12821284
fi
1285+
else
1286+
AC_DEFINE(USE_WIN32_SEMAPHORES, 1, [Define to select Win32-style semaphores.])
1287+
SEMA_IMPLEMENTATION="src/backend/port/win32_sema.c"
12831288
fi
12841289

12851290

src/backend/port/win32_sema.c

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* win32_sema.c
4+
* Microsoft Windows Win32 Semaphores Emulation
5+
*
6+
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
7+
*
8+
* IDENTIFICATION
9+
* $Header: /cvsroot/pgsql/src/backend/port/win32_sema.c,v 1.1 2006/04/29 16:34:41 momjian Exp $
10+
*
11+
*-------------------------------------------------------------------------
12+
*/
13+
14+
#include "postgres.h"
15+
16+
#include "miscadmin.h"
17+
#include "storage/ipc.h"
18+
#include "storage/pg_sema.h"
19+
20+
static HANDLE *mySemSet; /* IDs of sema sets acquired so far */
21+
static int numSems; /* number of sema sets acquired so far */
22+
static int maxSems; /* allocated size of mySemaSet array */
23+
24+
static void ReleaseSemaphores(int code, Datum arg);
25+
26+
/*
27+
* PGReserveSemaphores --- initialize semaphore support
28+
*
29+
* In the Win32 implementation, we acquire semaphores on-demand; the
30+
* maxSemas parameter is just used to size the array that keeps track of
31+
* acquired semas for subsequent releasing. We use anonymous semaphores
32+
* so the semaphores are automatically freed when the last referencing
33+
* process exits.
34+
*/
35+
void PGReserveSemaphores(int maxSemas, int port)
36+
{
37+
mySemSet = (HANDLE *)malloc(maxSemas * sizeof(HANDLE));
38+
if (mySemSet == NULL)
39+
elog(PANIC, "out of memory");
40+
numSems = 0;
41+
maxSems = maxSemas;
42+
43+
on_shmem_exit(ReleaseSemaphores, 0);
44+
}
45+
46+
/*
47+
* Release semaphores at shutdown or shmem reinitialization
48+
*
49+
* (called as an on_shmem_exit callback, hence funny argument list)
50+
*/
51+
static void
52+
ReleaseSemaphores(int code, Datum arg)
53+
{
54+
int i;
55+
56+
for (i = 0; i < numSems; i++)
57+
CloseHandle(mySemSet[i]);
58+
free(mySemSet);
59+
}
60+
61+
/*
62+
* PGSemaphoreCreate
63+
*
64+
* Initialize a PGSemaphore structure to represent a sema with count 1
65+
*/
66+
void PGSemaphoreCreate(PGSemaphore sema)
67+
{
68+
HANDLE cur_handle;
69+
SECURITY_ATTRIBUTES sec_attrs;
70+
71+
/* Can't do this in a backend, because static state is postmaster's */
72+
Assert(!IsUnderPostmaster);
73+
74+
if (numSems >= maxSems)
75+
elog(PANIC, "too many semaphores created");
76+
77+
ZeroMemory(&sec_attrs, sizeof(sec_attrs));
78+
sec_attrs.nLength = sizeof(sec_attrs);
79+
sec_attrs.lpSecurityDescriptor = NULL;
80+
sec_attrs.bInheritHandle = TRUE;
81+
82+
/* We don't need a named semaphore */
83+
cur_handle = CreateSemaphore(&sec_attrs, 1, 1, NULL);
84+
if (cur_handle)
85+
{
86+
/* Successfully done */
87+
*sema = cur_handle;
88+
mySemSet[numSems++] = cur_handle;
89+
}
90+
else
91+
ereport(PANIC,
92+
(errmsg("could not create semaphore: error code %d", (int)GetLastError())));
93+
}
94+
95+
/*
96+
* PGSemaphoreReset
97+
*
98+
* Reset a previously-initialized PGSemaphore to have count 0
99+
*/
100+
void PGSemaphoreReset(PGSemaphore sema)
101+
{
102+
/*
103+
* There's no direct API for this in Win32, so we have to ratchet the
104+
* semaphore down to 0 with repeated trylock's.
105+
*/
106+
while (PGSemaphoreTryLock(sema));
107+
}
108+
109+
/*
110+
* PGSemaphoreLock
111+
*
112+
* Lock a semaphore (decrement count), blocking if count would be < 0.
113+
* Serve the interrupt if interruptOK is true.
114+
*/
115+
void PGSemaphoreLock(PGSemaphore sema, bool interruptOK)
116+
{
117+
DWORD ret;
118+
HANDLE wh[2];
119+
120+
wh[0] = *sema;
121+
wh[1] = pgwin32_signal_event;
122+
123+
do
124+
{
125+
ImmediateInterruptOK = interruptOK;
126+
CHECK_FOR_INTERRUPTS();
127+
128+
errno = 0;
129+
ret = WaitForMultipleObjectsEx(2, wh, FALSE, INFINITE, TRUE);
130+
131+
if (ret == WAIT_OBJECT_0)
132+
{
133+
/* We got it! */
134+
return;
135+
}
136+
else if (ret == WAIT_OBJECT_0 + 1)
137+
{
138+
/* Signal event is set - we have a signal to deliver */
139+
pgwin32_dispatch_queued_signals();
140+
errno = EINTR;
141+
}
142+
else
143+
/* Otherwise we are in trouble */
144+
errno = EIDRM;
145+
146+
ImmediateInterruptOK = false;
147+
} while (errno == EINTR);
148+
149+
if (errno != 0)
150+
ereport(FATAL,
151+
(errmsg("could not lock semaphore: error code %d", (int) GetLastError())));
152+
}
153+
154+
/*
155+
* PGSemaphoreUnlock
156+
*
157+
* Unlock a semaphore (increment count)
158+
*/
159+
void PGSemaphoreUnlock(PGSemaphore sema)
160+
{
161+
if (!ReleaseSemaphore(*sema, 1, NULL))
162+
ereport(FATAL,
163+
(errmsg("could not unlock semaphore: error code %d", (int) GetLastError())));
164+
}
165+
166+
/*
167+
* PGSemaphoreTryLock
168+
*
169+
* Lock a semaphore only if able to do so without blocking
170+
*/
171+
bool PGSemaphoreTryLock(PGSemaphore sema)
172+
{
173+
DWORD ret;
174+
175+
ret = WaitForSingleObject(*sema, 0);
176+
177+
if (ret == WAIT_OBJECT_0)
178+
{
179+
/* We got it! */
180+
return true;
181+
}
182+
else if (ret == WAIT_TIMEOUT)
183+
{
184+
/* Can't get it */
185+
errno = EAGAIN;
186+
return false;
187+
}
188+
189+
/* Otherwise we are in trouble */
190+
ereport(FATAL,
191+
(errmsg("could not try-lock semaphore: error code %d", (int) GetLastError())));
192+
193+
/* keep compiler quiet */
194+
return false;
195+
}

src/include/storage/pg_sema.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
1414
* Portions Copyright (c) 1994, Regents of the University of California
1515
*
16-
* $PostgreSQL: pgsql/src/include/storage/pg_sema.h,v 1.8 2006/03/05 15:58:59 momjian Exp $
16+
* $PostgreSQL: pgsql/src/include/storage/pg_sema.h,v 1.9 2006/04/29 16:34:41 momjian Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -54,6 +54,11 @@ typedef struct PGSemaphoreData
5454
} PGSemaphoreData;
5555
#endif
5656

57+
#ifdef USE_WIN32_SEMAPHORES
58+
59+
typedef HANDLE PGSemaphoreData;
60+
#endif
61+
5762
typedef PGSemaphoreData *PGSemaphore;
5863

5964

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy