1 /* 2 * Copyright (c) 2004, QUALCOMM Inc. All rights reserved. 3 * Copyright (c) 2017, Richard Palethorpe <rpalethorpe (at) suse.com> 4 * Created by: abisain REMOVE-THIS AT qualcomm DOT com 5 * This file is licensed under the GPL license. For the full content 6 * of this license, see the COPYING file at the top level of this 7 * source tree. 8 * 9 * Test that EBUSY is returned when pthread_cond_destroy() is called on a cond 10 * var that has waiters. POSIX only recommends this behaviour, the required 11 * behaviour is undefined. 12 * 13 * This test is very similar to pthread_barrier_destroy 2-1 which has more 14 * explanation attached. 15 */ 16 17 #include <pthread.h> 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <errno.h> 21 #include <unistd.h> 22 #include <string.h> 23 #include "posixtest.h" 24 25 pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 26 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 27 28 void *thread(void *tmp) 29 { 30 int rc = 0; 31 32 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); 33 34 rc = pthread_mutex_lock(&mutex); 35 if (rc != 0) { 36 perror("child: pthread_mutex_lock"); 37 exit(PTS_UNRESOLVED); 38 } 39 40 rc = pthread_cond_wait(&cond, &mutex); 41 if (rc != 0) { 42 perror("child: pthread_cond_wait"); 43 exit(PTS_UNSUPPORTED); 44 } 45 46 rc = pthread_mutex_unlock(&mutex); 47 if (rc != 0) { 48 perror("child: pthread_mutex_unlock"); 49 exit(PTS_UNSUPPORTED); 50 } 51 52 return tmp; 53 } 54 55 void *watchdog(void *arg) 56 { 57 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); 58 59 sleep(1); 60 printf("watchdog: pthread_cond_destroy() appears to be blocking\n"); 61 if (pthread_cond_signal(&cond)) { 62 perror("watchdog: pthread_cond_signal()"); 63 exit(PTS_UNRESOLVED); 64 } 65 66 return arg; 67 } 68 69 int main(void) 70 { 71 pthread_t low_id, watchdog_thread; 72 int rc = 0; 73 74 rc = pthread_create(&low_id, NULL, thread, NULL); 75 if (rc != 0) { 76 perror("main: pthread_create"); 77 exit(PTS_UNRESOLVED); 78 } 79 80 sleep(1); 81 82 rc = pthread_create(&watchdog_thread, NULL, watchdog, NULL); 83 if (rc != 0) { 84 perror("main: pthread_create"); 85 exit(PTS_UNRESOLVED); 86 } 87 88 rc = pthread_cond_destroy(&cond); 89 if (rc != EBUSY) { 90 printf("UNSUPPORTED: The standard recommends returning %d, EBUSY, but got %d, %s\n", 91 EBUSY, rc, strerror(rc)); 92 rc = PTS_UNSUPPORTED; 93 } else { 94 printf("PASSED: received EBUSY as per recommendation\n"); 95 rc = PTS_PASS; 96 } 97 98 pthread_cancel(watchdog_thread); 99 pthread_cancel(low_id); 100 101 exit(rc); 102 } 103