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 * When the cancelation is acted on, the cancelation cleanup handlers for
10 * 'thread' shall be called.
11 *
12 * STEPS:
13 * 1. Create a thread
14 * 2. In the thread function, push a cleanup function onto the stack
15 * 3. Cancel the thread.  The cleanup function should be automatically
16 *    executed, else the test will fail.
17 */
18
19#include <pthread.h>
20#include <stdio.h>
21#include <errno.h>
22#include <unistd.h>
23#include "posixtest.h"
24
25int sem;			/* Manual semaphore */
26int cleanup_flag;		/* Made global so that the cleanup function
27				   can manipulate the value as well. */
28
29/* A cleanup function that sets the cleanup_flag to 1, meaning that the
30 * cleanup function was reached. */
31void a_cleanup_func()
32{
33	cleanup_flag=1;
34	sem=0;
35	return;
36}
37
38/* A thread function called at the creation of the thread. It will push
39 * the cleanup function onto it's stack, then go into a continuous 'while'
40 * loop, never reaching the cleanup_pop function.  So the only way the cleanup
41 * function can be called is when the thread is canceled and all the cleanup
42 * functions are supposed to be popped. */
43void *a_thread_func()
44{
45	/* To enable thread immediate cancelation, since the default
46	 * is PTHREAD_CANCEL_DEFERRED. */
47	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
48	pthread_cleanup_push(a_cleanup_func,NULL);
49	sem=1;
50	while(sem==1)
51		sleep(1);
52	sleep(5);
53	sem=0;
54	/* Should never be reached, but is required to be in the code
55	 * since pthread_cleanup_push is in the code.  Else a compile error
56	 * will result. */
57	pthread_cleanup_pop(0);
58	perror("Operation timed out, thread could not be canceled\n");
59	pthread_exit(0);
60	return NULL;
61}
62
63int main()
64{
65	pthread_t new_th;
66	int i;
67	/* Initializing the cleanup flag. */
68	cleanup_flag=0;
69	sem=0;
70
71	/* Create a new thread. */
72	if(pthread_create(&new_th, NULL, a_thread_func, NULL) != 0)
73	{
74		perror("Error creating thread\n");
75		return PTS_UNRESOLVED;
76	}
77
78	/* Make sure thread is created before we cancel it. */
79	while(sem==0)
80		sleep(1);
81
82	if(pthread_cancel(new_th) != 0)
83	{
84		printf("Error canceling thread\n");
85		return PTS_FAIL;
86	}
87
88	i=0;
89	while(sem==1)
90	{
91		sleep(1);
92		if(i==10)
93		{
94			printf("Test FAILED: Timed out while waiting for cancelation cleanup handlers to execute\n");
95			return PTS_FAIL;
96		}
97		i++;
98	}
99
100	/* If the cleanup function was not reached by calling the
101	 * pthread_cancel function, then the test fails. */
102	if(cleanup_flag != 1)
103	{
104		printf("Test FAILED: Could not cancel thread\n");
105		return PTS_FAIL;
106	}
107
108	printf("Test PASSED\n");
109	return PTS_PASS;
110}
111
112
113