From a4dec329802619a9d3d0f80b037ccce9e18ffe0a Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 6 Jan 2015 23:10:02 +0100 Subject: [SERVER] Get rid of epoll in alservers.c, make valgrind+gdb happy by handling signals even though we block them --- src/server/altservers.c | 48 ++++++++++++------------------------------------ src/server/globals.c | 2 +- src/server/globals.h | 2 +- src/server/locks.c | 1 + src/server/net.c | 3 ++- 5 files changed, 17 insertions(+), 39 deletions(-) diff --git a/src/server/altservers.c b/src/server/altservers.c index 7ed1a57..457405f 100644 --- a/src/server/altservers.c +++ b/src/server/altservers.c @@ -9,7 +9,6 @@ #include "signal.h" #include #include -#include #include #include #include @@ -21,7 +20,7 @@ static dnbd3_connection_t *pending[SERVER_MAX_PENDING_ALT_CHECKS]; static pthread_spinlock_t pendingLockProduce; // Lock for adding something to pending. (NULL -> nonNULL) static pthread_mutex_t pendingLockConsume = PTHREAD_MUTEX_INITIALIZER; // Lock for removing something (nonNULL -> NULL) -static int signalPipe = -1; +static int signalFd = -1; static dnbd3_alt_server_t altServers[SERVER_MAX_ALTS]; static int numAltServers = 0; @@ -52,7 +51,7 @@ void altservers_init() void altservers_shutdown() { if ( !initDone ) return; - signal_call( signalPipe ); // Wake altservers thread up + signal_call( signalFd ); // Wake altservers thread up thread_join( altThread, NULL ); } @@ -148,7 +147,7 @@ void altservers_findUplink(dnbd3_connection_t *uplink) pending[i] = uplink; uplink->rttTestResult = RTT_INPROGRESS; spin_unlock( &pendingLockProduce ); - signal_call( signalPipe ); // Wake altservers thread up + signal_call( signalFd ); // Wake altservers thread up return; } // End of loop - no free slot @@ -339,11 +338,8 @@ void altservers_serverFailed(const dnbd3_host_t * const host) */ static void *altservers_main(void *data) { - const int MAXEVENTS = 3; const int ALTS = 4; - struct epoll_event ev, events[MAXEVENTS]; - int fdEpoll = -1; - int numSocks, ret, itLink, itAlt, numAlts; + int ret, itLink, itAlt, numAlts; bool found; char buffer[DNBD3_BLOCK_SIZE ]; dnbd3_reply_t reply; @@ -360,39 +356,20 @@ static void *altservers_main(void *data) for (int i = 0; i < SERVER_MAX_PENDING_ALT_CHECKS; ++i) pending[i] = NULL; // Init signal-pipe - fdEpoll = epoll_create( 2 ); - if ( fdEpoll == -1 ) { - memlogf( "[WARNING] epoll_create failed. Uplink unavailable." ); + signalFd = signal_new(); + if ( signalFd < 0 ) { + memlogf( "[WARNING] error creating signal object. Uplink feature unavailable." ); goto cleanup; } - { - signalPipe = signal_new(); - if ( signalPipe < 0 ) { - memlogf( "[WARNING] error creating signal object. Uplink feature unavailable." ); - goto cleanup; - } - memset( &ev, 0, sizeof(ev) ); - ev.events = EPOLLIN; - ev.data.fd = signalPipe; - if ( epoll_ctl( fdEpoll, EPOLL_CTL_ADD, signalPipe, &ev ) < 0 ) { - memlogf( "[WARNING] adding read-signal-pipe to epoll set failed" ); - goto cleanup; - } - } // LOOP while ( !_shutdown ) { // Wait 5 seconds max. - numSocks = epoll_wait( fdEpoll, events, MAXEVENTS, 5000 ); - if ( numSocks < 0 ) { - const int err = errno; - memlogf( "[WARNING] epoll_wait() error %d in uplink_connector", err ); - usleep( 100000 ); - } + ret = signal_wait( signalFd, 5000 ); if ( _shutdown ) goto cleanup; - // Clear signal - ret = signal_clear( signalPipe ); if ( ret == SIGNAL_ERROR ) { + if ( errno == EAGAIN || errno == EINTR ) continue; memlogf( "[WARNING] Error on signal_clear on alservers_main! Things will break!" ); + usleep( 100000 ); } // Work your way through the queue for (itLink = 0; itLink < SERVER_MAX_PENDING_ALT_CHECKS; ++itLink) { @@ -536,9 +513,8 @@ static void *altservers_main(void *data) } } cleanup: ; - if ( fdEpoll != -1 ) close( fdEpoll ); - if ( signalPipe != -1 ) signal_close( signalPipe ); - signalPipe = -1; + if ( signalFd != -1 ) signal_close( signalFd ); + signalFd = -1; return NULL ; } diff --git a/src/server/globals.c b/src/server/globals.c index 1e35a8f..b441c8e 100644 --- a/src/server/globals.c +++ b/src/server/globals.c @@ -9,7 +9,7 @@ char *_configDir = NULL; char *_basePath = NULL; bool _vmdkLegacyMode = false; -bool _shutdown = false; +volatile bool _shutdown = false; int _serverPenalty = 0; int _clientPenalty = 0; bool _isProxy = false; diff --git a/src/server/globals.h b/src/server/globals.h index 09a9a5b..4b99e38 100644 --- a/src/server/globals.h +++ b/src/server/globals.h @@ -152,7 +152,7 @@ extern int _clientPenalty; /** * Is server shutting down? */ -extern bool _shutdown; +extern volatile bool _shutdown; /** * Is server allowed to provide images in proxy mode? diff --git a/src/server/locks.c b/src/server/locks.c index e464182..3c1956f 100644 --- a/src/server/locks.c +++ b/src/server/locks.c @@ -305,5 +305,6 @@ void debug_locks_stop_watchdog() signal_call( watchdogSignal ); pthread_spin_unlock( &initdestory ); thread_join( watchdog, NULL ); + signal_close( watchdogSignal ); #endif } diff --git a/src/server/net.c b/src/server/net.c index 5a9a640..3dfa231 100644 --- a/src/server/net.c +++ b/src/server/net.c @@ -49,7 +49,7 @@ static inline bool recv_request_header(int sock, dnbd3_request_t *request) int ret, fails = 0; // Read request header from socket while ( (ret = recv( sock, request, sizeof(*request), MSG_WAITALL )) != sizeof(*request) ) { - if ( errno == EINTR ) continue; + if ( errno == EINTR && ++fails < 10 ) continue; if ( ret >= 0 || ++fails > SOCKET_TIMEOUT_SERVER_RETRIES ) return false; if ( errno == EAGAIN ) continue; printf( "[DEBUG] Error receiving request: Could not read message header (%d/%d, e=%d)\n", ret, (int)sizeof(*request), errno ); @@ -196,6 +196,7 @@ void *net_client_handler(void *dnbd3_client) } // client handling mainloop while ( recv_request_header( client->sock, &request ) ) { + if ( _shutdown ) break; switch ( request.cmd ) { case CMD_GET_BLOCK: -- cgit v1.2.3-55-g7522