1ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes/*
2ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * Copyright (c) 2004, QUALCOMM Inc. All rights reserved.
3ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * Created by:  abisain REMOVE-THIS AT qualcomm DOT com
4ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * This file is licensed under the GPL license.  For the full content
5ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * of this license, see the COPYING file at the top level of this
6ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * source tree.
7ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes
8ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * Test pthread_cancel()
9ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes *
10ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * Any destructors for thread_specific data will be called
11ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes *
12ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * Steps:
13ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * 1.  Create a new thread.
14ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * 2.  Create a thread specific object in the thread with a destructor
15ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * 3.  Call pthread_cancel on the thread.
16ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes * 4.  Make sure that the destructor was called
17ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes *
18ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes */
19996bf79565ac88402920bd826d6f85952c83be20Elliott Hughes
2015c1945bb1810d061ea2d5b07a11e3ecc5ec8536Ruben Brunk#include <pthread.h>
21ad9208affa02f92a6b85354a33123d51d80febe1Elliott Hughes#include <stdio.h>
22ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes#include <stdlib.h>
23ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes#include <unistd.h>
24ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes#include "posixtest.h"
250a9d1ee45a9884a9616624d747172e18734e8fe0Elliott Hughes
266c1e5f4ad36c1f51687aa2b059e998a7c2db2e36Elliott Hughes#define TEST "2-2"
270b6b3e10459fc3a3f4dd280dab8d4a145f7bf2f0Elliott Hughes#define FUNCTION "pthread_cancel"
280568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughes#define ERROR_PREFIX "unexpected error: " FUNCTION " " TEST ": "
29e9f12043a1e2a29c60779cdb55c58eb156963570Elliott Hughes
300f746ff511162add42eeabaf14ba70ace874c6f4Elliott Hughesint cleanup_flag = 0;
31ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughesint sem = 0;			/* manual semaphore */
32ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes
330b6b3e10459fc3a3f4dd280dab8d4a145f7bf2f0Elliott Hughesvoid destructor(void *tmp)
34ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes{
351c039d71d3879f39e3a75b8788e656f7b4f88f08Elliott Hughes	cleanup_flag = 1;
36ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes}
370ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughes
38b974666d79ebc392b37ec1ae83aae57ae6331c08Elliott Hughes/* Thread's function. */
394f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughesvoid *a_thread_func(void *tmp)
400a9d1ee45a9884a9616624d747172e18734e8fe0Elliott Hughes{
4170c820401677ca251ad09ac64cc23c760764e75dElliott Hughes	pthread_key_t key;
42d4419fce71d11ec8494525eca65e54d1aab51de6Elliott Hughes	int value = 1;
43a5fb706fe4a6dbeaaf4cb1f8bbc2c68b0a2a3f3cElliott Hughes	int rc = 0;
44ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes
45461d0d860814c68154d8dd06d24f94118f33d28aElliott Hughes	/* To enable thread immediate cancelation, since the default
467e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughes	 * is PTHREAD_CANCEL_DEFERRED. */
4759e4744d27231f260271dbbca406e0cc39768116Elliott Hughes	rc = pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
4847cb338d43f75dd998b29caaaa9446c5705217d1Elliott Hughes	if (rc != 0) {
49069525a39125c203b658c805685b6045a7d4dfebElliott Hughes		printf(ERROR_PREFIX "pthread_setcanceltype\n");
500a9d1ee45a9884a9616624d747172e18734e8fe0Elliott Hughes		exit(PTS_UNRESOLVED);
510ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughes	}
52bbac92e691de7d570928ddfba639067978e55b06Elliott Hughes
537341b9ed7157a1e37a3e69a0974676da358b735aElliott Hughes	rc = pthread_key_create(&key, destructor);
549e67ca71d3d4a489a157abadc5ba519ced7a0b50Elliott Hughes	if (rc != 0) {
55bb5816aa1626eb2f6263bd21479600b114c8a1bdJohan Redestig		printf(ERROR_PREFIX "pthread_key_create\n");
560ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughes		exit(PTS_UNRESOLVED);
57ec617e2cb4a374f0fd8fbda4a633214cf23a59a9Elliott Hughes	}
58d4419fce71d11ec8494525eca65e54d1aab51de6Elliott Hughes
59d4419fce71d11ec8494525eca65e54d1aab51de6Elliott Hughes	rc = pthread_setspecific(key, &value);
60d4419fce71d11ec8494525eca65e54d1aab51de6Elliott Hughes	if (rc != 0) {
61d4419fce71d11ec8494525eca65e54d1aab51de6Elliott Hughes		printf(ERROR_PREFIX "pthread_setspecific\n");
621c039d71d3879f39e3a75b8788e656f7b4f88f08Elliott Hughes		exit(PTS_UNRESOLVED);
631c039d71d3879f39e3a75b8788e656f7b4f88f08Elliott Hughes	}
641c039d71d3879f39e3a75b8788e656f7b4f88f08Elliott Hughes
651c039d71d3879f39e3a75b8788e656f7b4f88f08Elliott Hughes	/* Tell main that the key is created */
661c039d71d3879f39e3a75b8788e656f7b4f88f08Elliott Hughes	sem = 1;
671c039d71d3879f39e3a75b8788e656f7b4f88f08Elliott Hughes
681c039d71d3879f39e3a75b8788e656f7b4f88f08Elliott Hughes	/* Sleep forever */
691c039d71d3879f39e3a75b8788e656f7b4f88f08Elliott Hughes	while (1)
70996bf79565ac88402920bd826d6f85952c83be20Elliott Hughes		sleep(5);
711124a814d698ed6fd68ac501f5dddfa103d656fdElliott Hughes	return NULL;
721124a814d698ed6fd68ac501f5dddfa103d656fdElliott Hughes}
731124a814d698ed6fd68ac501f5dddfa103d656fdElliott Hughes
74996bf79565ac88402920bd826d6f85952c83be20Elliott Hughesint main(void)
75996bf79565ac88402920bd826d6f85952c83be20Elliott Hughes{
76996bf79565ac88402920bd826d6f85952c83be20Elliott Hughes	pthread_t new_th;
771124a814d698ed6fd68ac501f5dddfa103d656fdElliott Hughes	int rc = 0;
781124a814d698ed6fd68ac501f5dddfa103d656fdElliott Hughes	sem = 0;
79996bf79565ac88402920bd826d6f85952c83be20Elliott Hughes
80996bf79565ac88402920bd826d6f85952c83be20Elliott Hughes	/* Create a new thread. */
811124a814d698ed6fd68ac501f5dddfa103d656fdElliott Hughes	rc = pthread_create(&new_th, NULL, a_thread_func, NULL);
821124a814d698ed6fd68ac501f5dddfa103d656fdElliott Hughes	if (rc != 0) {
831124a814d698ed6fd68ac501f5dddfa103d656fdElliott Hughes		printf(ERROR_PREFIX "pthread_create\n");
84996bf79565ac88402920bd826d6f85952c83be20Elliott Hughes		exit(PTS_UNRESOLVED);
85996bf79565ac88402920bd826d6f85952c83be20Elliott Hughes	}
861124a814d698ed6fd68ac501f5dddfa103d656fdElliott Hughes
871124a814d698ed6fd68ac501f5dddfa103d656fdElliott Hughes	/* Wait for the thread to be ready */
88996bf79565ac88402920bd826d6f85952c83be20Elliott Hughes	while (sem == 0)
89996bf79565ac88402920bd826d6f85952c83be20Elliott Hughes		sleep(1);
901124a814d698ed6fd68ac501f5dddfa103d656fdElliott Hughes
911124a814d698ed6fd68ac501f5dddfa103d656fdElliott Hughes	/* Cancel the thread. */
92996bf79565ac88402920bd826d6f85952c83be20Elliott Hughes	rc = pthread_cancel(new_th);
93996bf79565ac88402920bd826d6f85952c83be20Elliott Hughes	if (rc != 0) {
94996bf79565ac88402920bd826d6f85952c83be20Elliott Hughes		printf(ERROR_PREFIX "pthread_cancel\n");
95996bf79565ac88402920bd826d6f85952c83be20Elliott Hughes		exit(PTS_UNRESOLVED);
96996bf79565ac88402920bd826d6f85952c83be20Elliott Hughes	}
97996bf79565ac88402920bd826d6f85952c83be20Elliott Hughes
984f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes	/* Delay enough so that the destructor must have been called */
994f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes	sleep(5);
100ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes
101ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes	if (cleanup_flag != 1) {
102ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes		printf(ERROR_PREFIX
103ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes		       "Test FAIL: Destructor was not executed.\n");
104ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes		exit(PTS_FAIL);
105ddfdbb9d172fe9b72e08e8d7deab0aa3b8acf044Elliott Hughes	}
1064f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes
1074f11ebea266eada830d507b8f011e811a8e5d7bcElliott Hughes	printf("Test PASSED\n");
108f5333fd2094bdac4d6506177b1964b79afa64d77Elliott Hughes	exit(PTS_PASS);
109f5333fd2094bdac4d6506177b1964b79afa64d77Elliott Hughes}
110f5333fd2094bdac4d6506177b1964b79afa64d77Elliott Hughes