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., 15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 * 17 18 * This sample test aims to check the following assertion: 19 * If the mutex type is PTHREAD_MUTEX_RECURSIVE, 20 * and a thread attempts to unlock a mutex that it does not own, 21 * an error is returned. 22 23 * The steps are: 24 * -> Initialize and lock a recursive mutex 25 * -> create a child thread which tries to unlock this mutex. * 26 */ 27 28 /* 29 * - adam.li (at) intel.com 2004-05-20 30 * Add to PTS. Please refer to http://nptl.bullopensource.org/phpBB/ 31 * for general information 32 */ 33 34 /* We are testing conformance to IEEE Std 1003.1, 2003 Edition */ 35 #define _POSIX_C_SOURCE 200112L 36 37 /* We enable the following line to have mutex attributes defined */ 38 #ifndef WITHOUT_XOPEN 39 #define _XOPEN_SOURCE 600 40 41 /********************************************************************************************/ 42 /****************************** standard includes *****************************************/ 43 /********************************************************************************************/ 44 #include <pthread.h> 45 #include <unistd.h> 46 #include <stdlib.h> 47 #include <stdio.h> 48 #include <stdarg.h> 49 50 #include <errno.h> /* needed for EPERM test */ 51 52 /********************************************************************************************/ 53 /****************************** Test framework *****************************************/ 54 /********************************************************************************************/ 55 #include "../testfrmw/testfrmw.h" 56 #include "../testfrmw/testfrmw.c" 57 /* This header is responsible for defining the following macros: 58 * UNRESOLVED(ret, descr); 59 * where descr is a description of the error and ret is an int (error code for example) 60 * FAILED(descr); 61 * where descr is a short text saying why the test has failed. 62 * PASSED(); 63 * No parameter. 64 * 65 * Both three macros shall terminate the calling process. 66 * The testcase shall not terminate in any other maneer. 67 * 68 * The other file defines the functions 69 * void output_init() 70 * void output(char * string, ...) 71 * 72 * Those may be used to output information. 73 */ 74 75 /********************************************************************************************/ 76 /********************************** Configuration ******************************************/ 77 /********************************************************************************************/ 78 #ifndef VERBOSE 79 #define VERBOSE 1 80 #endif 81 82 /********************************************************************************************/ 83 /*********************************** Test case *****************************************/ 84 /********************************************************************************************/ 85 86 pthread_mutex_t m; 87 88 /** child thread function **/ 89 void *threaded(void *arg) 90 { 91 int ret; 92 ret = pthread_mutex_unlock(&m); 93 if (ret == 0) { 94 UNRESOLVED(ret, 95 "Unlocking a not owned recursive mutex succeeded"); 96 } 97 98 if (ret != EPERM) /* This is a "may" assertion */ 99 output 100 ("Unlocking a not owned recursive mutex did not return EPERM\n"); 101 102 return NULL; 103 } 104 105 /** parent thread function **/ 106 int main(void) 107 { 108 int ret; 109 pthread_mutexattr_t ma; 110 pthread_t th; 111 112 output_init(); 113 114 #if VERBOSE >1 115 output("Initialize the PTHREAD_MUTEX_RECURSIVE mutex\n"); 116 #endif 117 118 ret = pthread_mutexattr_init(&ma); 119 if (ret != 0) { 120 UNRESOLVED(ret, "Mutex attribute init failed"); 121 } 122 123 ret = pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE); 124 if (ret != 0) { 125 UNRESOLVED(ret, "Set type recursive failed"); 126 } 127 128 ret = pthread_mutex_init(&m, &ma); 129 if (ret != 0) { 130 UNRESOLVED(ret, "Mutex init failed"); 131 } 132 #if VERBOSE >1 133 output("Lock the mutex\n"); 134 #endif 135 136 ret = pthread_mutex_lock(&m); 137 if (ret != 0) { 138 UNRESOLVED(ret, "Mutex lock failed"); 139 } 140 141 /* destroy the mutex attribute object */ 142 ret = pthread_mutexattr_destroy(&ma); 143 if (ret != 0) { 144 UNRESOLVED(ret, "Mutex attribute destroy failed"); 145 } 146 #if VERBOSE >1 147 output("Create the thread\n"); 148 #endif 149 150 ret = pthread_create(&th, NULL, threaded, NULL); 151 if (ret != 0) { 152 UNRESOLVED(ret, "Thread creation failed"); 153 } 154 155 /* Let the thread terminate */ 156 ret = pthread_join(th, NULL); 157 if (ret != 0) { 158 UNRESOLVED(ret, "Thread join failed"); 159 } 160 #if VERBOSE >1 161 output("Joined the thread\n"); 162 #endif 163 164 /* We can clean everything and exit */ 165 ret = pthread_mutex_unlock(&m); 166 if (ret != 0) { 167 UNRESOLVED(ret, "Mutex unlock failed. Mutex got corrupted?"); 168 } 169 170 PASSED; 171 } 172 #else /* WITHOUT_XOPEN */ 173 int main(void) 174 { 175 output_init(); 176 UNTESTED("This test requires XSI features"); 177 } 178 #endif 179