diff options
author | Alan Antonuk <alan.antonuk@gmail.com> | 2015-06-01 23:38:08 -0700 |
---|---|---|
committer | Alan Antonuk <alan.antonuk@gmail.com> | 2015-06-01 23:50:27 -0700 |
commit | 6e9565c91fca092f69111a40fa56eabe41c60ff4 (patch) | |
tree | e0ad88f5fcc84c4afa4ef1a79eb88aa75e6213b2 /librabbitmq/amqp_socket.c | |
parent | 3f0d7454a3c31464fa771879d9922880e86b4a17 (diff) | |
download | rabbitmq-c-6e9565c91fca092f69111a40fa56eabe41c60ff4.tar.gz |
Lib: add select()-based implementation of poll()
Add select() based poll() implementation for platforms that either support this
better (Win32) or don't support poll().
Diffstat (limited to 'librabbitmq/amqp_socket.c')
-rw-r--r-- | librabbitmq/amqp_socket.c | 53 |
1 files changed, 48 insertions, 5 deletions
diff --git a/librabbitmq/amqp_socket.c b/librabbitmq/amqp_socket.c index 6267d23..c110765 100644 --- a/librabbitmq/amqp_socket.c +++ b/librabbitmq/amqp_socket.c @@ -67,18 +67,19 @@ # include <sys/types.h> /* On older BSD this must come before net includes */ # include <netinet/in.h> # include <netinet/tcp.h> +# ifdef HAVE_SELECT +# include <sys/select.h> +# endif # include <sys/socket.h> # include <netdb.h> # include <sys/uio.h> # include <fcntl.h> -# include <poll.h> +# ifdef HAVE_POLL +# include <poll.h> +# endif # include <unistd.h> #endif -#ifdef _WIN32 -# define poll(fdarray, nfds, timeout) WSAPoll(fdarray, nfds, timeout) -#endif - static int amqp_id_in_reply_list( amqp_method_number_t expected, amqp_method_number_t *list ); static int @@ -258,6 +259,7 @@ amqp_socket_get_sockfd(amqp_socket_t *self) } int amqp_poll(int fd, int event, amqp_time_t deadline) { +#ifdef HAVE_POLL struct pollfd pfd; int res; int timeout_ms; @@ -299,6 +301,47 @@ start_poll: } } return AMQP_STATUS_OK; +#elif defined(HAVE_SELECT) + fd_set fds; + int res; + struct timeval tv; + struct timeval *tvp; + + assert(event == AMQP_SF_POLLIN || event == AMQP_SF_POLLOUT); + +start_select: + FD_ZERO(&fds); + FD_SET(fd, &fds); + + res = amqp_time_tv_until(deadline, &tv, &tvp); + if (res != AMQP_STATUS_OK) { + return res; + } + + switch (event) { + case AMQP_SF_POLLIN: + res = select(fd + 1, &fds, NULL, NULL, tvp); + break; + case AMQP_SF_POLLOUT: + res = select(fd + 1, NULL, &fds, NULL, tvp); + } + + if (0 < res) { + return AMQP_STATUS_OK; + } else if (0 == res) { + return AMQP_STATUS_TIMEOUT; + } else { + switch (amqp_os_socket_error()) { + case EINTR: + goto start_select; + default: + return AMQP_STATUS_SOCKET_ERROR; + } + } + return AMQP_STATUS_OK; +#else +# error "poll() or select() is needed to compile rabbitmq-c" +#endif } static ssize_t do_poll(amqp_connection_state_t state, ssize_t res, |