Commit 9a9a0cf4 authored by Martin Sustrik's avatar Martin Sustrik

eventfd implementation of the signaler

Eventfd (on Linux) is more efficient that socketpair
for passing simple signals.
Signed-off-by: 's avatarMartin Sustrik <sustrik@250bpm.com>
parent da26134a
...@@ -57,10 +57,15 @@ ...@@ -57,10 +57,15 @@
#include "signaler.hpp" #include "signaler.hpp"
#include "likely.hpp" #include "likely.hpp"
#include "stdint.hpp"
#include "err.hpp" #include "err.hpp"
#include "fd.hpp" #include "fd.hpp"
#include "ip.hpp" #include "ip.hpp"
#if defined ZMQ_HAVE_EVENTFD
#include <sys/eventfd.h>
#endif
#if defined ZMQ_HAVE_WINDOWS #if defined ZMQ_HAVE_WINDOWS
#include "windows.hpp" #include "windows.hpp"
#else #else
...@@ -100,14 +105,19 @@ zmq::signaler_t::signaler_t () ...@@ -100,14 +105,19 @@ zmq::signaler_t::signaler_t ()
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); int rc = closesocket (w);
wsa_assert (rc != SOCKET_ERROR); wsa_assert (rc != SOCKET_ERROR);
rc = closesocket (r); rc = closesocket (r);
wsa_assert (rc != SOCKET_ERROR); wsa_assert (rc != SOCKET_ERROR);
#else #else
close (w); int rc = close (w);
close (r); errno_assert (rc == 0);
rc = close (r);
errno_assert (rc == 0);
#endif #endif
} }
...@@ -118,7 +128,11 @@ zmq::fd_t zmq::signaler_t::get_fd () ...@@ -118,7 +128,11 @@ zmq::fd_t zmq::signaler_t::get_fd ()
void zmq::signaler_t::send () 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; unsigned char dummy = 0;
int nbytes = ::send (w, &dummy, sizeof (dummy), 0); int nbytes = ::send (w, &dummy, sizeof (dummy), 0);
wsa_assert (nbytes != SOCKET_ERROR); wsa_assert (nbytes != SOCKET_ERROR);
...@@ -188,6 +202,14 @@ int zmq::signaler_t::wait (int timeout_) ...@@ -188,6 +202,14 @@ int zmq::signaler_t::wait (int timeout_)
void zmq::signaler_t::recv () void zmq::signaler_t::recv ()
{ {
// Attempt to read a signal. // 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; unsigned char dummy;
#if ZMQ_HAVE_WINDOWS #if ZMQ_HAVE_WINDOWS
int nbytes = ::recv (r, &dummy, sizeof (dummy), 0); int nbytes = ::recv (r, &dummy, sizeof (dummy), 0);
...@@ -198,11 +220,21 @@ void zmq::signaler_t::recv () ...@@ -198,11 +220,21 @@ void zmq::signaler_t::recv ()
#endif #endif
zmq_assert (nbytes == sizeof (dummy)); zmq_assert (nbytes == sizeof (dummy));
zmq_assert (dummy == 0); zmq_assert (dummy == 0);
#endif
} }
int zmq::signaler_t::make_fdpair (fd_t *r_, fd_t *w_) 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 // Windows has no 'socketpair' function. CreatePipe is no good as pipe
// handles cannot be polled on. Here we create the socketpair by hand. // handles cannot be polled on. Here we create the socketpair by hand.
......
...@@ -49,7 +49,7 @@ namespace zmq ...@@ -49,7 +49,7 @@ namespace zmq
// to pass the signals. // to pass the signals.
static int make_fdpair (fd_t *r_, fd_t *w_); 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 w;
fd_t r; fd_t r;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment