@@ -283,27 +283,31 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
283283 do
284284 {
285285 /*
286- * Clear the pipe, then check if the latch is set already. If someone
287- * sets the latch between this and the poll()/select() below, the
288- * setter will write a byte to the pipe (or signal us and the signal
289- * handler will do that), and the poll()/select() will return
290- * immediately.
286+ * Check if the latch is set already. If so, leave loop immediately,
287+ * avoid blocking again. We don't attempt to report any other events
288+ * that might also be satisfied.
289+ *
290+ * If someone sets the latch between this and the poll()/select()
291+ * below, the setter will write a byte to the pipe (or signal us and
292+ * the signal handler will do that), and the poll()/select() will
293+ * return immediately.
294+ *
295+ * If there's a pending byte in the self pipe, we'll notice whenever
296+ * blocking. Only clearing the pipe in that case avoids having to
297+ * drain it every time WaitLatchOrSocket() is used. Should the
298+ * pipe-buffer fill up we're still ok, because the pipe is in
299+ * nonblocking mode. It's unlikely for that to happen, because the
300+ * self pipe isn't filled unless we're blocking (waiting = true), or
301+ * from inside a signal handler in latch_sigusr1_handler().
291302 *
292303 * Note: we assume that the kernel calls involved in drainSelfPipe()
293304 * and SetLatch() will provide adequate synchronization on machines
294305 * with weak memory ordering, so that we cannot miss seeing is_set if
295306 * the signal byte is already in the pipe when we drain it.
296307 */
297- drainSelfPipe ();
298-
299308 if ((wakeEvents & WL_LATCH_SET ) && latch -> is_set )
300309 {
301310 result |= WL_LATCH_SET ;
302-
303- /*
304- * Leave loop immediately, avoid blocking again. We don't attempt
305- * to report any other events that might also be satisfied.
306- */
307311 break ;
308312 }
309313
@@ -313,24 +317,26 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
313317 */
314318#if defined(LATCH_USE_POLL )
315319 nfds = 0 ;
320+
321+ /* selfpipe is always in pfds[0] */
322+ pfds [0 ].fd = selfpipe_readfd ;
323+ pfds [0 ].events = POLLIN ;
324+ pfds [0 ].revents = 0 ;
325+ nfds ++ ;
326+
316327 if (wakeEvents & (WL_SOCKET_READABLE | WL_SOCKET_WRITEABLE ))
317328 {
318- /* socket, if used, is always in pfds[0 ] */
319- pfds [0 ].fd = sock ;
320- pfds [0 ].events = 0 ;
329+ /* socket, if used, is always in pfds[1 ] */
330+ pfds [1 ].fd = sock ;
331+ pfds [1 ].events = 0 ;
321332 if (wakeEvents & WL_SOCKET_READABLE )
322- pfds [0 ].events |= POLLIN ;
333+ pfds [1 ].events |= POLLIN ;
323334 if (wakeEvents & WL_SOCKET_WRITEABLE )
324- pfds [0 ].events |= POLLOUT ;
325- pfds [0 ].revents = 0 ;
335+ pfds [1 ].events |= POLLOUT ;
336+ pfds [1 ].revents = 0 ;
326337 nfds ++ ;
327338 }
328339
329- pfds [nfds ].fd = selfpipe_readfd ;
330- pfds [nfds ].events = POLLIN ;
331- pfds [nfds ].revents = 0 ;
332- nfds ++ ;
333-
334340 if (wakeEvents & WL_POSTMASTER_DEATH )
335341 {
336342 /* postmaster fd, if used, is always in pfds[nfds - 1] */
@@ -364,19 +370,27 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
364370 else
365371 {
366372 /* at least one event occurred, so check revents values */
373+
374+ if (pfds [0 ].revents & POLLIN )
375+ {
376+ /* There's data in the self-pipe, clear it. */
377+ drainSelfPipe ();
378+ }
379+
367380 if ((wakeEvents & WL_SOCKET_READABLE ) &&
368- (pfds [0 ].revents & POLLIN ))
381+ (pfds [1 ].revents & POLLIN ))
369382 {
370383 /* data available in socket, or EOF/error condition */
371384 result |= WL_SOCKET_READABLE ;
372385 }
373386 if ((wakeEvents & WL_SOCKET_WRITEABLE ) &&
374- (pfds [0 ].revents & POLLOUT ))
387+ (pfds [1 ].revents & POLLOUT ))
375388 {
376389 /* socket is writable */
377390 result |= WL_SOCKET_WRITEABLE ;
378391 }
379- if (pfds [0 ].revents & (POLLHUP | POLLERR | POLLNVAL ))
392+ if ((wakeEvents & WL_SOCKET_WRITEABLE ) &&
393+ (pfds [1 ].revents & (POLLHUP | POLLERR | POLLNVAL )))
380394 {
381395 /* EOF/error condition */
382396 if (wakeEvents & WL_SOCKET_READABLE )
@@ -468,6 +482,11 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
468482 else
469483 {
470484 /* at least one event occurred, so check masks */
485+ if (FD_ISSET (selfpipe_readfd , & input_mask ))
486+ {
487+ /* There's data in the self-pipe, clear it. */
488+ drainSelfPipe ();
489+ }
471490 if ((wakeEvents & WL_SOCKET_READABLE ) && FD_ISSET (sock , & input_mask ))
472491 {
473492 /* data available in socket, or EOF */
@@ -498,6 +517,16 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
498517 }
499518#endif /* LATCH_USE_SELECT */
500519
520+ /*
521+ * Check again whether latch is set, the arrival of a signal/self-byte
522+ * might be what stopped our sleep. It's not required for correctness
523+ * to signal the latch as being set (we'd just loop if there's no
524+ * other event), but it seems good to report an arrived latch asap.
525+ * This way we also don't have to compute the current timestamp again.
526+ */
527+ if ((wakeEvents & WL_LATCH_SET ) && latch -> is_set )
528+ result |= WL_LATCH_SET ;
529+
501530 /* If we're not done, update cur_timeout for next iteration */
502531 if (result == 0 && (wakeEvents & WL_TIMEOUT ))
503532 {
0 commit comments