diff options
Diffstat (limited to 'src/server')
-rw-r--r-- | src/server/locks.c | 43 | ||||
-rw-r--r-- | src/server/locks.h | 4 | ||||
-rw-r--r-- | src/server/server.c | 15 |
3 files changed, 41 insertions, 21 deletions
diff --git a/src/server/locks.c b/src/server/locks.c index 050fa4e..9e8d4ad 100644 --- a/src/server/locks.c +++ b/src/server/locks.c @@ -205,32 +205,45 @@ void debug_dump_lock_stats() static void *debug_thread_watchdog(void *something) { - while (!_shutdown) { - time_t now = time(NULL); - pthread_spin_lock( &initdestory ); - for (int i = 0; i < MAXTHREADS; ++i) { - if ( threads[i].tid == 0 ) continue; - const int diff = now - threads[i].time; - if ( diff > 6 && diff < 100000 ) { - printf("\n\n +++++++++ DEADLOCK ++++++++++++\n\n"); - pthread_spin_unlock( &initdestory ); - debug_dump_lock_stats(); - exit(99); + while ( !_shutdown ) { + if (init_done) { + time_t now = time( NULL ); + pthread_spin_lock( &initdestory ); + for (int i = 0; i < MAXTHREADS; ++i) { + if ( threads[i].tid == 0 ) continue; + const int diff = now - threads[i].time; + if ( diff > 6 && diff < 100000 ) { + printf( "\n\n +++++++++ DEADLOCK ++++++++++++\n\n" ); + pthread_spin_unlock( &initdestory ); + debug_dump_lock_stats(); + exit( 99 ); + } } + pthread_spin_unlock( &initdestory ); } - pthread_spin_unlock( &initdestory ); - sleep(10); + sleep( 10 ); } - return NULL; + return NULL ; } +#endif + void debug_locks_start_watchdog() { +#ifdef _DEBUG if ( 0 != pthread_create( &watchdog, NULL, &debug_thread_watchdog, (void *)NULL ) ) { memlogf( "[ERROR] Could not start debug-lock watchdog." ); return; } - pthread_detach( watchdog ); +#endif } +void debug_locks_stop_watchdog() +{ +#ifdef _DEBUG + _shutdown = TRUE; + pthread_spin_lock( &initdestory ); + pthread_spin_unlock( &initdestory ); + pthread_join( watchdog, NULL ); #endif +} diff --git a/src/server/locks.h b/src/server/locks.h index 6558558..5d4367b 100644 --- a/src/server/locks.h +++ b/src/server/locks.h @@ -15,7 +15,6 @@ int debug_spin_lock(const char *name, const char *file, int line, pthread_spinlo int debug_spin_unlock(const char *name, const char *file, int line, pthread_spinlock_t *lock); int debug_spin_destroy(const char *name, const char *file, int line, pthread_spinlock_t *lock); -void debug_locks_start_watchdog(); void debug_dump_lock_stats(); #else @@ -27,4 +26,7 @@ void debug_dump_lock_stats(); #endif +void debug_locks_start_watchdog(); +void debug_locks_stop_watchdog(); + #endif /* LOCKS_H_ */ diff --git a/src/server/server.c b/src/server/server.c index 38635c9..6e49eb0 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -96,6 +96,7 @@ void dnbd3_cleanup() { int i; + _shutdown = TRUE; memlogf( "INFO: Cleanup...\n" ); for (int i = 0; i < socket_count; ++i) { @@ -108,6 +109,7 @@ void dnbd3_cleanup() // Clean up clients spin_lock( &_clients_lock ); for (i = 0; i < _num_clients; ++i) { + if ( _clients[i] == NULL ) continue; dnbd3_client_t * const client = _clients[i]; spin_lock( &client->lock ); if ( client->sock >= 0 ) shutdown( client->sock, SHUT_RDWR ); @@ -122,11 +124,14 @@ void dnbd3_cleanup() // Clean up images spin_lock( &_images_lock ); for (i = 0; i < _num_images; ++i) { + if ( _images[i] == NULL ) continue; _images[i] = image_free( _images[i] ); } _num_images = 0; spin_unlock( &_images_lock ); + debug_locks_stop_watchdog(); + exit( EXIT_SUCCESS ); } @@ -335,11 +340,11 @@ dnbd3_client_t* dnbd3_free_client(dnbd3_client_t *client) { spin_lock( &client->lock ); /* - for (it = client->sendqueue; it; it = it->next) { - free( it->data ); - } - g_slist_free( client->sendqueue ); - */ + for (it = client->sendqueue; it; it = it->next) { + free( it->data ); + } + g_slist_free( client->sendqueue ); + */ if ( client->sock >= 0 ) close( client->sock ); client->sock = -1; if ( client->image != NULL ) image_release( client->image ); |