1 /******************************************************************** 2 * COPYRIGHT: 3 * Copyright (c) 1999-2015, International Business Machines Corporation and 4 * others. All Rights Reserved. 5 ********************************************************************/ 6 7 #if defined(hpux) 8 # ifndef _INCLUDE_POSIX_SOURCE 9 # define _INCLUDE_POSIX_SOURCE 10 # endif 11 #endif 12 13 /* Define __EXTENSIONS__ for Solaris and old friends in strict mode. */ 14 #ifndef __EXTENSIONS__ 15 #define __EXTENSIONS__ 16 #endif 17 18 // Defines _XOPEN_SOURCE for access to POSIX functions. 19 // Must be before any other #includes. 20 #include "uposixdefs.h" 21 22 #include "simplethread.h" 23 24 #include "unicode/utypes.h" 25 #include "unicode/ustring.h" 26 #include "umutex.h" 27 #include "cmemory.h" 28 #include "cstring.h" 29 #include "uparse.h" 30 #include "unicode/resbund.h" 31 #include "unicode/udata.h" 32 #include "unicode/uloc.h" 33 #include "unicode/locid.h" 34 #include "putilimp.h" 35 #include "intltest.h" 36 37 #include <stdio.h> 38 #include <string.h> 39 #include <ctype.h> // tolower, toupper 40 41 #if U_PLATFORM_USES_ONLY_WIN32_API 42 /* Prefer native Windows APIs even if POSIX is implemented (i.e., on Cygwin). */ 43 # undef POSIX 44 #elif U_PLATFORM_IMPLEMENTS_POSIX 45 # define POSIX 46 #else 47 # undef POSIX 48 #endif 49 50 /* Needed by z/OS to get usleep */ 51 #if U_PLATFORM == U_PF_OS390 52 #define __DOT1 1 53 #ifndef __UU 54 # define __UU 55 #endif 56 #ifndef _XPG4_2 57 # define _XPG4_2 58 #endif 59 #include <unistd.h> 60 #endif 61 62 #if defined(POSIX) 63 #define HAVE_IMP 64 65 #include <pthread.h> 66 67 #if U_PLATFORM == U_PF_OS390 68 #include <sys/types.h> 69 #endif 70 71 #if U_PLATFORM != U_PF_OS390 72 #include <signal.h> 73 #endif 74 75 /* Define _XPG4_2 for Solaris and friends. */ 76 #ifndef _XPG4_2 77 #define _XPG4_2 78 #endif 79 80 /* Define __USE_XOPEN_EXTENDED for Linux and glibc. */ 81 #ifndef __USE_XOPEN_EXTENDED 82 #define __USE_XOPEN_EXTENDED 83 #endif 84 85 /* Define _INCLUDE_XOPEN_SOURCE_EXTENDED for HP/UX (11?). */ 86 #ifndef _INCLUDE_XOPEN_SOURCE_EXTENDED 87 #define _INCLUDE_XOPEN_SOURCE_EXTENDED 88 #endif 89 90 #include <unistd.h> 91 92 #endif 93 /* HPUX */ 94 #ifdef sleep 95 #undef sleep 96 #endif 97 98 99 #include "unicode/putil.h" 100 101 /* for mthreadtest*/ 102 #include "unicode/numfmt.h" 103 #include "unicode/choicfmt.h" 104 #include "unicode/msgfmt.h" 105 #include "unicode/locid.h" 106 #include "unicode/ucol.h" 107 #include "unicode/calendar.h" 108 #include "ucaconf.h" 109 110 #if U_PLATFORM_USES_ONLY_WIN32_API 111 #define HAVE_IMP 112 113 # define VC_EXTRALEAN 114 # define WIN32_LEAN_AND_MEAN 115 # define NOUSER 116 # define NOSERVICE 117 # define NOIME 118 # define NOMCX 119 #include <windows.h> 120 #include <process.h> 121 122 //----------------------------------------------------------------------------------- 123 // 124 // class SimpleThread Windows Implementation 125 // 126 //----------------------------------------------------------------------------------- 127 struct Win32ThreadImplementation 128 { 129 HANDLE fHandle; 130 unsigned int fThreadID; 131 }; 132 133 134 extern "C" unsigned int __stdcall SimpleThreadProc(void *arg) 135 { 136 ((SimpleThread*)arg)->run(); 137 return 0; 138 } 139 140 SimpleThread::SimpleThread() 141 :fImplementation(0) 142 { 143 Win32ThreadImplementation *imp = new Win32ThreadImplementation; 144 imp->fHandle = 0; 145 fImplementation = imp; 146 } 147 148 SimpleThread::~SimpleThread() 149 { 150 // Destructor. Because we start the thread running with _beginthreadex(), 151 // we own the Windows HANDLE for the thread and must 152 // close it here. 153 Win32ThreadImplementation *imp = (Win32ThreadImplementation*)fImplementation; 154 if (imp != 0) { 155 if (imp->fHandle != 0) { 156 CloseHandle(imp->fHandle); 157 imp->fHandle = 0; 158 } 159 } 160 delete (Win32ThreadImplementation*)fImplementation; 161 } 162 163 int32_t SimpleThread::start() 164 { 165 Win32ThreadImplementation *imp = (Win32ThreadImplementation*)fImplementation; 166 if(imp->fHandle != NULL) { 167 // The thread appears to have already been started. 168 // This is probably an error on the part of our caller. 169 return -1; 170 } 171 172 imp->fHandle = (HANDLE) _beginthreadex( 173 NULL, // Security 174 0x20000, // Stack Size 175 SimpleThreadProc, // Function to Run 176 (void *)this, // Arg List 177 0, // initflag. Start running, not suspended 178 &imp->fThreadID // thraddr 179 ); 180 181 if (imp->fHandle == 0) { 182 // An error occured 183 int err = errno; 184 if (err == 0) { 185 err = -1; 186 } 187 return err; 188 } 189 return 0; 190 } 191 192 193 void SimpleThread::join() { 194 Win32ThreadImplementation *imp = (Win32ThreadImplementation*)fImplementation; 195 if (imp->fHandle == 0) { 196 // No handle, thread must not be running. 197 return; 198 } 199 WaitForSingleObject(imp->fHandle, INFINITE); 200 } 201 202 #endif 203 204 205 //----------------------------------------------------------------------------------- 206 // 207 // class SimpleThread POSIX implementation 208 // 209 //----------------------------------------------------------------------------------- 210 #if defined(POSIX) 211 #define HAVE_IMP 212 213 struct PosixThreadImplementation 214 { 215 pthread_t fThread; 216 }; 217 218 extern "C" void* SimpleThreadProc(void *arg) 219 { 220 // This is the code that is run in the new separate thread. 221 SimpleThread *This = (SimpleThread *)arg; 222 This->run(); 223 return 0; 224 } 225 226 SimpleThread::SimpleThread() 227 { 228 PosixThreadImplementation *imp = new PosixThreadImplementation; 229 fImplementation = imp; 230 } 231 232 SimpleThread::~SimpleThread() 233 { 234 PosixThreadImplementation *imp = (PosixThreadImplementation*)fImplementation; 235 delete imp; 236 fImplementation = (void *)0xdeadbeef; 237 } 238 239 int32_t SimpleThread::start() 240 { 241 int32_t rc; 242 static pthread_attr_t attr; 243 static UBool attrIsInitialized = FALSE; 244 245 PosixThreadImplementation *imp = (PosixThreadImplementation*)fImplementation; 246 247 if (attrIsInitialized == FALSE) { 248 rc = pthread_attr_init(&attr); 249 #if U_PLATFORM == U_PF_OS390 250 { 251 int detachstate = 0; // jdc30: detach state of zero causes 252 //threads created with this attr to be in 253 //an undetached state. An undetached 254 //thread will keep its resources after 255 //termination. 256 pthread_attr_setdetachstate(&attr, &detachstate); 257 } 258 #else 259 // pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 260 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 261 #endif 262 attrIsInitialized = TRUE; 263 } 264 rc = pthread_create(&(imp->fThread), &attr, &SimpleThreadProc, (void*)this); 265 266 if (rc != 0) { 267 // some kind of error occured, the thread did not start. 268 } 269 270 return rc; 271 } 272 273 void SimpleThread::join() { 274 PosixThreadImplementation *imp = (PosixThreadImplementation*)fImplementation; 275 pthread_join(imp->fThread, NULL); 276 } 277 278 #endif 279 // end POSIX 280 281 282 #ifndef HAVE_IMP 283 #error No implementation for threads! Cannot test. 284 #endif 285