/* * This program is used to verify that when the owner of a robust mutex exit * prematurely without unlocking the mutex, the next owner will be successfully * acquire the mutex and get EOWNERDEAD returned. And, if that "next owner" * unlock this mutex without making it consistent, it will be unusable * permanently and any subsequent attempts to lock it using * "pthread_mutex_lock(3)" with return ENORECOVERABLE. * * Compile and link with -pthread */ #include #include #include #include pthread_mutex_t lock; void *original_owner_thread(void *ptr) { printf("[original owner] Setting lock...\n"); pthread_mutex_lock(&lock); printf("[original owner] Locked. Now exiting without unlocking.\n"); pthread_exit(NULL); } int main(int argc, char *argv[]) { pthread_t lock_getter; pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); /* initialize the attribute object */ pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST); pthread_mutex_init(&lock, &attr); /* initialize the lock */ pthread_create(&lock_getter, NULL, original_owner_thread, NULL); sleep(2); /* original_owner_thread should have exited now */ int ret_code; printf("Attempting to acquire unlock robust mutex.\n"); ret_code = pthread_mutex_lock(&lock); if(EOWNERDEAD == ret_code) { printf("EOWNERDEAD returned. Unlock the mutex without making it consistent.\n"); pthread_mutex_unlock(&lock); } /* try to acquire the lock again, and ENORECOVERABLE will be returned */ ret_code = pthread_mutex_lock(&lock); if(ENOTRECOVERABLE == ret_code) { printf("ENOTRECOVERABLE returned. This mutex is not recoverable now\n"); } return 0; }