From: Gurucharan Shetty Date: Wed, 5 Feb 2014 18:10:10 +0000 (-0800) Subject: poll-loop: Make poll_fd_wait_event() cross-platform. X-Git-Tag: sliver-openvswitch-2.1.90-1~1^2~73 X-Git-Url: http://git.onelab.eu/?p=sliver-openvswitch.git;a=commitdiff_plain;h=55489d31a66b39aa7b41ed07a19f0bd7d7fbdd11 poll-loop: Make poll_fd_wait_event() cross-platform. This is helpful if we want to wait either on 'fd' for POSIX or events for Windows. For Windows, if both 'fd' and 'wevent' is specified, we associate that event with the 'fd' using WSAEventSelect() in poll_block(). So any 'events' on that 'fd' will wake us up from WaitForMultipleObjects(). WSAEventSelect() does not understand POLLIN, POLLOUT etc. Instead the macros it understands are FD_READ, FD_ACCEPT, FD_CONNECT, FD_CLOSE etc. So we need to make that transition. Signed-off-by: Gurucharan Shetty Acked-by: Ben Pfaff --- diff --git a/lib/poll-loop.c b/lib/poll-loop.c index abd44d1be..510903e46 100644 --- a/lib/poll-loop.c +++ b/lib/poll-loop.c @@ -81,11 +81,13 @@ find_poll_node(struct poll_loop *loop, int fd, uint32_t wevent) * * On Windows system: * - * Register 'wevent' handle for the specified 'events'. These wevents are - * given to the handleMultipleObjects() 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 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. * * ('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 @@ -293,6 +295,16 @@ poll_block(void) pollfds[i] = node->pollfd; #ifdef _WIN32 wevents[i] = node->wevent; + if (node->pollfd.fd && node->wevent) { + short int wsa_events = 0; + if (node->pollfd.events & POLLIN) { + wsa_events |= FD_READ | FD_ACCEPT | FD_CLOSE; + } + if (node->pollfd.events & POLLOUT) { + wsa_events |= FD_WRITE | FD_CONNECT | FD_CLOSE; + } + WSAEventSelect(node->pollfd.fd, node->wevent, wsa_events); + } #endif i++; } diff --git a/lib/poll-loop.h b/lib/poll-loop.h index ae4c0c0eb..412bd09d4 100644 --- a/lib/poll-loop.h +++ b/lib/poll-loop.h @@ -53,9 +53,9 @@ extern "C" { 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) -#else -#define poll_fd_wait_event(fd, wevent, events) poll_fd_wait_at(fd, wevent, events, SOURCE_LOCATOR) #endif +#define poll_fd_wait_event(fd, wevent, events) \ + poll_fd_wait_at(fd, wevent, events, SOURCE_LOCATOR) void poll_timer_wait_at(long long int msec, const char *where); #define poll_timer_wait(msec) poll_timer_wait_at(msec, SOURCE_LOCATOR)