diff options
| -rw-r--r-- | src/zmq.cpp | 54 | 
1 files changed, 37 insertions, 17 deletions
diff --git a/src/zmq.cpp b/src/zmq.cpp index 1ed96df..c40be65 100644 --- a/src/zmq.cpp +++ b/src/zmq.cpp @@ -452,31 +452,25 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_)              maxfd = notify_fd;      } +    bool block = (timeout_ < 0);      timeval timeout = {timeout_ / 1000000, timeout_ % 1000000};      timeval zero_timeout = {0, 0};      int nevents = 0; -    bool initial = true; -    while (!nevents) { -        //  Wait for activity. In the first iteration just check for events, -        //  don't wait. Waiting would prevent exiting on any events that may -        //  already be signaled on 0MQ sockets. -        int rc = select (maxfd, &pollset_in, &pollset_out, &pollset_err, -            initial ? &zero_timeout : &timeout); +    //  First iteration just check for events, don't block. Waiting would +    //  prevent exiting on any events that may already been signaled on +    //  0MQ sockets. +    int rc = select (maxfd, &pollset_in, &pollset_out, &pollset_err, +        &zero_timeout);  #if defined ZMQ_HAVE_WINDOWS -        wsa_assert (rc != SOCKET_ERROR); +    wsa_assert (rc != SOCKET_ERROR);  #else -        if (rc == -1 && errno == EINTR) -            break; +    if (rc == -1 && errno == EINTR) +        break; +    errno_assert (rc >= 0);  #endif -        errno_assert (rc >= 0); -        //  If timeout was hit with no events signaled, return zero. -        if (!initial && rc == 0) -            return 0; - -        //  From now on, perform blocking select. -        initial = false; +    while (true) {          //  Process 0MQ commands if needed.          if (nsockets && FD_ISSET (notify_fd, &pollset_in)) @@ -507,6 +501,32 @@ int zmq_poll (zmq_pollitem_t *items_, int nitems_, long timeout_)              if (items_ [i].revents)                  nevents++;          } + +        //  If there's at least one event, or if we are asked not to block, +        //  return immediately. +        if (nevents || (timeout.tv_sec == 0 && timeout.tv_usec == 0)) +            break; + +        //  Wait for events. +        int rc = select (maxfd, &pollset_in, &pollset_out, &pollset_err, +            block ? NULL : &timeout); +#if defined ZMQ_HAVE_WINDOWS +        wsa_assert (rc != SOCKET_ERROR); +#else +        if (rc == -1 && errno == EINTR) +            break; +        errno_assert (rc >= 0); +#endif +         +        //  If timeout was hit with no events signaled, return zero. +        if (rc == 0) +            break; + +        //  If timeout was already applied, we don't want to poll anymore. +        //  Setting timeout to zero will cause termination of the function +        //  once the events we've got are processed. +        if (!block) +            timeout = zero_timeout;      }      return nevents;  | 
