|
3 | 3 | * win32_latch.c |
4 | 4 | * Windows implementation of latches. |
5 | 5 | * |
6 | | - * The Windows implementation uses Windows events. See unix_latch.c for |
7 | | - * information on usage. |
| 6 | + * See unix_latch.c for information on usage. |
| 7 | + * |
| 8 | + * The Windows implementation uses Windows events that are inherited by |
| 9 | + * all postmaster child processes. |
8 | 10 | * |
9 | 11 | * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group |
10 | 12 | * Portions Copyright (c) 1994, Regents of the University of California |
11 | 13 | * |
12 | 14 | * IDENTIFICATION |
13 | | - * $PostgreSQL: pgsql/src/backend/port/win32_latch.c,v 1.1 2010/09/11 15:48:04 heikki Exp $ |
| 15 | + * $PostgreSQL: pgsql/src/backend/port/win32_latch.c,v 1.2 2010/09/15 10:06:21 heikki Exp $ |
14 | 16 | * |
15 | 17 | *------------------------------------------------------------------------- |
16 | 18 | */ |
|
24 | 26 | #include "replication/walsender.h" |
25 | 27 | #include "storage/latch.h" |
26 | 28 | #include "storage/shmem.h" |
27 | | -#include "storage/spin.h" |
28 | | - |
29 | | -/* |
30 | | - * Shared latches are implemented with Windows events that are shared by |
31 | | - * all postmaster child processes. At postmaster startup we create enough |
32 | | - * Event objects, and mark them as inheritable so that they are accessible |
33 | | - * in child processes. The handles are stored in sharedHandles. |
34 | | - */ |
35 | | -typedef struct |
36 | | -{ |
37 | | - slock_t mutex; /* protects all the other fields */ |
38 | 29 |
|
39 | | - int maxhandles; /* number of shared handles created */ |
40 | | - int nfreehandles; /* number of free handles in array */ |
41 | | - HANDLE handles[1]; /* free handles, variable length */ |
42 | | -} SharedEventHandles; |
43 | | - |
44 | | -static SharedEventHandles *sharedHandles; |
45 | 30 |
|
46 | 31 | void |
47 | 32 | InitLatch(volatile Latch *latch) |
48 | 33 | { |
49 | | - latch->event = CreateEvent(NULL, TRUE, FALSE, NULL); |
50 | | - latch->is_shared = false; |
51 | 34 | latch->is_set = false; |
| 35 | + latch->owner_pid = MyProcPid; |
| 36 | + latch->is_shared = false; |
| 37 | + |
| 38 | + latch->event = CreateEvent(NULL, TRUE, FALSE, NULL); |
| 39 | + if (latch->event == NULL) |
| 40 | + elog(ERROR, "CreateEvent failed: error code %d", (int) GetLastError()); |
52 | 41 | } |
53 | 42 |
|
54 | 43 | void |
55 | 44 | InitSharedLatch(volatile Latch *latch) |
56 | 45 | { |
57 | | - latch->is_shared = true; |
| 46 | + SECURITY_ATTRIBUTES sa; |
| 47 | + |
58 | 48 | latch->is_set = false; |
59 | | - latch->event = NULL; |
| 49 | + latch->owner_pid = 0; |
| 50 | + latch->is_shared = true; |
| 51 | + |
| 52 | + /* |
| 53 | + * Set up security attributes to specify that the events are |
| 54 | + * inherited. |
| 55 | + */ |
| 56 | + ZeroMemory(&sa, sizeof(sa)); |
| 57 | + sa.nLength = sizeof(sa); |
| 58 | + sa.bInheritHandle = TRUE; |
| 59 | + |
| 60 | + latch->event = CreateEvent(&sa, TRUE, FALSE, NULL); |
| 61 | + if (latch->event == NULL) |
| 62 | + elog(ERROR, "CreateEvent failed: error code %d", (int) GetLastError()); |
60 | 63 | } |
61 | 64 |
|
62 | 65 | void |
63 | 66 | OwnLatch(volatile Latch *latch) |
64 | 67 | { |
65 | | - HANDLE event; |
66 | | - |
67 | 68 | /* Sanity checks */ |
68 | 69 | Assert(latch->is_shared); |
69 | | - if (latch->event != 0) |
| 70 | + if (latch->owner_pid != 0) |
70 | 71 | elog(ERROR, "latch already owned"); |
71 | 72 |
|
72 | | - /* Reserve an event handle from the shared handles array */ |
73 | | - SpinLockAcquire(&sharedHandles->mutex); |
74 | | - if (sharedHandles->nfreehandles <= 0) |
75 | | - { |
76 | | - SpinLockRelease(&sharedHandles->mutex); |
77 | | - elog(ERROR, "out of shared event objects"); |
78 | | - } |
79 | | - sharedHandles->nfreehandles--; |
80 | | - event = sharedHandles->handles[sharedHandles->nfreehandles]; |
81 | | - SpinLockRelease(&sharedHandles->mutex); |
82 | | - |
83 | | - latch->event = event; |
| 73 | + latch->owner_pid = MyProcPid; |
84 | 74 | } |
85 | 75 |
|
86 | 76 | void |
87 | 77 | DisownLatch(volatile Latch *latch) |
88 | 78 | { |
89 | 79 | Assert(latch->is_shared); |
90 | | - Assert(latch->event != NULL); |
91 | | - |
92 | | - /* Put the event handle back to the pool */ |
93 | | - SpinLockAcquire(&sharedHandles->mutex); |
94 | | - if (sharedHandles->nfreehandles >= sharedHandles->maxhandles) |
95 | | - { |
96 | | - SpinLockRelease(&sharedHandles->mutex); |
97 | | - elog(PANIC, "too many free event handles"); |
98 | | - } |
99 | | - sharedHandles->handles[sharedHandles->nfreehandles] = latch->event; |
100 | | - sharedHandles->nfreehandles++; |
101 | | - SpinLockRelease(&sharedHandles->mutex); |
| 80 | + Assert(latch->owner_pid == MyProcPid); |
102 | 81 |
|
103 | | - latch->event = NULL; |
| 82 | + latch->owner_pid = 0; |
104 | 83 | } |
105 | 84 |
|
106 | 85 | bool |
@@ -217,68 +196,3 @@ ResetLatch(volatile Latch *latch) |
217 | 196 | { |
218 | 197 | latch->is_set = false; |
219 | 198 | } |
220 | | - |
221 | | -/* |
222 | | - * Number of shared latches, used to allocate the right number of shared |
223 | | - * Event handles at postmaster startup. You must update this if you |
224 | | - * introduce a new shared latch! |
225 | | - */ |
226 | | -static int |
227 | | -NumSharedLatches(void) |
228 | | -{ |
229 | | - int numLatches = 0; |
230 | | - |
231 | | - /* Each walsender needs one latch */ |
232 | | - numLatches += max_wal_senders; |
233 | | - |
234 | | - return numLatches; |
235 | | -} |
236 | | - |
237 | | -/* |
238 | | - * LatchShmemSize |
239 | | - * Compute space needed for latch's shared memory |
240 | | - */ |
241 | | -Size |
242 | | -LatchShmemSize(void) |
243 | | -{ |
244 | | - return offsetof(SharedEventHandles, handles) + |
245 | | - NumSharedLatches() * sizeof(HANDLE); |
246 | | -} |
247 | | - |
248 | | -/* |
249 | | - * LatchShmemInit |
250 | | - * Allocate and initialize shared memory needed for latches |
251 | | - */ |
252 | | -void |
253 | | -LatchShmemInit(void) |
254 | | -{ |
255 | | - Size size = LatchShmemSize(); |
256 | | - bool found; |
257 | | - |
258 | | - sharedHandles = ShmemInitStruct("SharedEventHandles", size, &found); |
259 | | - |
260 | | - /* If we're first, initialize the struct and allocate handles */ |
261 | | - if (!found) |
262 | | - { |
263 | | - int i; |
264 | | - SECURITY_ATTRIBUTES sa; |
265 | | - |
266 | | - /* |
267 | | - * Set up security attributes to specify that the events are |
268 | | - * inherited. |
269 | | - */ |
270 | | - ZeroMemory(&sa, sizeof(sa)); |
271 | | - sa.nLength = sizeof(sa); |
272 | | - sa.bInheritHandle = TRUE; |
273 | | - |
274 | | - SpinLockInit(&sharedHandles->mutex); |
275 | | - sharedHandles->maxhandles = NumSharedLatches(); |
276 | | - sharedHandles->nfreehandles = sharedHandles->maxhandles; |
277 | | - for (i = 0; i < sharedHandles->maxhandles; i++) |
278 | | - { |
279 | | - sharedHandles->handles[i] = CreateEvent(&sa, TRUE, FALSE, NULL); |
280 | | - if (sharedHandles->handles[i] == NULL) |
281 | | - elog(ERROR, "CreateEvent failed: error code %d", (int) GetLastError()); |
282 | | - } |
283 | | - } |
284 | | -} |
0 commit comments