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