@ -18,6 +18,8 @@
* don ' t need to register a signal handler or create our own self - pipe . We
* assume that any system that has Linux epoll ( ) also has Linux signalfd ( ) .
*
* The kqueue ( ) implementation waits for SIGURG with EVFILT_SIGNAL .
*
* The Windows implementation uses Windows events that are inherited by all
* postmaster child processes . There ' s no need for the self - pipe trick there .
*
@ -150,7 +152,7 @@ static volatile sig_atomic_t waiting = false;
static int signal_fd = - 1 ;
# endif
# if defined(WAIT_USE_POLL) || defined(WAIT_USE_KQUEUE)
# if defined(WAIT_USE_POLL)
/* Read and write ends of the self-pipe */
static int selfpipe_readfd = - 1 ;
static int selfpipe_writefd = - 1 ;
@ -189,7 +191,7 @@ static inline int WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
void
InitializeLatchSupport ( void )
{
# if defined(WAIT_USE_POLL) || defined(WAIT_USE_KQUEUE)
# if defined(WAIT_USE_POLL)
int pipefd [ 2 ] ;
if ( IsUnderPostmaster )
@ -277,6 +279,11 @@ InitializeLatchSupport(void)
elog ( FATAL , " signalfd() failed " ) ;
ReserveExternalFD ( ) ;
# endif
# ifdef WAIT_USE_KQUEUE
/* Ignore SIGURG, because we'll receive it via kqueue. */
pqsignal ( SIGURG , SIG_IGN ) ;
# endif
}
void
@ -300,7 +307,7 @@ InitializeLatchWaitSet(void)
void
ShutdownLatchSupport ( void )
{
# if defined(WAIT_USE_POLL) || defined(WAIT_USE_KQUEUE)
# if defined(WAIT_USE_POLL)
pqsignal ( SIGURG , SIG_IGN ) ;
# endif
@ -310,7 +317,7 @@ ShutdownLatchSupport(void)
LatchWaitSet = NULL ;
}
# if defined(WAIT_USE_POLL) || defined(WAIT_USE_KQUEUE)
# if defined(WAIT_USE_POLL)
close ( selfpipe_readfd ) ;
close ( selfpipe_writefd ) ;
selfpipe_readfd = - 1 ;
@ -335,7 +342,7 @@ InitLatch(Latch *latch)
latch - > owner_pid = MyProcPid ;
latch - > is_shared = false ;
# if defined(WAIT_USE_POLL) || defined(WAIT_USE_KQUEUE)
# if defined(WAIT_USE_POLL)
/* Assert InitializeLatchSupport has been called in this process */
Assert ( selfpipe_readfd > = 0 & & selfpipe_owner_pid = = MyProcPid ) ;
# elif defined(WAIT_USE_WIN32)
@ -399,7 +406,7 @@ OwnLatch(Latch *latch)
/* Sanity checks */
Assert ( latch - > is_shared ) ;
# if defined(WAIT_USE_POLL) || defined(WAIT_USE_KQUEUE)
# if defined(WAIT_USE_POLL)
/* Assert InitializeLatchSupport has been called in this process */
Assert ( selfpipe_readfd > = 0 & & selfpipe_owner_pid = = MyProcPid ) ;
# endif
@ -611,7 +618,7 @@ SetLatch(Latch *latch)
return ;
else if ( owner_pid = = MyProcPid )
{
# if defined(WAIT_USE_POLL) || defined(WAIT_USE_KQUEUE)
# if defined(WAIT_USE_POLL)
if ( waiting )
sendSelfPipeByte ( ) ;
# else
@ -898,13 +905,15 @@ AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd, Latch *latch,
{
set - > latch = latch ;
set - > latch_pos = event - > pos ;
# if defined(WAIT_USE_POLL) || defined(WAIT_USE_KQUEUE)
# if defined(WAIT_USE_POLL)
event - > fd = selfpipe_readfd ;
# elif defined(WAIT_USE_EPOLL)
event - > fd = signal_fd ;
# else
event - > fd = PGINVALID_SOCKET ;
# ifdef WAIT_USE_EPOLL
return event - > pos ;
# endif
# endif
}
else if ( events = = WL_POSTMASTER_DEATH )
@ -1125,6 +1134,18 @@ WaitEventAdjustKqueueAddPostmaster(struct kevent *k_ev, WaitEvent *event)
AccessWaitEvent ( k_ev ) = event ;
}
static inline void
WaitEventAdjustKqueueAddLatch ( struct kevent * k_ev , WaitEvent * event )
{
/* For now latch can only be added, not removed. */
k_ev - > ident = SIGURG ;
k_ev - > filter = EVFILT_SIGNAL ;
k_ev - > flags = EV_ADD ;
k_ev - > fflags = 0 ;
k_ev - > data = 0 ;
AccessWaitEvent ( k_ev ) = event ;
}
/*
* old_events is the previous event mask , used to compute what has changed .
*/
@ -1156,6 +1177,11 @@ WaitEventAdjustKqueue(WaitEventSet *set, WaitEvent *event, int old_events)
*/
WaitEventAdjustKqueueAddPostmaster ( & k_ev [ count + + ] , event ) ;
}
else if ( event - > events = = WL_LATCH_SET )
{
/* We detect latch wakeup using a signal event. */
WaitEventAdjustKqueueAddLatch ( & k_ev [ count + + ] , event ) ;
}
else
{
/*
@ -1163,11 +1189,9 @@ WaitEventAdjustKqueue(WaitEventSet *set, WaitEvent *event, int old_events)
* old event mask to the new event mask , since kevent treats readable
* and writable as separate events .
*/
if ( old_events = = WL_LATCH_SET | |
( old_events & WL_SOCKET_READABLE ) )
if ( old_events & WL_SOCKET_READABLE )
old_filt_read = true ;
if ( event - > events = = WL_LATCH_SET | |
( event - > events & WL_SOCKET_READABLE ) )
if ( event - > events & WL_SOCKET_READABLE )
new_filt_read = true ;
if ( old_events & WL_SOCKET_WRITEABLE )
old_filt_write = true ;
@ -1620,11 +1644,8 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
occurred_events - > events = 0 ;
if ( cur_event - > events = = WL_LATCH_SET & &
cur_kqueue_event - > filter = = EVFILT_READ )
cur_kqueue_event - > filter = = EVFILT_SIGNAL )
{
/* There's data in the self-pipe, clear it. */
drain ( ) ;
if ( set - > latch & & set - > latch - > is_set )
{
occurred_events - > fd = PGINVALID_SOCKET ;
@ -1999,7 +2020,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
}
# endif
# if defined(WAIT_USE_POLL) || defined(WAIT_USE_KQUEUE)
# if defined(WAIT_USE_POLL)
/*
* SetLatch uses SIGURG to wake up the process waiting on the latch .