提交 c1796620 编写于 作者: A Andres Freund

Make it easier to choose the used waiting primitive in unix_latch.c.

This allows for easier testing of the different primitives; in
preparation for adding a new primitive.

Discussion: 20160114143931.GG10941@awork2.anarazel.de
Reviewed-By: Robert Haas
上级 6bc4d95f
...@@ -56,6 +56,22 @@ ...@@ -56,6 +56,22 @@
#include "storage/pmsignal.h" #include "storage/pmsignal.h"
#include "storage/shmem.h" #include "storage/shmem.h"
/*
* Select the fd readiness primitive to use. Normally the "most modern"
* primitive supported by the OS will be used, but for testing it can be
* useful to manually specify the used primitive. If desired, just add a
* define somewhere before this block.
*/
#if defined(LATCH_USE_POLL) || defined(LATCH_USE_SELECT)
/* don't overwrite manual choice */
#elif defined(HAVE_POLL)
#define LATCH_USE_POLL
#elif HAVE_SYS_SELECT_H
#define LATCH_USE_SELECT
#else
#error "no latch implementation available"
#endif
/* Are we currently in WaitLatch? The signal handler would like to know. */ /* Are we currently in WaitLatch? The signal handler would like to know. */
static volatile sig_atomic_t waiting = false; static volatile sig_atomic_t waiting = false;
...@@ -215,10 +231,10 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock, ...@@ -215,10 +231,10 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
cur_time; cur_time;
long cur_timeout; long cur_timeout;
#ifdef HAVE_POLL #if defined(LATCH_USE_POLL)
struct pollfd pfds[3]; struct pollfd pfds[3];
int nfds; int nfds;
#else #elif defined(LATCH_USE_SELECT)
struct timeval tv, struct timeval tv,
*tvp; *tvp;
fd_set input_mask; fd_set input_mask;
...@@ -248,7 +264,7 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock, ...@@ -248,7 +264,7 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
Assert(timeout >= 0 && timeout <= INT_MAX); Assert(timeout >= 0 && timeout <= INT_MAX);
cur_timeout = timeout; cur_timeout = timeout;
#ifndef HAVE_POLL #ifdef LATCH_USE_SELECT
tv.tv_sec = cur_timeout / 1000L; tv.tv_sec = cur_timeout / 1000L;
tv.tv_usec = (cur_timeout % 1000L) * 1000L; tv.tv_usec = (cur_timeout % 1000L) * 1000L;
tvp = &tv; tvp = &tv;
...@@ -258,7 +274,7 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock, ...@@ -258,7 +274,7 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
{ {
cur_timeout = -1; cur_timeout = -1;
#ifndef HAVE_POLL #ifdef LATCH_USE_SELECT
tvp = NULL; tvp = NULL;
#endif #endif
} }
...@@ -292,16 +308,10 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock, ...@@ -292,16 +308,10 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
} }
/* /*
* Must wait ... we use poll(2) if available, otherwise select(2). * Must wait ... we use the polling interface determined at the top of
* * this file to do so.
* On at least older linux kernels select(), in violation of POSIX,
* doesn't reliably return a socket as writable if closed - but we
* rely on that. So far all the known cases of this problem are on
* platforms that also provide a poll() implementation without that
* bug. If we find one where that's not the case, we'll need to add a
* workaround.
*/ */
#ifdef HAVE_POLL #if defined(LATCH_USE_POLL)
nfds = 0; nfds = 0;
if (wakeEvents & (WL_SOCKET_READABLE | WL_SOCKET_WRITEABLE)) if (wakeEvents & (WL_SOCKET_READABLE | WL_SOCKET_WRITEABLE))
{ {
...@@ -397,8 +407,16 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock, ...@@ -397,8 +407,16 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
result |= WL_POSTMASTER_DEATH; result |= WL_POSTMASTER_DEATH;
} }
} }
#else /* !HAVE_POLL */ #elif defined(LATCH_USE_SELECT)
/*
* On at least older linux kernels select(), in violation of POSIX,
* doesn't reliably return a socket as writable if closed - but we
* rely on that. So far all the known cases of this problem are on
* platforms that also provide a poll() implementation without that
* bug. If we find one where that's not the case, we'll need to add a
* workaround.
*/
FD_ZERO(&input_mask); FD_ZERO(&input_mask);
FD_ZERO(&output_mask); FD_ZERO(&output_mask);
...@@ -478,7 +496,7 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock, ...@@ -478,7 +496,7 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
result |= WL_POSTMASTER_DEATH; result |= WL_POSTMASTER_DEATH;
} }
} }
#endif /* HAVE_POLL */ #endif /* LATCH_USE_SELECT */
/* If we're not done, update cur_timeout for next iteration */ /* If we're not done, update cur_timeout for next iteration */
if (result == 0 && (wakeEvents & WL_TIMEOUT)) if (result == 0 && (wakeEvents & WL_TIMEOUT))
...@@ -491,7 +509,7 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock, ...@@ -491,7 +509,7 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
/* Timeout has expired, no need to continue looping */ /* Timeout has expired, no need to continue looping */
result |= WL_TIMEOUT; result |= WL_TIMEOUT;
} }
#ifndef HAVE_POLL #ifdef LATCH_USE_SELECT
else else
{ {
tv.tv_sec = cur_timeout / 1000L; tv.tv_sec = cur_timeout / 1000L;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册