Home | History | Annotate | Download | only in speculative
      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