#include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <assert.h> /* Test that locks, having entered the lock acquisition tracking machinery, are forgotten by it when the client does pthread_{mutex,rwlock}_destroy. 2008-Nov-10: see comments below. */ int main ( void ) { int r; pthread_mutex_t *mx1, *mx2; assert (sizeof(pthread_mutex_t) <= 120); mx1 = malloc(120 + sizeof(pthread_mutex_t) - sizeof(pthread_mutex_t)); mx2 = malloc(120 + sizeof(pthread_mutex_t) - sizeof(pthread_mutex_t)); assert(mx1); assert(mx2); r = pthread_mutex_init( mx1, NULL ); assert(r==0); r = pthread_mutex_init( mx2, NULL ); assert(r==0); /* Establish order 1 -> 2 */ fprintf(stderr, "Establish order 1 -> 2\n"); r = pthread_mutex_lock( mx1 ); assert(r==0); r = pthread_mutex_lock( mx2 ); assert(r==0); r = pthread_mutex_unlock( mx1 ); assert(r==0); r = pthread_mutex_unlock( mx2 ); assert(r==0); /* Try order 2 -> 1. This gives an error. */ fprintf(stderr, "Try order 2 -> 1. This gives an error.\n"); r = pthread_mutex_lock( mx2 ); assert(r==0); /* error */ r = pthread_mutex_lock( mx1 ); assert(r==0); r = pthread_mutex_unlock( mx1 ); assert(r==0); r = pthread_mutex_unlock( mx2 ); assert(r==0); /* De-initialise 2 and re-initialise it. This gives it a new identity, so a second locking sequence 2 -> 1 should now be OK. */ fprintf(stderr, "Free 2 and re-allocate it. This gives it a new identity,\n"); fprintf(stderr, "so a second locking sequence 2 -> 1 should now be OK.\n"); pthread_mutex_destroy( mx2 ); r = pthread_mutex_init( mx2, NULL ); assert(r==0); r = pthread_mutex_lock( mx2 ); assert(r==0); r = pthread_mutex_lock( mx1 ); assert(r==0); /* no error */ r = pthread_mutex_unlock( mx1 ); assert(r==0); r = pthread_mutex_unlock( mx2 ); assert(r==0); /* done */ fprintf(stderr, "done\n"); r = pthread_mutex_destroy( mx1 ); r = pthread_mutex_destroy( mx2 ); free( mx1 ); free( mx2 ); return 0; } /* 2008-Nov-10: I believe this test is flawed and requires further investigation. I don't think it really tests what it claims to test. In particular, it still gives the right results if "pthread_mutex_destroy( mx2 );" at line 46 is commented out. In other words, laog somehow forgets about mx2 so that 2->1 lock sequence at lines 52/3 does not produce a complaint, EVEN WHEN the preceding "pthread_mutex_destroy( mx2 );" is not observed. I don't know why this is, but it seems highly suspicious to me. */