summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/daemon-windows.c4
-rw-r--r--lib/fatal-signal.c11
-rw-r--r--lib/latch-unix.c2
-rw-r--r--lib/latch-windows.c2
-rw-r--r--lib/poll-loop.c94
-rw-r--r--lib/poll-loop.h12
-rw-r--r--lib/stream-fd-windows.c14
-rw-r--r--lib/stream-ssl.c42
8 files changed, 97 insertions, 84 deletions
diff --git a/lib/daemon-windows.c b/lib/daemon-windows.c
index a7d65666a..33b3b36de 100644
--- a/lib/daemon-windows.c
+++ b/lib/daemon-windows.c
@@ -107,7 +107,7 @@ service_start(int *argcp, char **argvp[])
VLOG_FATAL("Failed to create a event (%s).", msg_buf);
}
- poll_fd_wait_event(0, wevent, POLLIN);
+ poll_wevent_wait(wevent);
/* Register the control handler. This function is called by the service
* manager to stop the service. */
@@ -206,7 +206,7 @@ should_service_stop(void)
if (service_status.dwCurrentState != SERVICE_RUNNING) {
return true;
} else {
- poll_fd_wait_event(0, wevent, POLLIN);
+ poll_wevent_wait(wevent);
}
}
return false;
diff --git a/lib/fatal-signal.c b/lib/fatal-signal.c
index eff007d12..199cf6bd5 100644
--- a/lib/fatal-signal.c
+++ b/lib/fatal-signal.c
@@ -59,9 +59,12 @@ static struct hook hooks[MAX_HOOKS];
static size_t n_hooks;
static int signal_fds[2];
-static HANDLE wevent;
static volatile sig_atomic_t stored_sig_nr = SIG_ATOMIC_MAX;
+#ifdef _WIN32
+static HANDLE wevent;
+#endif
+
static struct ovs_mutex mutex;
static void call_hooks(int sig_nr);
@@ -215,7 +218,11 @@ void
fatal_signal_wait(void)
{
fatal_signal_init();
- poll_fd_wait_event(signal_fds[0], wevent, POLLIN);
+#ifdef _WIN32
+ poll_wevent_wait(wevent);
+#else
+ poll_fd_wait(signal_fds[0], POLLIN);
+#endif
}
void
diff --git a/lib/latch-unix.c b/lib/latch-unix.c
index 20a6575e7..bf518b9ca 100644
--- a/lib/latch-unix.c
+++ b/lib/latch-unix.c
@@ -83,5 +83,5 @@ latch_is_set(const struct latch *latch)
void
latch_wait_at(const struct latch *latch, const char *where)
{
- poll_fd_wait_at(latch->fds[0], 0, POLLIN, where);
+ poll_fd_wait_at(latch->fds[0], POLLIN, where);
}
diff --git a/lib/latch-windows.c b/lib/latch-windows.c
index 34796d5d8..3160527b5 100644
--- a/lib/latch-windows.c
+++ b/lib/latch-windows.c
@@ -79,5 +79,5 @@ latch_is_set(const struct latch *latch)
void
latch_wait_at(const struct latch *latch, const char *where)
{
- poll_fd_wait_at(0, latch->wevent, POLLIN, where);
+ poll_wevent_wait_at(latch->wevent, where);
}
diff --git a/lib/poll-loop.c b/lib/poll-loop.c
index f5f1e5d0c..8747c61a1 100644
--- a/lib/poll-loop.c
+++ b/lib/poll-loop.c
@@ -35,7 +35,7 @@
VLOG_DEFINE_THIS_MODULE(poll_loop);
-COVERAGE_DEFINE(poll_fd_wait);
+COVERAGE_DEFINE(poll_create_node);
COVERAGE_DEFINE(poll_zero_timeout);
struct poll_node {
@@ -59,11 +59,12 @@ static struct poll_loop *poll_loop(void);
/* Look up the node with same fd and wevent. */
static struct poll_node *
-find_poll_node(struct poll_loop *loop, int fd, uint32_t wevent)
+find_poll_node(struct poll_loop *loop, int fd, HANDLE wevent)
{
struct poll_node *node;
- HMAP_FOR_EACH_WITH_HASH (node, hmap_node, hash_2words(fd, wevent),
+ HMAP_FOR_EACH_WITH_HASH (node, hmap_node,
+ hash_2words(fd, (uint32_t)wevent),
&loop->poll_nodes) {
if (node->pollfd.fd == fd && node->wevent == wevent) {
return node;
@@ -77,54 +78,91 @@ find_poll_node(struct poll_loop *loop, int fd, uint32_t wevent)
* Registers 'fd' as waiting for the specified 'events' (which should be
* POLLIN or POLLOUT or POLLIN | POLLOUT). The following call to
* poll_block() will wake up when 'fd' becomes ready for one or more of the
- * requested events. the 'fd's are given to poll() function later.
+ * requested events. The 'fd's are given to poll() function later.
*
* On Windows system:
*
- * If both 'wevent' handle and 'fd' is specified, associate the 'fd' with
- * with that 'wevent' for 'events' (implemented in poll_block()).
- * In case of no 'fd' specified, wake up on any event on that 'wevent'.
- * These wevents are given to the WaitForMultipleObjects() to be polled.
- * The event registration is one-shot: only the following call to
- * poll_block() is affected. The event will need to be re-registered after
- * poll_block() is called if it is to persist.
+ * If 'fd' is specified, create a new 'wevent'. Association of 'fd' and
+ * 'wevent' for 'events' happens in poll_block(). If 'wevent' is specified,
+ * it is assumed that it is unrelated to any sockets and poll_block()
+ * will wake up on any event on that 'wevent'. It is an error to pass
+ * both 'wevent' and 'fd'.
+ *
+ * The event registration is one-shot: only the following call to
+ * poll_block() is affected. The event will need to be re-registered after
+ * poll_block() is called if it is to persist.
*
* ('where' is used in debug logging. Commonly one would use poll_fd_wait() to
* automatically provide the caller's source file and line number for
* 'where'.) */
-void
-poll_fd_wait_at(int fd, HANDLE wevent, short int events, const char *where)
+static void
+poll_create_node(int fd, HANDLE wevent, short int events, const char *where)
{
struct poll_loop *loop = poll_loop();
struct poll_node *node;
- COVERAGE_INC(poll_fd_wait);
+ COVERAGE_INC(poll_create_node);
-#ifdef _WIN32
- /* Null event cannot be polled. */
- if (wevent == 0) {
- VLOG_ERR("No event to wait fd %d", fd);
- return;
- }
-#else
- wevent = 0;
-#endif
+ /* Both 'fd' and 'wevent' cannot be set. */
+ ovs_assert(!fd != !wevent);
- /* Check for duplicate. If found, "or" the event. */
+ /* Check for duplicate. If found, "or" the events. */
node = find_poll_node(loop, fd, wevent);
if (node) {
node->pollfd.events |= events;
} else {
node = xzalloc(sizeof *node);
hmap_insert(&loop->poll_nodes, &node->hmap_node,
- hash_2words(fd, wevent));
+ hash_2words(fd, (uint32_t)wevent));
node->pollfd.fd = fd;
node->pollfd.events = events;
+#ifdef _WIN32
+ if (!wevent) {
+ wevent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ }
+#endif
node->wevent = wevent;
node->where = where;
}
}
+/* Registers 'fd' as waiting for the specified 'events' (which should be POLLIN
+ * or POLLOUT or POLLIN | POLLOUT). The following call to poll_block() will
+ * wake up when 'fd' becomes ready for one or more of the requested events.
+ *
+ * On Windows, 'fd' must be a socket.
+ *
+ * The event registration is one-shot: only the following call to poll_block()
+ * is affected. The event will need to be re-registered after poll_block() is
+ * called if it is to persist.
+ *
+ * ('where' is used in debug logging. Commonly one would use poll_fd_wait() to
+ * automatically provide the caller's source file and line number for
+ * 'where'.) */
+void
+poll_fd_wait_at(int fd, short int events, const char *where)
+{
+ poll_create_node(fd, 0, events, where);
+}
+
+#ifdef _WIN32
+/* Registers for the next call to poll_block() to wake up when 'wevent' is
+ * signaled.
+ *
+ * The event registration is one-shot: only the following call to poll_block()
+ * is affected. The event will need to be re-registered after poll_block() is
+ * called if it is to persist.
+ *
+ * ('where' is used in debug logging. Commonly one would use
+ * poll_wevent_wait() to automatically provide the caller's source file and
+ * line number for 'where'.) */
+void
+poll_wevent_wait_at(HANDLE wevent, const char *where)
+{
+ poll_create_node(0, wevent, 0, where);
+}
+#endif /* _WIN32 */
+
/* Causes the following call to poll_block() to block for no more than 'msec'
* milliseconds. If 'msec' is nonpositive, the following call to poll_block()
* will not block at all.
@@ -258,6 +296,12 @@ free_poll_nodes(struct poll_loop *loop)
HMAP_FOR_EACH_SAFE (node, next, hmap_node, &loop->poll_nodes) {
hmap_remove(&loop->poll_nodes, &node->hmap_node);
+#ifdef _WIN32
+ if (node->wevent && node->pollfd.fd) {
+ WSAEventSelect(node->pollfd.fd, NULL, 0);
+ CloseHandle(node->wevent);
+ }
+#endif
free(node);
}
}
diff --git a/lib/poll-loop.h b/lib/poll-loop.h
index 412bd09d4..5fdf87411 100644
--- a/lib/poll-loop.h
+++ b/lib/poll-loop.h
@@ -50,12 +50,12 @@ extern "C" {
* caller to supply a location explicitly, which is useful if the caller's own
* caller would be more useful in log output. See timer_wait_at() for an
* example. */
-void poll_fd_wait_at(int fd, HANDLE wevent, short int events, const char *where);
-#ifndef _WIN32
-#define poll_fd_wait(fd, events) poll_fd_wait_at(fd, 0, events, SOURCE_LOCATOR)
-#endif
-#define poll_fd_wait_event(fd, wevent, events) \
- poll_fd_wait_at(fd, wevent, events, SOURCE_LOCATOR)
+void poll_fd_wait_at(int fd, short int events, const char *where);
+#define poll_fd_wait(fd, events) poll_fd_wait_at(fd, events, SOURCE_LOCATOR)
+
+#ifdef _WIN32
+#define poll_wevent_wait(wevent) poll_wevent_wait_at(wevent, SOURCE_LOCATOR)
+#endif /* _WIN32 */
void poll_timer_wait_at(long long int msec, const char *where);
#define poll_timer_wait(msec) poll_timer_wait_at(msec, SOURCE_LOCATOR)
diff --git a/lib/stream-fd-windows.c b/lib/stream-fd-windows.c
index 23fd55c65..e366c715b 100644
--- a/lib/stream-fd-windows.c
+++ b/lib/stream-fd-windows.c
@@ -39,7 +39,6 @@ struct stream_fd
{
struct stream stream;
int fd;
- HANDLE wevent;
};
static const struct stream_class stream_fd_class;
@@ -61,7 +60,6 @@ new_fd_stream(const char *name, int fd, int connect_status,
s = xmalloc(sizeof *s);
stream_init(&s->stream, &stream_fd_class, connect_status, name);
s->fd = fd;
- s->wevent = CreateEvent(NULL, FALSE, FALSE, NULL);
*streamp = &s->stream;
return 0;
}
@@ -77,8 +75,6 @@ static void
fd_close(struct stream *stream)
{
struct stream_fd *s = stream_fd_cast(stream);
- WSAEventSelect(s->fd, NULL, 0);
- CloseHandle(s->wevent);
closesocket(s->fd);
free(s);
}
@@ -130,11 +126,11 @@ fd_wait(struct stream *stream, enum stream_wait_type wait)
switch (wait) {
case STREAM_CONNECT:
case STREAM_SEND:
- poll_fd_wait_event(s->fd, s->wevent, POLLOUT);
+ poll_fd_wait(s->fd, POLLOUT);
break;
case STREAM_RECV:
- poll_fd_wait_event(s->fd, s->wevent, POLLIN);
+ poll_fd_wait(s->fd, POLLIN);
break;
default:
@@ -161,7 +157,6 @@ struct fd_pstream
{
struct pstream pstream;
int fd;
- HANDLE wevent;
int (*accept_cb)(int fd, const struct sockaddr_storage *, size_t ss_len,
struct stream **);
int (*set_dscp_cb)(int fd, uint8_t dscp);
@@ -201,7 +196,6 @@ new_fd_pstream(const char *name, int fd,
struct fd_pstream *ps = xmalloc(sizeof *ps);
pstream_init(&ps->pstream, &fd_pstream_class, name);
ps->fd = fd;
- ps->wevent = CreateEvent(NULL, FALSE, FALSE, NULL);
ps->accept_cb = accept_cb;
ps->set_dscp_cb = set_dscp_cb;
ps->unlink_path = unlink_path;
@@ -213,8 +207,6 @@ static void
pfd_close(struct pstream *pstream)
{
struct fd_pstream *ps = fd_pstream_cast(pstream);
- WSAEventSelect(ps->fd, NULL, 0);
- CloseHandle(ps->wevent);
closesocket(ps->fd);
if (ps->unlink_path) {
fatal_signal_unlink_file_now(ps->unlink_path);
@@ -254,7 +246,7 @@ static void
pfd_wait(struct pstream *pstream)
{
struct fd_pstream *ps = fd_pstream_cast(pstream);
- poll_fd_wait_event(ps->fd, ps->wevent, POLLIN);
+ poll_fd_wait(ps->fd, POLLIN);
}
static int
diff --git a/lib/stream-ssl.c b/lib/stream-ssl.c
index 9a214be46..fb7fb2f3a 100644
--- a/lib/stream-ssl.c
+++ b/lib/stream-ssl.c
@@ -82,7 +82,6 @@ struct ssl_stream
enum ssl_state state;
enum session_type type;
int fd;
- HANDLE wevent;
SSL *ssl;
struct ofpbuf *txbuf;
unsigned int session_nr;
@@ -200,7 +199,6 @@ static void ssl_protocol_cb(int write_p, int version, int content_type,
const void *, size_t, SSL *, void *sslv_);
static bool update_ssl_config(struct ssl_config_file *, const char *file_name);
static int sock_errno(void);
-static void clear_handle(int fd, HANDLE wevent);
static short int
want_to_poll_events(int want)
@@ -305,11 +303,6 @@ new_ssl_stream(const char *name, int fd, enum session_type type,
sslv->state = state;
sslv->type = type;
sslv->fd = fd;
-#ifdef _WIN32
- sslv->wevent = CreateEvent(NULL, FALSE, FALSE, NULL);
-#else
- sslv->wevent = 0;
-#endif
sslv->ssl = ssl;
sslv->txbuf = NULL;
sslv->rx_want = sslv->tx_want = SSL_NOTHING;
@@ -542,7 +535,6 @@ ssl_close(struct stream *stream)
ERR_clear_error();
SSL_free(sslv->ssl);
- clear_handle(sslv->fd, sslv->wevent);
closesocket(sslv->fd);
free(sslv);
}
@@ -735,8 +727,7 @@ ssl_run_wait(struct stream *stream)
struct ssl_stream *sslv = ssl_stream_cast(stream);
if (sslv->tx_want != SSL_NOTHING) {
- poll_fd_wait_event(sslv->fd, sslv->wevent,
- want_to_poll_events(sslv->tx_want));
+ poll_fd_wait(sslv->fd, want_to_poll_events(sslv->tx_want));
}
}
@@ -752,14 +743,14 @@ ssl_wait(struct stream *stream, enum stream_wait_type wait)
} else {
switch (sslv->state) {
case STATE_TCP_CONNECTING:
- poll_fd_wait_event(sslv->fd, sslv->wevent, POLLOUT);
+ poll_fd_wait(sslv->fd, POLLOUT);
break;
case STATE_SSL_CONNECTING:
/* ssl_connect() called SSL_accept() or SSL_connect(), which
* set up the status that we test here. */
- poll_fd_wait_event(sslv->fd, sslv->wevent,
- want_to_poll_events(SSL_want(sslv->ssl)));
+ poll_fd_wait(sslv->fd,
+ want_to_poll_events(SSL_want(sslv->ssl)));
break;
default:
@@ -770,8 +761,7 @@ ssl_wait(struct stream *stream, enum stream_wait_type wait)
case STREAM_RECV:
if (sslv->rx_want != SSL_NOTHING) {
- poll_fd_wait_event(sslv->fd, sslv->wevent,
- want_to_poll_events(sslv->rx_want));
+ poll_fd_wait(sslv->fd, want_to_poll_events(sslv->rx_want));
} else {
poll_immediate_wake();
}
@@ -811,7 +801,6 @@ struct pssl_pstream
{
struct pstream pstream;
int fd;
- HANDLE wevent;
};
const struct pstream_class pssl_pstream_class;
@@ -853,11 +842,6 @@ pssl_open(const char *name OVS_UNUSED, char *suffix, struct pstream **pstreamp,
pstream_init(&pssl->pstream, &pssl_pstream_class, bound_name);
pstream_set_bound_port(&pssl->pstream, htons(port));
pssl->fd = fd;
-#ifdef _WIN32
- pssl->wevent = CreateEvent(NULL, FALSE, FALSE, NULL);
-#else
- pssl->wevent = 0;
-#endif
*pstreamp = &pssl->pstream;
return 0;
}
@@ -866,7 +850,6 @@ static void
pssl_close(struct pstream *pstream)
{
struct pssl_pstream *pssl = pssl_pstream_cast(pstream);
- clear_handle(pssl->fd, pssl->wevent);
closesocket(pssl->fd);
free(pssl);
}
@@ -913,7 +896,7 @@ static void
pssl_wait(struct pstream *pstream)
{
struct pssl_pstream *pssl = pssl_pstream_cast(pstream);
- poll_fd_wait_event(pssl->fd, pssl->wevent, POLLIN);
+ poll_fd_wait(pssl->fd, POLLIN);
}
static int
@@ -1444,16 +1427,3 @@ ssl_protocol_cb(int write_p, int version OVS_UNUSED, int content_type,
ds_destroy(&details);
}
-
-static void
-clear_handle(int fd OVS_UNUSED, HANDLE wevent OVS_UNUSED)
-{
-#ifdef _WIN32
- if (fd) {
- WSAEventSelect(fd, NULL, 0);
- }
- if (wevent) {
- CloseHandle(wevent);
- }
-#endif
-}