1818 * don't need to register a signal handler or create our own self-pipe. We
1919 * assume that any system that has Linux epoll() also has Linux signalfd().
2020 *
21+ * The kqueue() implementation waits for SIGURG with EVFILT_SIGNAL.
22+ *
2123 * The Windows implementation uses Windows events that are inherited by all
2224 * postmaster child processes. There's no need for the self-pipe trick there.
2325 *
@@ -150,7 +152,7 @@ static volatile sig_atomic_t waiting = false;
150152static int signal_fd = -1 ;
151153#endif
152154
153- #if defined(WAIT_USE_POLL ) || defined( WAIT_USE_KQUEUE )
155+ #if defined(WAIT_USE_POLL )
154156/* Read and write ends of the self-pipe */
155157static int selfpipe_readfd = -1 ;
156158static int selfpipe_writefd = -1 ;
@@ -189,7 +191,7 @@ static inline int WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
189191void
190192InitializeLatchSupport (void )
191193{
192- #if defined(WAIT_USE_POLL ) || defined( WAIT_USE_KQUEUE )
194+ #if defined(WAIT_USE_POLL )
193195 int pipefd [2 ];
194196
195197 if (IsUnderPostmaster )
@@ -277,6 +279,11 @@ InitializeLatchSupport(void)
277279 elog (FATAL , "signalfd() failed" );
278280 ReserveExternalFD ();
279281#endif
282+
283+ #ifdef WAIT_USE_KQUEUE
284+ /* Ignore SIGURG, because we'll receive it via kqueue. */
285+ pqsignal (SIGURG , SIG_IGN );
286+ #endif
280287}
281288
282289void
@@ -300,7 +307,7 @@ InitializeLatchWaitSet(void)
300307void
301308ShutdownLatchSupport (void )
302309{
303- #if defined(WAIT_USE_POLL ) || defined( WAIT_USE_KQUEUE )
310+ #if defined(WAIT_USE_POLL )
304311 pqsignal (SIGURG , SIG_IGN );
305312#endif
306313
@@ -310,7 +317,7 @@ ShutdownLatchSupport(void)
310317 LatchWaitSet = NULL ;
311318 }
312319
313- #if defined(WAIT_USE_POLL ) || defined( WAIT_USE_KQUEUE )
320+ #if defined(WAIT_USE_POLL )
314321 close (selfpipe_readfd );
315322 close (selfpipe_writefd );
316323 selfpipe_readfd = -1 ;
@@ -335,7 +342,7 @@ InitLatch(Latch *latch)
335342 latch -> owner_pid = MyProcPid ;
336343 latch -> is_shared = false;
337344
338- #if defined(WAIT_USE_POLL ) || defined( WAIT_USE_KQUEUE )
345+ #if defined(WAIT_USE_POLL )
339346 /* Assert InitializeLatchSupport has been called in this process */
340347 Assert (selfpipe_readfd >= 0 && selfpipe_owner_pid == MyProcPid );
341348#elif defined(WAIT_USE_WIN32 )
@@ -399,7 +406,7 @@ OwnLatch(Latch *latch)
399406 /* Sanity checks */
400407 Assert (latch -> is_shared );
401408
402- #if defined(WAIT_USE_POLL ) || defined( WAIT_USE_KQUEUE )
409+ #if defined(WAIT_USE_POLL )
403410 /* Assert InitializeLatchSupport has been called in this process */
404411 Assert (selfpipe_readfd >= 0 && selfpipe_owner_pid == MyProcPid );
405412#endif
@@ -611,7 +618,7 @@ SetLatch(Latch *latch)
611618 return ;
612619 else if (owner_pid == MyProcPid )
613620 {
614- #if defined(WAIT_USE_POLL ) || defined( WAIT_USE_KQUEUE )
621+ #if defined(WAIT_USE_POLL )
615622 if (waiting )
616623 sendSelfPipeByte ();
617624#else
@@ -898,13 +905,15 @@ AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd, Latch *latch,
898905 {
899906 set -> latch = latch ;
900907 set -> latch_pos = event -> pos ;
901- #if defined(WAIT_USE_POLL ) || defined( WAIT_USE_KQUEUE )
908+ #if defined(WAIT_USE_POLL )
902909 event -> fd = selfpipe_readfd ;
903910#elif defined(WAIT_USE_EPOLL )
904911 event -> fd = signal_fd ;
905912#else
906913 event -> fd = PGINVALID_SOCKET ;
914+ #ifdef WAIT_USE_EPOLL
907915 return event -> pos ;
916+ #endif
908917#endif
909918 }
910919 else if (events == WL_POSTMASTER_DEATH )
@@ -1125,6 +1134,18 @@ WaitEventAdjustKqueueAddPostmaster(struct kevent *k_ev, WaitEvent *event)
11251134 AccessWaitEvent (k_ev ) = event ;
11261135}
11271136
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+
11281149/*
11291150 * old_events is the previous event mask, used to compute what has changed.
11301151 */
@@ -1156,18 +1177,21 @@ WaitEventAdjustKqueue(WaitEventSet *set, WaitEvent *event, int old_events)
11561177 */
11571178 WaitEventAdjustKqueueAddPostmaster (& k_ev [count ++ ], event );
11581179 }
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+ }
11591185 else
11601186 {
11611187 /*
11621188 * We need to compute the adds and deletes required to get from the
11631189 * old event mask to the new event mask, since kevent treats readable
11641190 * and writable as separate events.
11651191 */
1166- if (old_events == WL_LATCH_SET ||
1167- (old_events & WL_SOCKET_READABLE ))
1192+ if (old_events & WL_SOCKET_READABLE )
11681193 old_filt_read = true;
1169- if (event -> events == WL_LATCH_SET ||
1170- (event -> events & WL_SOCKET_READABLE ))
1194+ if (event -> events & WL_SOCKET_READABLE )
11711195 new_filt_read = true;
11721196 if (old_events & WL_SOCKET_WRITEABLE )
11731197 old_filt_write = true;
@@ -1620,11 +1644,8 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
16201644 occurred_events -> events = 0 ;
16211645
16221646 if (cur_event -> events == WL_LATCH_SET &&
1623- cur_kqueue_event -> filter == EVFILT_READ )
1647+ cur_kqueue_event -> filter == EVFILT_SIGNAL )
16241648 {
1625- /* There's data in the self-pipe, clear it. */
1626- drain ();
1627-
16281649 if (set -> latch && set -> latch -> is_set )
16291650 {
16301651 occurred_events -> fd = PGINVALID_SOCKET ;
@@ -1999,7 +2020,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
19992020}
20002021#endif
20012022
2002- #if defined(WAIT_USE_POLL ) || defined( WAIT_USE_KQUEUE )
2023+ #if defined(WAIT_USE_POLL )
20032024
20042025/*
20052026 * SetLatch uses SIGURG to wake up the process waiting on the latch.
0 commit comments