150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/******************************************************************** 250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * COPYRIGHT: 359d709d503bab6e2b61931737e662dd293b40578ccornelius * Copyright (c) 1999-2013, International Business Machines Corporation and 450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * others. All Rights Reserved. 550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ********************************************************************/ 650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if defined(hpux) 850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho# ifndef _INCLUDE_POSIX_SOURCE 950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho# define _INCLUDE_POSIX_SOURCE 1050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho# endif 1150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 1250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 13103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius/* Define __EXTENSIONS__ for Solaris and old friends in strict mode. */ 14103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#ifndef __EXTENSIONS__ 15103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#define __EXTENSIONS__ 16103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#endif 17103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 18103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// Defines _XOPEN_SOURCE for access to POSIX functions. 19103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// Must be before any other #includes. 20103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "uposixdefs.h" 21103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 2250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "simplethread.h" 2350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 2450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/utypes.h" 2550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/ustring.h" 2650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "umutex.h" 2750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "cmemory.h" 2850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "cstring.h" 2950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "uparse.h" 3050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/resbund.h" 3150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/udata.h" 3250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/uloc.h" 3350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/locid.h" 3450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "putilimp.h" 3554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#include "intltest.h" 3650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 3750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include <stdio.h> 3850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include <string.h> 3950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include <ctype.h> // tolower, toupper 4050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 41103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM_USES_ONLY_WIN32_API 42103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius /* Prefer native Windows APIs even if POSIX is implemented (i.e., on Cygwin). */ 43103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius# undef POSIX 44103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM_IMPLEMENTS_POSIX 45103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius# define POSIX 46103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#else 47103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius# undef POSIX 4850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 4950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 5050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* Needed by z/OS to get usleep */ 51103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM == U_PF_OS390 5250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define __DOT1 1 5359d709d503bab6e2b61931737e662dd293b40578ccornelius#ifndef __UU 5459d709d503bab6e2b61931737e662dd293b40578ccornelius# define __UU 5559d709d503bab6e2b61931737e662dd293b40578ccornelius#endif 5650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#ifndef _XPG4_2 5759d709d503bab6e2b61931737e662dd293b40578ccornelius# define _XPG4_2 5850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 5950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include <unistd.h> 6050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 6150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 62103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if defined(POSIX) 6350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define HAVE_IMP 6450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 6550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if (ICU_USE_THREADS == 1) 6650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include <pthread.h> 6750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 6850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 6950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if defined(__hpux) && defined(HPUX_CMA) 7050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho# if defined(read) // read being defined as cma_read causes trouble with iostream::read 7150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho# undef read 7250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho# endif 7350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 7450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 75103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM == U_PF_OS390 7650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include <sys/types.h> 7750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 7850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 79103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM != U_PF_OS390 8050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include <signal.h> 8150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 8250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 8350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* Define _XPG4_2 for Solaris and friends. */ 8450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#ifndef _XPG4_2 8550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define _XPG4_2 8650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 8750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 8850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* Define __USE_XOPEN_EXTENDED for Linux and glibc. */ 8950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#ifndef __USE_XOPEN_EXTENDED 9050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define __USE_XOPEN_EXTENDED 9150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 9250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 9350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* Define _INCLUDE_XOPEN_SOURCE_EXTENDED for HP/UX (11?). */ 9450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#ifndef _INCLUDE_XOPEN_SOURCE_EXTENDED 9550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define _INCLUDE_XOPEN_SOURCE_EXTENDED 9650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 9750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 9850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include <unistd.h> 9950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 10050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 10150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* HPUX */ 10250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#ifdef sleep 10350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#undef sleep 10450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 10550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 10650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 10750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if (ICU_USE_THREADS==0) 10850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho SimpleThread::SimpleThread() 10950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho {} 11050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 11150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho SimpleThread::~SimpleThread() 11250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho {} 11350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 11450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t 11550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho SimpleThread::start() 11650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho { return -1; } 11750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 11850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho void 11950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho SimpleThread::run() 12050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho {} 12150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 12250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho void 12350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho SimpleThread::sleep(int32_t millis) 12450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho {} 12550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 12650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UBool 12750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho SimpleThread::isRunning() { 12850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return FALSE; 12950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 13050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#else 13150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 13250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/putil.h" 13350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 13450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/* for mthreadtest*/ 13550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/numfmt.h" 13650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/choicfmt.h" 13750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/msgfmt.h" 13850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/locid.h" 13950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/ucol.h" 14050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/calendar.h" 14150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "ucaconf.h" 14250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 143103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM_USES_ONLY_WIN32_API 14450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define HAVE_IMP 14550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 14650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho# define VC_EXTRALEAN 14750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho# define WIN32_LEAN_AND_MEAN 14850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho# define NOUSER 14950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho# define NOSERVICE 15050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho# define NOIME 15150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho# define NOMCX 15250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include <windows.h> 15350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include <process.h> 15450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 15550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//----------------------------------------------------------------------------------- 15650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// 15750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// class SimpleThread Windows Implementation 15850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// 15950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//----------------------------------------------------------------------------------- 16050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostruct Win32ThreadImplementation 16150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{ 16250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho HANDLE fHandle; 16350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho unsigned int fThreadID; 16450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}; 16550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 16650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 16750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoextern "C" unsigned int __stdcall SimpleThreadProc(void *arg) 16850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{ 16950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ((SimpleThread*)arg)->run(); 17050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return 0; 17150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 17250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 17350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSimpleThread::SimpleThread() 17450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho:fImplementation(0) 17550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{ 17650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Win32ThreadImplementation *imp = new Win32ThreadImplementation; 17750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho imp->fHandle = 0; 17850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fImplementation = imp; 17950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 18050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 18150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSimpleThread::~SimpleThread() 18250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{ 18350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Destructor. Because we start the thread running with _beginthreadex(), 18450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // we own the Windows HANDLE for the thread and must 18550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // close it here. 18650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Win32ThreadImplementation *imp = (Win32ThreadImplementation*)fImplementation; 18750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (imp != 0) { 18850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (imp->fHandle != 0) { 18950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho CloseHandle(imp->fHandle); 19050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho imp->fHandle = 0; 19150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 19250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 19350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho delete (Win32ThreadImplementation*)fImplementation; 19450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 19550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 19650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoint32_t SimpleThread::start() 19750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{ 19850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Win32ThreadImplementation *imp = (Win32ThreadImplementation*)fImplementation; 19950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(imp->fHandle != NULL) { 20050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // The thread appears to have already been started. 20150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // This is probably an error on the part of our caller. 20250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return -1; 20350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 20450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 20550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho imp->fHandle = (HANDLE) _beginthreadex( 20650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho NULL, // Security 20750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 0x20000, // Stack Size 20850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho SimpleThreadProc, // Function to Run 20950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (void *)this, // Arg List 21050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 0, // initflag. Start running, not suspended 21150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho &imp->fThreadID // thraddr 21250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ); 21350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 21450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (imp->fHandle == 0) { 21550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // An error occured 21650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int err = errno; 21750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (err == 0) { 21850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho err = -1; 21950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 22050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return err; 22150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 22250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return 0; 22350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 22450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 22550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 22650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUBool SimpleThread::isRunning() { 22750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // 22850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Test whether the thread associated with the SimpleThread object is 22950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // still actually running. 23050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // 23150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // NOTE: on Win64 on Itanium processors, a crashes 23250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // occur if the main thread of a process exits concurrently with some 23350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // other thread(s) exiting. To avoid the possibility, we wait until the 23450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // OS indicates that all threads have terminated, rather than waiting 23550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // only until the end of the user's Run function has been reached. 23650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // 23750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // I don't know whether the crashes represent a Windows bug, or whether 23850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // main() programs are supposed to have to wait for their threads. 23950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // 24050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Win32ThreadImplementation *imp = (Win32ThreadImplementation*)fImplementation; 24150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 24250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho bool success; 24350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho DWORD threadExitCode; 24450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 24550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (imp->fHandle == 0) { 24650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // No handle, thread must not be running. 24750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return FALSE; 24850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 24950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho success = GetExitCodeThread(imp->fHandle, &threadExitCode) != 0; 25050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (! success) { 25150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Can't get status, thread must not be running. 25250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return FALSE; 25350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 25450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return (threadExitCode == STILL_ACTIVE); 25550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 25650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 25750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 25850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid SimpleThread::sleep(int32_t millis) 25950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{ 26050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ::Sleep(millis); 26150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 26250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 26350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//----------------------------------------------------------------------------------- 26450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// 26550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// class SimpleThread NULL Implementation 26650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// 26750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//----------------------------------------------------------------------------------- 268103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM == U_PF_CLASSIC_MACOS 26950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 27050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// since the Mac has no preemptive threading (at least on MacOS 8), only 27150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// cooperative threading, threads are a no-op. We have no yield() calls 27250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// anywhere in the ICU, so we are guaranteed to be thread-safe. 27350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 27450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define HAVE_IMP 27550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 27650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSimpleThread::SimpleThread() 27750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{} 27850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 27950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSimpleThread::~SimpleThread() 28050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{} 28150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 28250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoint32_t 28350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSimpleThread::start() 28450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{ return 0; } 28550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 28650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid 28750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSimpleThread::run() 28850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{} 28950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 29050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid 29150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSimpleThread::sleep(int32_t millis) 29250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{} 29350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 29450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUBool 29550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSimpleThread::isRunning() { 29650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return FALSE; 29750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 29850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 29950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 30050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 30150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 30250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//----------------------------------------------------------------------------------- 30350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// 30450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// class SimpleThread POSIX implementation 30550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// 30650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// A note on the POSIX vs the Windows implementations of this class.. 30750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// On Windows, the main thread must verify that other threads have finished 30850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// before exiting, or crashes occasionally occur. (Seen on Itanium Win64 only) 30950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// The function SimpleThread::isRunning() is used for this purpose. 31050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// 31150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// On POSIX, there is NO reliable non-blocking mechanism to determine 31250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// whether a thread has exited. pthread_kill(thread, 0) almost works, 31350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// but the system can recycle thread ids immediately, so seeing that a 31450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// thread exists with this call could mean that the original thread has 31550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// finished and a new one started with the same ID. Useless. 31650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// 31750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// So we need to do the check with user code, by setting a flag just before 31850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// the thread function returns. A technique that is guaranteed to fail 31950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// on Windows, because it indicates that the thread is done before all 32050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// system level cleanup has happened. 32150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// 32250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//----------------------------------------------------------------------------------- 323103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if defined(POSIX) 32450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define HAVE_IMP 32550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 32650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostruct PosixThreadImplementation 32750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{ 32850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pthread_t fThread; 32950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UBool fRunning; 33050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UBool fRan; // True if the thread was successfully started 33150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}; 33250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 33350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoextern "C" void* SimpleThreadProc(void *arg) 33450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{ 33550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // This is the code that is run in the new separate thread. 33650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho SimpleThread *This = (SimpleThread *)arg; 33750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho This->run(); // Run the user code. 33850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 33950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // The user function has returned. Set the flag indicating that this thread 34050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // is done. Need a mutex for memory barrier purposes only, so that other thread 34150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // will reliably see that the flag has changed. 34250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho PosixThreadImplementation *imp = (PosixThreadImplementation*)This->fImplementation; 34350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho umtx_lock(NULL); 34450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho imp->fRunning = FALSE; 34550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho umtx_unlock(NULL); 34650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return 0; 34750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 34850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 34950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSimpleThread::SimpleThread() 35050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{ 35150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho PosixThreadImplementation *imp = new PosixThreadImplementation; 35250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho imp->fRunning = FALSE; 35350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho imp->fRan = FALSE; 35450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fImplementation = imp; 35550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 35650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 35750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSimpleThread::~SimpleThread() 35850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{ 35950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho PosixThreadImplementation *imp = (PosixThreadImplementation*)fImplementation; 36050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (imp->fRan) { 36150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pthread_join(imp->fThread, NULL); 36250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 36350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho delete imp; 36450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fImplementation = (void *)0xdeadbeef; 36550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 36650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 36750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoint32_t SimpleThread::start() 36850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{ 36950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t rc; 37050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho static pthread_attr_t attr; 37150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho static UBool attrIsInitialized = FALSE; 37250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 37350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho PosixThreadImplementation *imp = (PosixThreadImplementation*)fImplementation; 37450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho imp->fRunning = TRUE; 37550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho imp->fRan = TRUE; 37650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 37750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#ifdef HPUX_CMA 37850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (attrIsInitialized == FALSE) { 37950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho rc = pthread_attr_create(&attr); 38050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho attrIsInitialized = TRUE; 38150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 38250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho rc = pthread_create(&(imp->fThread),attr,&SimpleThreadProc,(void*)this); 38350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#else 38450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (attrIsInitialized == FALSE) { 38550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho rc = pthread_attr_init(&attr); 386103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM == U_PF_OS390 38750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho { 38850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int detachstate = 0; // jdc30: detach state of zero causes 38950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho //threads created with this attr to be in 39050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho //an undetached state. An undetached 39150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho //thread will keep its resources after 39250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho //termination. 39350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pthread_attr_setdetachstate(&attr, &detachstate); 39450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 39550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#else 39650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 39750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 39850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 39950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho attrIsInitialized = TRUE; 40050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 40150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho rc = pthread_create(&(imp->fThread),&attr,&SimpleThreadProc,(void*)this); 40250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 40350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 40450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (rc != 0) { 40550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // some kind of error occured, the thread did not start. 40650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho imp->fRan = FALSE; 40750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho imp->fRunning = FALSE; 40850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 40950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 41050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return rc; 41150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 41250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 41350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 41450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUBool 41550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSimpleThread::isRunning() { 41650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Note: Mutex functions are used here not for synchronization, 41750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // but to force memory barriors to exist, to ensure that one thread 41850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // can see changes made by another when running on processors 41950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // with memory models having weak coherency. 42050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho PosixThreadImplementation *imp = (PosixThreadImplementation*)fImplementation; 42150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho umtx_lock(NULL); 42250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UBool retVal = imp->fRunning; 42350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho umtx_unlock(NULL); 42450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return retVal; 42550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 42650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 42750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 42850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid SimpleThread::sleep(int32_t millis) 42950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{ 430103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM == U_PF_SOLARIS 43150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho sigignore(SIGALRM); 43250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 43350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 43450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#ifdef HPUX_CMA 43550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho cma_sleep(millis/100); 436103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM == U_PF_HPUX || U_PLATFORM == U_PF_OS390 43750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho millis *= 1000; 43850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho while(millis >= 1000000) { 43950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho usleep(999999); 44050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho millis -= 1000000; 44150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 44250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(millis > 0) { 44350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho usleep(millis); 44450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 44550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#else 44650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho usleep(millis * 1000); 44750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 44850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 44950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 45050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 45150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// end POSIX 45250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 45350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 45450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#ifndef HAVE_IMP 45550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#error No implementation for threads! Cannot test. 45650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho0 = 216; //die 45750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 45850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 45950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//------------------------------------------------------------------------------------------- 46050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// 46150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// class ThreadWithStatus - a thread that we can check the status and error condition of 46250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// 46350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//------------------------------------------------------------------------------------------- 46450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoclass ThreadWithStatus : public SimpleThread 46550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{ 46650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehopublic: 46750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UBool getError() { return (fErrors > 0); } 46850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UBool getError(UnicodeString& fillinError) { fillinError = fErrorString; return (fErrors > 0); } 46950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho virtual ~ThreadWithStatus(){} 47050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoprotected: 47150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ThreadWithStatus() : fErrors(0) {} 47250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho void error(const UnicodeString &error) { 47350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho fErrors++; fErrorString = error; 47450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho SimpleThread::errorFunc(); 47550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 47650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho void error() { error("An error occured."); } 47750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoprivate: 47850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t fErrors; 47950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UnicodeString fErrorString; 48050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}; 48150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 48250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif // ICU_USE_THREADS 483