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//----------------------------------------------------------------------------------- 127struct Win32ThreadImplementation 128{ 129 HANDLE fHandle; 130 unsigned int fThreadID; 131}; 132 133 134extern "C" unsigned int __stdcall SimpleThreadProc(void *arg) 135{ 136 ((SimpleThread*)arg)->run(); 137 return 0; 138} 139 140SimpleThread::SimpleThread() 141:fImplementation(0) 142{ 143 Win32ThreadImplementation *imp = new Win32ThreadImplementation; 144 imp->fHandle = 0; 145 fImplementation = imp; 146} 147 148SimpleThread::~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 163int32_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 193void 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 213struct PosixThreadImplementation 214{ 215 pthread_t fThread; 216}; 217 218extern "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 226SimpleThread::SimpleThread() 227{ 228 PosixThreadImplementation *imp = new PosixThreadImplementation; 229 fImplementation = imp; 230} 231 232SimpleThread::~SimpleThread() 233{ 234 PosixThreadImplementation *imp = (PosixThreadImplementation*)fImplementation; 235 delete imp; 236 fImplementation = (void *)0xdeadbeef; 237} 238 239int32_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 273void 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