1/* 2 * Copyright (c) 2004, Bull S.A.. All rights reserved. 3 * Created by: Sebastien Decugis 4 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of version 2 of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it would be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 * 13 * You should have received a copy of the GNU General Public License along 14 * with this program; if not, write the Free Software Foundation, Inc., 59 15 * Temple Place - Suite 330, Boston MA 02111-1307, USA. 16 * 17 18 19 * This sample test aims to check the following assertion: 20 * If the mutex type is PTHREAD_MUTEX_RECURSIVE, 21 * and a thread attempts to unlock a mutex that it does not own, 22 * an error is returned. 23 24 * The steps are: 25 * -> Initialize and lock a recursive mutex 26 * -> create a child thread which tries to unlock this mutex. * 27 */ 28 29 /* 30 * - adam.li@intel.com 2004-05-20 31 * Add to PTS. Please refer to http://nptl.bullopensource.org/phpBB/ 32 * for general information 33 */ 34 35 /* We are testing conformance to IEEE Std 1003.1, 2003 Edition */ 36 #define _POSIX_C_SOURCE 200112L 37 38 /* We enable the following line to have mutex attributes defined */ 39#ifndef WITHOUT_XOPEN 40 #define _XOPEN_SOURCE 600 41 42/********************************************************************************************/ 43/****************************** standard includes *****************************************/ 44/********************************************************************************************/ 45 #include <pthread.h> 46 #include <unistd.h> 47 #include <stdlib.h> 48 #include <stdio.h> 49 #include <stdarg.h> 50 51 #include <errno.h> /* needed for EPERM test */ 52 53/********************************************************************************************/ 54/****************************** Test framework *****************************************/ 55/********************************************************************************************/ 56 #include "testfrmw.h" 57 #include "testfrmw.c" 58 /* This header is responsible for defining the following macros: 59 * UNRESOLVED(ret, descr); 60 * where descr is a description of the error and ret is an int (error code for example) 61 * FAILED(descr); 62 * where descr is a short text saying why the test has failed. 63 * PASSED(); 64 * No parameter. 65 * 66 * Both three macros shall terminate the calling process. 67 * The testcase shall not terminate in any other maneer. 68 * 69 * The other file defines the functions 70 * void output_init() 71 * void output(char * string, ...) 72 * 73 * Those may be used to output information. 74 */ 75 76/********************************************************************************************/ 77/********************************** Configuration ******************************************/ 78/********************************************************************************************/ 79#ifndef VERBOSE 80#define VERBOSE 1 81#endif 82 83/********************************************************************************************/ 84/*********************************** Test case *****************************************/ 85/********************************************************************************************/ 86 87pthread_mutex_t m; 88 89/** child thread function **/ 90void * threaded(void * arg) 91{ 92 int ret; 93 ret = pthread_mutex_unlock(&m); 94 if (ret == 0) 95 { UNRESOLVED(ret, "Unlocking a not owned recursive mutex succeeded"); } 96 97 if (ret != EPERM) /* This is a "may" assertion */ 98 output("Unlocking a not owned recursive mutex did not return EPERM\n"); 99 100 return NULL; 101} 102 103/** parent thread function **/ 104int main(int argc, char * argv[]) 105{ 106 int ret; 107 pthread_mutexattr_t ma; 108 pthread_t th; 109 110 output_init(); 111 112 #if VERBOSE >1 113 output("Initialize the PTHREAD_MUTEX_RECURSIVE mutex\n"); 114 #endif 115 116 ret = pthread_mutexattr_init(&ma); 117 if (ret != 0) 118 { UNRESOLVED(ret, "Mutex attribute init failed"); } 119 120 ret = pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE); 121 if (ret != 0) 122 { UNRESOLVED(ret, "Set type recursive failed"); } 123 124 ret = pthread_mutex_init(&m, &ma); 125 if (ret != 0) 126 { UNRESOLVED(ret, "Mutex init failed"); } 127 128 #if VERBOSE >1 129 output("Lock the mutex\n"); 130 #endif 131 132 ret = pthread_mutex_lock(&m); 133 if (ret != 0) 134 { UNRESOLVED(ret, "Mutex lock failed"); } 135 136 /* destroy the mutex attribute object */ 137 ret = pthread_mutexattr_destroy(&ma); 138 if (ret != 0) 139 { UNRESOLVED(ret, "Mutex attribute destroy failed"); } 140 141 #if VERBOSE >1 142 output("Create the thread\n"); 143 #endif 144 145 ret = pthread_create(&th, NULL, threaded, NULL); 146 if (ret != 0) 147 { UNRESOLVED(ret, "Thread creation failed"); } 148 149 /* Let the thread terminate */ 150 ret = pthread_join(th, NULL); 151 if (ret != 0) 152 { UNRESOLVED(ret, "Thread join failed"); } 153 154 #if VERBOSE >1 155 output("Joined the thread\n"); 156 #endif 157 158 /* We can clean everything and exit */ 159 ret = pthread_mutex_unlock(&m); 160 if (ret != 0) 161 { UNRESOLVED(ret, "Mutex unlock failed. Mutex got corrupted?"); } 162 163 PASSED; 164} 165#else /* WITHOUT_XOPEN */ 166int main(int argc, char * argv[]) 167{ 168 output_init(); 169 UNTESTED("This test requires XSI features"); 170} 171#endif 172 173