1/*
2 * Copyright (c) 2004, QUALCOMM Inc. All rights reserved.
3 * Created by:  abisain REMOVE-THIS AT qualcomm 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 pthread_cancel()
9 *
10 * Any destructors for thread_specific data will be called
11 *
12 * Steps:
13 * 1.  Create a new thread.
14 * 2.  Create a thread specific object in the thread with a destructor
15 * 3.  Call pthread_cancel on the thread.
16 * 4.  Make sure that the destructor was called
17 *
18 */
19
20#include <pthread.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <unistd.h>
24#include "posixtest.h"
25
26#define TEST "2-2"
27#define FUNCTION "pthread_cancel"
28#define ERROR_PREFIX "unexpected error: " FUNCTION " " TEST ": "
29
30int cleanup_flag = 0;
31int sem = 0;			/* manual semaphore */
32
33void destructor(void *tmp)
34{
35	cleanup_flag = 1;
36}
37
38/* Thread's function. */
39void *a_thread_func(void *tmp)
40{
41	pthread_key_t key;
42	int value = 1;
43	int rc = 0;
44
45	/* To enable thread immediate cancelation, since the default
46	 * is PTHREAD_CANCEL_DEFERRED. */
47	rc = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
48	if (rc != 0) {
49		printf(ERROR_PREFIX "pthread_setcanceltype\n");
50		exit(PTS_UNRESOLVED);
51	}
52
53	rc = pthread_key_create(&key, destructor);
54	if (rc != 0) {
55		printf(ERROR_PREFIX "pthread_key_create\n");
56		exit(PTS_UNRESOLVED);
57	}
58
59	rc = pthread_setspecific(key, &value);
60	if (rc != 0) {
61		printf(ERROR_PREFIX "pthread_setspecific\n");
62		exit(PTS_UNRESOLVED);
63	}
64
65	/* Tell main that the key is created */
66	sem = 1;
67
68	/* Sleep forever */
69	while (1)
70		sleep(5);
71	return NULL;
72}
73
74int main(void)
75{
76	pthread_t new_th;
77	int rc = 0;
78	sem = 0;
79
80	/* Create a new thread. */
81	rc = pthread_create(&new_th, NULL, a_thread_func, NULL);
82	if (rc != 0) {
83		printf(ERROR_PREFIX "pthread_create\n");
84		exit(PTS_UNRESOLVED);
85	}
86
87	/* Wait for the thread to be ready */
88	while (sem == 0)
89		sleep(1);
90
91	/* Cancel the thread. */
92	rc = pthread_cancel(new_th);
93	if (rc != 0) {
94		printf(ERROR_PREFIX "pthread_cancel\n");
95		exit(PTS_UNRESOLVED);
96	}
97
98	/* Delay enough so that the destructor must have been called */
99	sleep(5);
100
101	if (cleanup_flag != 1) {
102		printf(ERROR_PREFIX
103		       "Test FAIL: Destructor was not executed.\n");
104		exit(PTS_FAIL);
105	}
106
107	printf("Test PASSED\n");
108	exit(PTS_PASS);
109}
110