From 3db3bbfbbb84127b90636b7e0a681fb82ff6e7ee Mon Sep 17 00:00:00 2001 From: Simon Giesecke Date: Thu, 31 May 2018 18:29:01 +0200 Subject: [PATCH] Problem: duplication in implementation zmq_poller_poll Solution: remove duplication --- src/zmq.cpp | 183 ++++++++++++++++++---------------------------------- 1 file changed, 64 insertions(+), 119 deletions(-) diff --git a/src/zmq.cpp b/src/zmq.cpp index 43423549..eb5a8b1e 100644 --- a/src/zmq.cpp +++ b/src/zmq.cpp @@ -800,7 +800,7 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_) // if poller is present, use that. return zmq_poller_poll (items_, nitems_, timeout_); #else -#if defined ZMQ_POLL_BASED_ON_POLL +#if defined ZMQ_POLL_BASED_ON_POLL || defined ZMQ_POLL_BASED_ON_SELECT if (unlikely (nitems_ < 0)) { errno = EINVAL; return -1; @@ -811,22 +811,25 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_) #if defined ZMQ_HAVE_WINDOWS Sleep (timeout_ > 0 ? timeout_ : INFINITE); return 0; -#elif defined ZMQ_HAVE_ANDROID - usleep (timeout_ * 1000); - return 0; +#elif defined ZMQ_HAVE_VXWORKS + struct timespec ns_; + ns_.tv_sec = timeout_ / 1000; + ns_.tv_nsec = timeout_ % 1000 * 1000000; + return nanosleep (&ns_, 0); #else return usleep (timeout_ * 1000); #endif } + zmq::clock_t clock; + uint64_t now = 0; + uint64_t end = 0; +#if defined ZMQ_POLL_BASED_ON_POLL if (!items_) { errno = EFAULT; return -1; } - zmq::clock_t clock; - uint64_t now = 0; - uint64_t end = 0; pollfd spollfds[ZMQ_POLLITEMS_DFLT]; pollfd *pollfds = spollfds; @@ -860,11 +863,60 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_) | (items_[i].events & ZMQ_POLLPRI ? POLLPRI : 0); } } +#else + // Ensure we do not attempt to select () on more than FD_SETSIZE + // file descriptors. + zmq_assert (nitems_ <= FD_SETSIZE); + + fd_set pollset_in; + FD_ZERO (&pollset_in); + fd_set pollset_out; + FD_ZERO (&pollset_out); + fd_set pollset_err; + FD_ZERO (&pollset_err); + + zmq::fd_t maxfd = 0; + + // Build the fd_sets for passing to select (). + for (int i = 0; i != nitems_; i++) { + // If the poll item is a 0MQ socket we are interested in input on the + // notification file descriptor retrieved by the ZMQ_FD socket option. + if (items_[i].socket) { + size_t zmq_fd_size = sizeof (zmq::fd_t); + zmq::fd_t notify_fd; + if (zmq_getsockopt (items_[i].socket, ZMQ_FD, ¬ify_fd, + &zmq_fd_size) + == -1) + return -1; + if (items_[i].events) { + FD_SET (notify_fd, &pollset_in); + if (maxfd < notify_fd) + maxfd = notify_fd; + } + } + // Else, the poll item is a raw file descriptor. Convert the poll item + // events to the appropriate fd_sets. + else { + if (items_[i].events & ZMQ_POLLIN) + FD_SET (items_[i].fd, &pollset_in); + if (items_[i].events & ZMQ_POLLOUT) + FD_SET (items_[i].fd, &pollset_out); + if (items_[i].events & ZMQ_POLLERR) + FD_SET (items_[i].fd, &pollset_err); + if (maxfd < items_[i].fd) + maxfd = items_[i].fd; + } + } + + fd_set inset, outset, errset; +#endif bool first_pass = true; int nevents = 0; while (true) { +#if defined ZMQ_POLL_BASED_ON_POLL + // Compute the timeout for the subsequent poll. int timeout; if (first_pass) @@ -925,119 +977,8 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_) nevents++; } - // If timeout is zero, exit immediately whether there are events or not. - if (timeout_ == 0) - break; - - // If there are events to return, we can exit immediately. - if (nevents) - break; - - // At this point we are meant to wait for events but there are none. - // If timeout is infinite we can just loop until we get some events. - if (timeout_ < 0) { - if (first_pass) - first_pass = false; - continue; - } - - // The timeout is finite and there are no events. In the first pass - // we get a timestamp of when the polling have begun. (We assume that - // first pass have taken negligible time). We also compute the time - // when the polling should time out. - if (first_pass) { - now = clock.now_ms (); - end = now + timeout_; - if (now == end) - break; - first_pass = false; - continue; - } - - // Find out whether timeout have expired. - now = clock.now_ms (); - if (now >= end) - break; - } - - if (pollfds != spollfds) - free (pollfds); - return nevents; - -#elif defined ZMQ_POLL_BASED_ON_SELECT - - if (unlikely (nitems_ < 0)) { - errno = EINVAL; - return -1; - } - if (unlikely (nitems_ == 0)) { - if (timeout_ == 0) - return 0; -#if defined ZMQ_HAVE_WINDOWS - Sleep (timeout_ > 0 ? timeout_ : INFINITE); - return 0; -#elif defined ZMQ_HAVE_VXWORKS - struct timespec ns_; - ns_.tv_sec = timeout_ / 1000; - ns_.tv_nsec = timeout_ % 1000 * 1000000; - return nanosleep (&ns_, 0); #else - return usleep (timeout_ * 1000); -#endif - } - zmq::clock_t clock; - uint64_t now = 0; - uint64_t end = 0; - // Ensure we do not attempt to select () on more than FD_SETSIZE - // file descriptors. - zmq_assert (nitems_ <= FD_SETSIZE); - - fd_set pollset_in; - FD_ZERO (&pollset_in); - fd_set pollset_out; - FD_ZERO (&pollset_out); - fd_set pollset_err; - FD_ZERO (&pollset_err); - - zmq::fd_t maxfd = 0; - - // Build the fd_sets for passing to select (). - for (int i = 0; i != nitems_; i++) { - // If the poll item is a 0MQ socket we are interested in input on the - // notification file descriptor retrieved by the ZMQ_FD socket option. - if (items_[i].socket) { - size_t zmq_fd_size = sizeof (zmq::fd_t); - zmq::fd_t notify_fd; - if (zmq_getsockopt (items_[i].socket, ZMQ_FD, ¬ify_fd, - &zmq_fd_size) - == -1) - return -1; - if (items_[i].events) { - FD_SET (notify_fd, &pollset_in); - if (maxfd < notify_fd) - maxfd = notify_fd; - } - } - // Else, the poll item is a raw file descriptor. Convert the poll item - // events to the appropriate fd_sets. - else { - if (items_[i].events & ZMQ_POLLIN) - FD_SET (items_[i].fd, &pollset_in); - if (items_[i].events & ZMQ_POLLOUT) - FD_SET (items_[i].fd, &pollset_out); - if (items_[i].events & ZMQ_POLLERR) - FD_SET (items_[i].fd, &pollset_err); - if (maxfd < items_[i].fd) - maxfd = items_[i].fd; - } - } - - bool first_pass = true; - int nevents = 0; - fd_set inset, outset, errset; - - while (true) { // Compute the timeout for the subsequent poll. timeval timeout; timeval *ptimeout; @@ -1125,6 +1066,7 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_) if (items_[i].revents) nevents++; } +#endif // If timeout is zero, exit immediately whether there are events or not. if (timeout_ == 0) @@ -1160,9 +1102,12 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_) if (now >= end) break; } +#if defined ZMQ_POLL_BASED_ON_POLL + if (pollfds != spollfds) + free (pollfds); +#endif return nevents; - #else // Exotic platforms that support neither poll() nor select(). errno = ENOTSUP;