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 pthread_cancel
9 * Shall request that 'thread' shall be canceled.  The target thread's
10 * cancelability state and type determines when the cancelation takes
11 * effect.
12 *
13 * Test when a thread is PTHREAD_CANCEL_ENABLE and PTHREAD_CANCEL_ASYNCHRONOUS
14 *
15 * STEPS:
16 * 1. Create a thread.
17 * 2. In the thread function, set the set and type to
18 *    PTHREAD_CANCEL_ENABLE and PTHREAD_CANCEL_ASYNCHRONOUS
19 * 3. Setup a cleanup handler for the thread.
20 * 4. Send out a thread cancel request to the new thread
21 * 5. If the cancel request was honored immediately and correctly, the
22 *    cleanup handler would have been executed, and the test will pass.
23 * 6. If not, the thread will wait for 10 seconds before it exits itself,
24 *    and the test will fail.
25 */
26
27#include <pthread.h>
28#include <stdio.h>
29#include <errno.h>
30#include <unistd.h>
31#include "posixtest.h"
32
33# define INTHREAD 0 	/* Control going to or is already for Thread */
34# define INMAIN 1	/* Control going to or is already for Main */
35
36int sem1;		/* Manual semaphore */
37int cleanup_flag;
38
39/* Cleanup function that the thread executes when it is canceled.  So if
40 * cleanup_flag is -1, it means that the thread was canceled. */
41void a_cleanup_func()
42{
43	cleanup_flag=1;
44	return;
45}
46
47/* Function that the thread executes upon its creation */
48void *a_thread_func()
49{
50	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
51	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
52
53	pthread_cleanup_push(a_cleanup_func,NULL);
54
55	/* Indicate to main() that the thread has been created. */
56	sem1=INMAIN;
57
58	/* Wait until main() has sent out a cancel request, meaning until it
59	 * sets sem1==0 */
60	while(sem1==1)
61		sleep(1);
62
63	/* Give thread 10 seconds to time out.  If the cancel request was not
64	 * honored until now, the test will fail. */
65	sleep(10);
66
67	/* Shouldn't get here if the cancel request was honored immediately
68	 * like it should have been. */
69	cleanup_flag=-1;
70	pthread_cleanup_pop(0);
71	pthread_exit(0);
72	return NULL;
73}
74
75int main()
76{
77	pthread_t new_th;
78
79	/* Initializing values */
80	sem1=INTHREAD;
81	cleanup_flag=0;
82
83	/* Create a new thread. */
84	if(pthread_create(&new_th, NULL, a_thread_func, NULL) != 0)
85	{
86		perror("Error creating thread\n");
87		return PTS_UNRESOLVED;
88	}
89
90	/* Make sure thread is created before we cancel it. (wait for
91	 * a_thread_func() to set sem1=1.) */
92	while(sem1==INTHREAD)
93		sleep(1);
94
95	if(pthread_cancel(new_th) != 0)
96	{
97		printf("Test FAILED: Couldn't cancel thread\n");
98		return PTS_FAIL;
99	}
100
101	/* Indicate to the thread function that the thread cancel request
102	 * has been sent to it. */
103	sem1=INTHREAD;
104
105	/* Wait for thread to return. (i.e. either canceled correctly and
106	 * called the cleanup function, or timed out after 10 seconds. */
107	while(cleanup_flag==INTHREAD)
108		sleep(1);
109
110	/* This means that the cleanup function wasn't called, so the cancel
111	 * request was not honord immediately like it should have been. */
112	if(cleanup_flag < 0)
113	{
114		printf("Test FAILED: Cancel request timed out\n");
115		return PTS_FAIL;
116	}
117
118	printf("Test PASSED\n");
119	return PTS_PASS;
120}
121
122
123