From 415e28e43bf0538ced45d6f0a2627448d7360ba0 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Fri, 5 Feb 2016 21:14:23 +0100 Subject: [SHARED] Implement pipe() based signalling --- src/shared/signal.c | 81 +++++++---------------------------------------------- 1 file changed, 10 insertions(+), 71 deletions(-) (limited to 'src/shared/signal.c') diff --git a/src/shared/signal.c b/src/shared/signal.c index e023c49..051f785 100644 --- a/src/shared/signal.c +++ b/src/shared/signal.c @@ -1,74 +1,13 @@ #include "signal.h" -#include -#include -#include -#include -#include -/* - * Linux implementation of signals. - * Internally, eventfds are used for signalling, as they - * provide the least overhead. We don't allocate any struct - * ever, but cast the event fd+1 to dnbd3_signal_t* - * to save all the malloc() and free() calls. - */ - -dnbd3_signal_t* signal_new() -{ - // On error, eventfd() returns -1, so essentially we return NULL on error. - // (Yes, NULL doesn't have to be 0 everywhere, but cmon) - return (dnbd3_signal_t*)(intptr_t)( eventfd( 0, EFD_NONBLOCK ) + 1 ); -} - -dnbd3_signal_t* signal_newBlocking() -{ - return (dnbd3_signal_t*)(intptr_t)( eventfd( 0, 0 ) + 1 ); -} - -int signal_call(const dnbd3_signal_t* const signal) -{ - if ( signal == NULL ) return SIGNAL_ERROR; - static uint64_t one = 1; - const int signalFd = ( (int)(intptr_t)signal ) - 1; - return write( signalFd, &one, sizeof one ) == sizeof one; -} - -int signal_wait(const dnbd3_signal_t* const signal, int timeoutMs) -{ - if ( signal == NULL ) return SIGNAL_ERROR; - const int signalFd = ( (int)(intptr_t)signal ) - 1; - struct pollfd ps = { - .fd = signalFd, - .events = POLLIN - }; - int ret = poll( &ps, 1, timeoutMs ); - if ( ret == 0 ) return SIGNAL_TIMEOUT; - if ( ret == -1 ) return SIGNAL_ERROR; - if ( ps.revents & ( POLLERR | POLLNVAL ) ) return SIGNAL_ERROR; - return signal_clear( signal ); -} - -int signal_clear(const dnbd3_signal_t* const signal) -{ - if ( signal == NULL ) return SIGNAL_ERROR; - uint64_t ret; - const int signalFd = ( (int)(intptr_t)signal ) - 1; - if ( read( signalFd, &ret, sizeof ret ) != sizeof ret ) { - if ( errno == EAGAIN ) return 0; - return SIGNAL_ERROR; - } - return (int)ret; -} - -void signal_close(const dnbd3_signal_t* const signal) -{ - const int signalFd = ( (int)(intptr_t)signal ) - 1; - close( signalFd ); -} - -int signal_getWaitFd(const dnbd3_signal_t* const signal) -{ - const int signalFd = ( (int)(intptr_t)signal ) - 1; - return signalFd; -} +#if defined(linux) +//#warning "Using eventfd based signalling" +#include "signal.inc/eventfd.c" +#elif __SIZEOF_INT__ == 4 && __SIZEOF_POINTER__ == 8 +//#warning "Using pointer-packing pipe based signalling" +#include "signal.inc/pipe64.c" +#else +//#warning "Using fallback pipe based signalling" +#include "signal.inc/pipe_malloc.c" +#endif -- cgit v1.2.3-55-g7522