Home | History | Annotate | Download | only in pthread_join
      1 /*
      2  * Copyright (c) 2002, Intel Corporation. All rights reserved.
      3  * Created by:  rolla.n.selbak REMOVE-THIS AT intel DOT com
      4  * This file is licensed under the GPL license.  For the full content
      5  * of this license, see the COPYING file at the top level of this
      6  * source tree.
      7  *
      8  * Test that pthread_join()
      9  *
     10  * When pthread_join() returns successfully, the target thread has been
     11  * terminated.
     12  *
     13  * Steps:
     14  * 1.  Create a new thread.
     15  * 2.  Send a cancel request to it from main, then use pthread_join to
     16  *     wait for it to end.
     17  * 3.  The thread will sleep for 3 seconds, then call test_cancel() to
     18  *     cancel execution.
     19  * 4.  When this happens, the cleanup handler should be called.
     20  * 5.  Main will test that when pthread_join allows main to continue
     21  *     with the process that the thread has ended execution.  If the
     22  *     cleanup_handler was not called, then the test fails.
     23  */
     24 
     25 #include <pthread.h>
     26 #include <stdio.h>
     27 #include <string.h>
     28 #include <unistd.h>
     29 #include "posixtest.h"
     30 
     31 #define TIMEOUT 10
     32 static int cleanup_flag;
     33 
     34 /*
     35  * Cleanup function that the thread executes when it is canceled.  So if
     36  * cleanup_flag is 1, it means that the thread was canceled.
     37  */
     38 static void a_cleanup_func()
     39 {
     40 	cleanup_flag = 1;
     41 }
     42 
     43 static void *a_thread_func()
     44 {
     45 	int err;
     46 
     47 	err = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
     48 	if (err != 0) {
     49 		fprintf(stderr, "pthread_setcancelstate: %s", strerror(err));
     50 		goto thread_exit_failure;
     51 	}
     52 
     53 	err = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
     54 	if (err != 0) {
     55 		fprintf(stderr, "pthread_setcanceltype: %s", strerror(err));
     56 		goto thread_exit_failure;
     57 	}
     58 
     59 	/* Set up the cleanup handler */
     60 	pthread_cleanup_push(a_cleanup_func, NULL);
     61 
     62 	/* Wait for a timeout period for the cancel request to be sent. */
     63 	sleep(TIMEOUT);
     64 
     65 	/* Should not get here, but just in case pthread_testcancel() didn't
     66 	 * work -- the cancel request timed out. */
     67 	pthread_cleanup_pop(0);
     68 
     69 thread_exit_failure:
     70 	cleanup_flag = -1;
     71 
     72 	return NULL;
     73 }
     74 
     75 int main(void)
     76 {
     77 	pthread_t new_th;
     78 
     79 	int err;
     80 
     81 	err = pthread_create(&new_th, NULL, a_thread_func, NULL);
     82 	if (err != 0) {
     83 		fprintf(stderr, "pthread_create: %s\n", strerror(err));
     84 		return PTS_UNRESOLVED;
     85 	}
     86 
     87 	/* Remove potential for race */
     88 	sleep(TIMEOUT / 2);
     89 
     90 	err = pthread_cancel(new_th);
     91 	if (err != 0) {
     92 		fprintf(stderr, "pthread_cancel: %s\n", strerror(err));
     93 		return PTS_UNRESOLVED;
     94 	}
     95 
     96 	err = pthread_join(new_th, NULL);
     97 	if (err != 0) {
     98 		fprintf(stderr, "pthread_join: %s\n", strerror(err));
     99 		return PTS_UNRESOLVED;
    100 	}
    101 
    102 	if (cleanup_flag == 0) {
    103 		printf("Test FAILED: Thread did not finish execution when "
    104 		       "pthread_join returned.\n");
    105 		return PTS_FAIL;
    106 	}
    107 
    108 	if (cleanup_flag == -1) {
    109 		printf("Error in pthread_testcancel.  Cancel request timed "
    110 		       "out.\n");
    111 		return PTS_UNRESOLVED;
    112 	}
    113 
    114 	printf("Test PASSED\n");
    115 	return PTS_PASS;
    116 }
    117