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