diff options
author | Martin Sustrik <sustrik@250bpm.com> | 2011-07-03 15:13:57 +0200 |
---|---|---|
committer | Martin Sustrik <sustrik@250bpm.com> | 2011-07-03 15:13:57 +0200 |
commit | 9a9a0cf41066d32f0d16492e212712b42df36950 (patch) | |
tree | 96ca75b859f4393c1cfd537f8606ec66bacd30cf | |
parent | da26134aa696352de6e77a800a433878dbabb7fa (diff) |
eventfd implementation of the signaler
Eventfd (on Linux) is more efficient that socketpair
for passing simple signals.
Signed-off-by: Martin Sustrik <sustrik@250bpm.com>
-rw-r--r-- | src/signaler.cpp | 42 | ||||
-rw-r--r-- | src/signaler.hpp | 2 |
2 files changed, 38 insertions, 6 deletions
diff --git a/src/signaler.cpp b/src/signaler.cpp index 2ecfb98..3045467 100644 --- a/src/signaler.cpp +++ b/src/signaler.cpp @@ -57,10 +57,15 @@ #include "signaler.hpp" #include "likely.hpp" +#include "stdint.hpp" #include "err.hpp" #include "fd.hpp" #include "ip.hpp" +#if defined ZMQ_HAVE_EVENTFD +#include <sys/eventfd.h> +#endif + #if defined ZMQ_HAVE_WINDOWS #include "windows.hpp" #else @@ -100,14 +105,19 @@ zmq::signaler_t::signaler_t () zmq::signaler_t::~signaler_t () { -#if defined ZMQ_HAVE_WINDOWS +#if defined ZMQ_HAVE_EVENTFD + int rc = close (r); + errno_assert (rc == 0); +#elif defined ZMQ_HAVE_WINDOWS int rc = closesocket (w); wsa_assert (rc != SOCKET_ERROR); rc = closesocket (r); wsa_assert (rc != SOCKET_ERROR); #else - close (w); - close (r); + int rc = close (w); + errno_assert (rc == 0); + rc = close (r); + errno_assert (rc == 0); #endif } @@ -118,7 +128,11 @@ zmq::fd_t zmq::signaler_t::get_fd () void zmq::signaler_t::send () { -#if defined ZMQ_HAVE_WINDOWS +#if defined ZMQ_HAVE_EVENTFD + const uint64_t inc = 1; + ssize_t sz = write (w, &inc, sizeof (inc)); + errno_assert (sz == sizeof (inc)); +#elif defined ZMQ_HAVE_WINDOWS unsigned char dummy = 0; int nbytes = ::send (w, &dummy, sizeof (dummy), 0); wsa_assert (nbytes != SOCKET_ERROR); @@ -188,6 +202,14 @@ int zmq::signaler_t::wait (int timeout_) void zmq::signaler_t::recv () { // Attempt to read a signal. +#if defined ZMQ_HAVE_EVENTFD + uint64_t dummy; + ssize_t sz = read (r, &dummy, sizeof (dummy)); + errno_assert (sz == sizeof (dummy)); +if (dummy != 1) +printf ("dummy:%d\n", (int) dummy); + zmq_assert (dummy == 1); +#else unsigned char dummy; #if ZMQ_HAVE_WINDOWS int nbytes = ::recv (r, &dummy, sizeof (dummy), 0); @@ -198,11 +220,21 @@ void zmq::signaler_t::recv () #endif zmq_assert (nbytes == sizeof (dummy)); zmq_assert (dummy == 0); +#endif } int zmq::signaler_t::make_fdpair (fd_t *r_, fd_t *w_) { -#if defined ZMQ_HAVE_WINDOWS +#if defined ZMQ_HAVE_EVENTFD + + // Create eventfd object. + fd_t fd = eventfd (0, 0); + errno_assert (fd != -1); + *w_ = fd; + *r_ = fd; + return 0; + +#elif defined ZMQ_HAVE_WINDOWS // Windows has no 'socketpair' function. CreatePipe is no good as pipe // handles cannot be polled on. Here we create the socketpair by hand. diff --git a/src/signaler.hpp b/src/signaler.hpp index 2ebff41..dd474d9 100644 --- a/src/signaler.hpp +++ b/src/signaler.hpp @@ -49,7 +49,7 @@ namespace zmq // to pass the signals. static int make_fdpair (fd_t *r_, fd_t *w_); - // Write & read end of the socketpair. + // Underlying write & read file descriptor. fd_t w; fd_t r; |