summaryrefslogtreecommitdiffstats
path: root/src/server/locks.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/locks.c')
-rw-r--r--src/server/locks.c59
1 files changed, 54 insertions, 5 deletions
diff --git a/src/server/locks.c b/src/server/locks.c
index 4293c2f..ce29b9a 100644
--- a/src/server/locks.c
+++ b/src/server/locks.c
@@ -106,7 +106,7 @@ int debug_spin_lock(const char *name, const char *file, int line, pthread_spinlo
break;
}
pthread_spin_unlock( &initdestory );
- int retval = pthread_spin_lock( lock );
+ const int retval = pthread_spin_lock( lock );
pthread_spin_lock( &initdestory );
t->tid = 0;
t->time = 0;
@@ -125,6 +125,55 @@ int debug_spin_lock(const char *name, const char *file, int line, pthread_spinlo
return retval;
}
+int debug_spin_trylock(const char *name, const char *file, int line, pthread_spinlock_t *lock)
+{
+ debug_lock_t *l = NULL;
+ pthread_spin_lock( &initdestory );
+ for (int i = 0; i < MAXLOCKS; ++i) {
+ if ( locks[i].lock == lock ) {
+ l = &locks[i];
+ break;
+ }
+ }
+ pthread_spin_unlock( &initdestory );
+ if ( l == NULL ) {
+ printf( "[ERROR] Tried to lock uninitialized lock %p (%s) at %s:%d\n", lock, name, file, line );
+ debug_dump_lock_stats();
+ exit( 4 );
+ }
+ debug_thread_t *t = NULL;
+ pthread_spin_lock( &initdestory );
+ for (int i = 0; i < MAXTHREADS; ++i) {
+ if ( threads[i].tid != 0 ) continue;
+ threads[i].tid = pthread_self();
+ threads[i].time = time( NULL );
+ snprintf( threads[i].name, LOCKLEN, "%s", name );
+ snprintf( threads[i].where, LOCKLEN, "%s:%d", file, line );
+ t = &threads[i];
+ break;
+ }
+ pthread_spin_unlock( &initdestory );
+ const int retval = pthread_spin_trylock( lock );
+ pthread_spin_lock( &initdestory );
+ t->tid = 0;
+ t->time = 0;
+ pthread_spin_unlock( &initdestory );
+ if ( retval == 0 ) {
+ if ( l->locked ) {
+ printf( "[ERROR] Lock sanity check: lock %p (%s) already locked at %s:%d\n", lock, name, file, line );
+ exit( 4 );
+ }
+ l->locked = 1;
+ l->locktime = time( NULL );
+ l->thread = pthread_self();
+ snprintf( l->where, LOCKLEN, "L %s:%d", file, line );
+ pthread_spin_lock( &initdestory );
+ l->lockId = ++lockId;
+ pthread_spin_unlock( &initdestory );
+ }
+ return retval;
+}
+
int debug_spin_unlock(const char *name, const char *file, int line, pthread_spinlock_t *lock)
{
debug_lock_t *l = NULL;
@@ -140,7 +189,6 @@ int debug_spin_unlock(const char *name, const char *file, int line, pthread_spin
printf( "[ERROR] Tried to unlock uninitialized lock %p (%s) at %s:%d\n", lock, name, file, line );
exit( 4 );
}
- int retval = pthread_spin_unlock( lock );
if ( !l->locked ) {
printf( "[ERROR] Unlock sanity check: lock %p (%s) not locked at %s:%d\n", lock, name, file, line );
exit( 4 );
@@ -149,6 +197,7 @@ int debug_spin_unlock(const char *name, const char *file, int line, pthread_spin
l->locktime = 0;
l->thread = 0;
snprintf( l->where, LOCKLEN, "U %s:%d", file, line );
+ int retval = pthread_spin_unlock( lock );
return retval;
}
@@ -192,7 +241,7 @@ void debug_dump_lock_stats()
"* Locked: %d\n", locks[i].name, locks[i].where, (int)locks[i].locked );
}
}
- printf( "\n **** THREADS ****\n\n" );
+ printf( "\n **** WAITING THREADS ****\n\n" );
for (int i = 0; i < MAXTHREADS; ++i) {
if ( threads[i].tid == 0 ) continue;
printf( "* *** Thread %d ***\n"
@@ -206,7 +255,7 @@ void debug_dump_lock_stats()
static void *debug_thread_watchdog(void *something)
{
while ( !_shutdown ) {
- if (init_done) {
+ if ( init_done ) {
time_t now = time( NULL );
pthread_spin_lock( &initdestory );
for (int i = 0; i < MAXTHREADS; ++i) {
@@ -242,7 +291,7 @@ void debug_locks_stop_watchdog()
{
#ifdef _DEBUG
_shutdown = TRUE;
- printf("Killing debug watchdog...\n");
+ printf( "Killing debug watchdog...\n" );
pthread_spin_lock( &initdestory );
pthread_spin_unlock( &initdestory );
pthread_join( watchdog, NULL );