18
18
* don't need to register a signal handler or create our own self-pipe. We
19
19
* assume that any system that has Linux epoll() also has Linux signalfd().
20
20
*
21
+ * The kqueue() implementation waits for SIGURG with EVFILT_SIGNAL.
22
+ *
21
23
* The Windows implementation uses Windows events that are inherited by all
22
24
* postmaster child processes. There's no need for the self-pipe trick there.
23
25
*
@@ -150,7 +152,7 @@ static volatile sig_atomic_t waiting = false;
150
152
static int signal_fd = -1 ;
151
153
#endif
152
154
153
- #if defined(WAIT_USE_POLL ) || defined( WAIT_USE_KQUEUE )
155
+ #if defined(WAIT_USE_POLL )
154
156
/* Read and write ends of the self-pipe */
155
157
static int selfpipe_readfd = -1 ;
156
158
static int selfpipe_writefd = -1 ;
@@ -189,7 +191,7 @@ static inline int WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
189
191
void
190
192
InitializeLatchSupport (void )
191
193
{
192
- #if defined(WAIT_USE_POLL ) || defined( WAIT_USE_KQUEUE )
194
+ #if defined(WAIT_USE_POLL )
193
195
int pipefd [2 ];
194
196
195
197
if (IsUnderPostmaster )
@@ -277,6 +279,11 @@ InitializeLatchSupport(void)
277
279
elog (FATAL , "signalfd() failed" );
278
280
ReserveExternalFD ();
279
281
#endif
282
+
283
+ #ifdef WAIT_USE_KQUEUE
284
+ /* Ignore SIGURG, because we'll receive it via kqueue. */
285
+ pqsignal (SIGURG , SIG_IGN );
286
+ #endif
280
287
}
281
288
282
289
void
@@ -300,7 +307,7 @@ InitializeLatchWaitSet(void)
300
307
void
301
308
ShutdownLatchSupport (void )
302
309
{
303
- #if defined(WAIT_USE_POLL ) || defined( WAIT_USE_KQUEUE )
310
+ #if defined(WAIT_USE_POLL )
304
311
pqsignal (SIGURG , SIG_IGN );
305
312
#endif
306
313
@@ -310,7 +317,7 @@ ShutdownLatchSupport(void)
310
317
LatchWaitSet = NULL ;
311
318
}
312
319
313
- #if defined(WAIT_USE_POLL ) || defined( WAIT_USE_KQUEUE )
320
+ #if defined(WAIT_USE_POLL )
314
321
close (selfpipe_readfd );
315
322
close (selfpipe_writefd );
316
323
selfpipe_readfd = -1 ;
@@ -335,7 +342,7 @@ InitLatch(Latch *latch)
335
342
latch -> owner_pid = MyProcPid ;
336
343
latch -> is_shared = false;
337
344
338
- #if defined(WAIT_USE_POLL ) || defined( WAIT_USE_KQUEUE )
345
+ #if defined(WAIT_USE_POLL )
339
346
/* Assert InitializeLatchSupport has been called in this process */
340
347
Assert (selfpipe_readfd >= 0 && selfpipe_owner_pid == MyProcPid );
341
348
#elif defined(WAIT_USE_WIN32 )
@@ -399,7 +406,7 @@ OwnLatch(Latch *latch)
399
406
/* Sanity checks */
400
407
Assert (latch -> is_shared );
401
408
402
- #if defined(WAIT_USE_POLL ) || defined( WAIT_USE_KQUEUE )
409
+ #if defined(WAIT_USE_POLL )
403
410
/* Assert InitializeLatchSupport has been called in this process */
404
411
Assert (selfpipe_readfd >= 0 && selfpipe_owner_pid == MyProcPid );
405
412
#endif
@@ -611,7 +618,7 @@ SetLatch(Latch *latch)
611
618
return ;
612
619
else if (owner_pid == MyProcPid )
613
620
{
614
- #if defined(WAIT_USE_POLL ) || defined( WAIT_USE_KQUEUE )
621
+ #if defined(WAIT_USE_POLL )
615
622
if (waiting )
616
623
sendSelfPipeByte ();
617
624
#else
@@ -898,13 +905,15 @@ AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd, Latch *latch,
898
905
{
899
906
set -> latch = latch ;
900
907
set -> latch_pos = event -> pos ;
901
- #if defined(WAIT_USE_POLL ) || defined( WAIT_USE_KQUEUE )
908
+ #if defined(WAIT_USE_POLL )
902
909
event -> fd = selfpipe_readfd ;
903
910
#elif defined(WAIT_USE_EPOLL )
904
911
event -> fd = signal_fd ;
905
912
#else
906
913
event -> fd = PGINVALID_SOCKET ;
914
+ #ifdef WAIT_USE_EPOLL
907
915
return event -> pos ;
916
+ #endif
908
917
#endif
909
918
}
910
919
else if (events == WL_POSTMASTER_DEATH )
@@ -1125,6 +1134,18 @@ WaitEventAdjustKqueueAddPostmaster(struct kevent *k_ev, WaitEvent *event)
1125
1134
AccessWaitEvent (k_ev ) = event ;
1126
1135
}
1127
1136
1137
+ static inline void
1138
+ WaitEventAdjustKqueueAddLatch (struct kevent * k_ev , WaitEvent * event )
1139
+ {
1140
+ /* For now latch can only be added, not removed. */
1141
+ k_ev -> ident = SIGURG ;
1142
+ k_ev -> filter = EVFILT_SIGNAL ;
1143
+ k_ev -> flags = EV_ADD ;
1144
+ k_ev -> fflags = 0 ;
1145
+ k_ev -> data = 0 ;
1146
+ AccessWaitEvent (k_ev ) = event ;
1147
+ }
1148
+
1128
1149
/*
1129
1150
* old_events is the previous event mask, used to compute what has changed.
1130
1151
*/
@@ -1156,18 +1177,21 @@ WaitEventAdjustKqueue(WaitEventSet *set, WaitEvent *event, int old_events)
1156
1177
*/
1157
1178
WaitEventAdjustKqueueAddPostmaster (& k_ev [count ++ ], event );
1158
1179
}
1180
+ else if (event -> events == WL_LATCH_SET )
1181
+ {
1182
+ /* We detect latch wakeup using a signal event. */
1183
+ WaitEventAdjustKqueueAddLatch (& k_ev [count ++ ], event );
1184
+ }
1159
1185
else
1160
1186
{
1161
1187
/*
1162
1188
* We need to compute the adds and deletes required to get from the
1163
1189
* old event mask to the new event mask, since kevent treats readable
1164
1190
* and writable as separate events.
1165
1191
*/
1166
- if (old_events == WL_LATCH_SET ||
1167
- (old_events & WL_SOCKET_READABLE ))
1192
+ if (old_events & WL_SOCKET_READABLE )
1168
1193
old_filt_read = true;
1169
- if (event -> events == WL_LATCH_SET ||
1170
- (event -> events & WL_SOCKET_READABLE ))
1194
+ if (event -> events & WL_SOCKET_READABLE )
1171
1195
new_filt_read = true;
1172
1196
if (old_events & WL_SOCKET_WRITEABLE )
1173
1197
old_filt_write = true;
@@ -1620,11 +1644,8 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
1620
1644
occurred_events -> events = 0 ;
1621
1645
1622
1646
if (cur_event -> events == WL_LATCH_SET &&
1623
- cur_kqueue_event -> filter == EVFILT_READ )
1647
+ cur_kqueue_event -> filter == EVFILT_SIGNAL )
1624
1648
{
1625
- /* There's data in the self-pipe, clear it. */
1626
- drain ();
1627
-
1628
1649
if (set -> latch && set -> latch -> is_set )
1629
1650
{
1630
1651
occurred_events -> fd = PGINVALID_SOCKET ;
@@ -1999,7 +2020,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
1999
2020
}
2000
2021
#endif
2001
2022
2002
- #if defined(WAIT_USE_POLL ) || defined( WAIT_USE_KQUEUE )
2023
+ #if defined(WAIT_USE_POLL )
2003
2024
2004
2025
/*
2005
2026
* SetLatch uses SIGURG to wake up the process waiting on the latch.
0 commit comments