1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Check that an error is reported for various kinds of bogus
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pthread_mutex_unlock calls. */
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <pthread.h>
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h>
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdlib.h>
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid* child_fn ( void* arg )
10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pthread_mutex_unlock( (pthread_mutex_t*)arg ); /* ERROR */
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return NULL;
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid nearly_main ( void )
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pthread_t child;
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pthread_mutex_t mx1, mx2;
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   int bogus[100], i;
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* fill bogus with values which will cause glibc's pth_mx_unlock to fail */
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < 100; i++) bogus[i] = 0xFFFFFFFF;
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Unlocking a lock that is already unlocked */
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pthread_mutex_init( &mx1, NULL );
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pthread_mutex_lock( &mx1 );
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pthread_mutex_unlock( &mx1 );
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pthread_mutex_unlock( &mx1 ); /* ERROR */
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Unlocking a lock that is held by a different thread */
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pthread_mutex_init( &mx2, NULL );
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pthread_mutex_lock( &mx2 );
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // start child and get it to unlock this lock
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pthread_create( &child, NULL, child_fn, (void*)&mx2 );
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* child runs and attempts to unlock our lock.  Error
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         is reported in child_fn. */
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pthread_join(child, NULL );
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Unlocking a totally bogus lock. */
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pthread_mutex_unlock( (pthread_mutex_t*) &bogus[50] ); /* ERROR */
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Now we get a freeing-locked-lock error, since the stack
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      frame is removed whilst mx2 is still locked. */
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint main ( void )
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   nearly_main(); fprintf(stderr, "---------------------\n" );
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   nearly_main();
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return 0;
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
53