1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <pthread.h> 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <unistd.h> 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <assert.h> 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <signal.h> 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Should see 3 threads exiting in different ways, all holding one (or 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown two) locks. */ 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownpthread_mutex_t mxC1 = PTHREAD_MUTEX_INITIALIZER; 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownpthread_mutex_t mxC2 = PTHREAD_MUTEX_INITIALIZER; 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownpthread_mutex_t mxC2b = PTHREAD_MUTEX_INITIALIZER; 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownpthread_mutex_t mxP = PTHREAD_MUTEX_INITIALIZER; 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This one exits in the normal way, by joining back */ 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid* child_fn1 ( void* arg ) 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int r= pthread_mutex_lock( &mxC1 ); assert(!r); 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This one detaches, does its own thing. */ 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid* child_fn2 ( void* arg ) 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int r; 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown r= pthread_mutex_lock( &mxC2 ); assert(!r); 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown r= pthread_mutex_lock( &mxC2b ); assert(!r); 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown r= pthread_detach( pthread_self() ); assert(!r); 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return NULL; 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Parent creates 2 children, takes a lock, waits, segfaults. Use 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sleeps to enforce exit ordering, for repeatable regtesting. */ 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint main ( void ) 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int r; 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_t child1, child2; 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown r= pthread_create(&child2, NULL, child_fn2, NULL); assert(!r); 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sleep(1); 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown r= pthread_create(&child1, NULL, child_fn1, NULL); assert(!r); 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown r= pthread_join(child1, NULL); assert(!r); 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sleep(1); 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown r= pthread_mutex_lock( &mxP ); 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown kill( getpid(), SIGABRT ); 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 51