1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/********************************************************************
2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * COPYRIGHT:
3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Copyright (c) 1999-2009, International Business Machines Corporation and
4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * others. All Rights Reserved.
5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ********************************************************************/
6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if defined(hpux)
8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)# ifndef _INCLUDE_POSIX_SOURCE
9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#  define _INCLUDE_POSIX_SOURCE
10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)# endif
11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "simplethread.h"
14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h"
16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ustring.h"
17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "umutex.h"
18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cmemory.h"
19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cstring.h"
20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "uparse.h"
21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/resbund.h"
22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/udata.h"
23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/uloc.h"
24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/locid.h"
25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "putilimp.h"
26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <stdio.h>
28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <string.h>
29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <ctype.h>    // tolower, toupper
30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !defined(U_WINDOWS) && !defined(XP_MAC) && !defined(U_RHAPSODY)
32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define POSIX 1
33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Needed by z/OS to get usleep */
36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if defined(OS390)
37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define __DOT1 1
38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define __UU
39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define _XOPEN_SOURCE_EXTENDED 1
40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifndef _XPG4_2
41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define _XPG4_2
42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <unistd.h>
44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*#include "platform_xopen_source_extended.h"*/
45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if defined(POSIX) || defined(U_SOLARIS) || defined(U_AIX) || defined(U_HPUX)
48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define HAVE_IMP
49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if (ICU_USE_THREADS == 1)
51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <pthread.h>
52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if defined(__hpux) && defined(HPUX_CMA)
55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)# if defined(read)  // read being defined as cma_read causes trouble with iostream::read
56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#  undef read
57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)# endif
58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Define __EXTENSIONS__ for Solaris and old friends in strict mode. */
61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifndef __EXTENSIONS__
62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define __EXTENSIONS__
63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if defined(OS390)
66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <sys/types.h>
67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !defined(OS390)
70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <signal.h>
71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Define _XPG4_2 for Solaris and friends. */
74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifndef _XPG4_2
75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define _XPG4_2
76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Define __USE_XOPEN_EXTENDED for Linux and glibc. */
79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifndef __USE_XOPEN_EXTENDED
80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define __USE_XOPEN_EXTENDED
81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Define _INCLUDE_XOPEN_SOURCE_EXTENDED for HP/UX (11?). */
84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifndef _INCLUDE_XOPEN_SOURCE_EXTENDED
85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define _INCLUDE_XOPEN_SOURCE_EXTENDED
86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <unistd.h>
89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* HPUX */
92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifdef sleep
93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#undef sleep
94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if (ICU_USE_THREADS==0)
98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    SimpleThread::SimpleThread()
99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {}
100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    SimpleThread::~SimpleThread()
102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {}
103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t
105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    SimpleThread::start()
106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    { return -1; }
107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    void
109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    SimpleThread::run()
110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {}
111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    void
113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    SimpleThread::sleep(int32_t millis)
114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {}
115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool
117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    SimpleThread::isRunning() {
118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return FALSE;
119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#else
121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/putil.h"
123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* for mthreadtest*/
125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/numfmt.h"
126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/choicfmt.h"
127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/msgfmt.h"
128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/locid.h"
129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ucol.h"
130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/calendar.h"
131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ucaconf.h"
132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifdef U_WINDOWS
134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define HAVE_IMP
135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#   define VC_EXTRALEAN
137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#   define WIN32_LEAN_AND_MEAN
138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#   define NOUSER
139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#   define NOSERVICE
140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#   define NOIME
141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#   define NOMCX
142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <windows.h>
143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <process.h>
144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-----------------------------------------------------------------------------------
146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//   class SimpleThread   Windows Implementation
148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-----------------------------------------------------------------------------------
150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)struct Win32ThreadImplementation
151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    HANDLE         fHandle;
153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    unsigned int   fThreadID;
154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)extern "C" unsigned int __stdcall SimpleThreadProc(void *arg)
158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ((SimpleThread*)arg)->run();
160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return 0;
161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleThread::SimpleThread()
164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles):fImplementation(0)
165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    Win32ThreadImplementation *imp = new Win32ThreadImplementation;
167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    imp->fHandle = 0;
168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fImplementation = imp;
169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleThread::~SimpleThread()
172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Destructor.  Because we start the thread running with _beginthreadex(),
174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //              we own the Windows HANDLE for the thread and must
175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //              close it here.
176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    Win32ThreadImplementation *imp = (Win32ThreadImplementation*)fImplementation;
177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (imp != 0) {
178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (imp->fHandle != 0) {
179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            CloseHandle(imp->fHandle);
180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            imp->fHandle = 0;
181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    delete (Win32ThreadImplementation*)fImplementation;
184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t SimpleThread::start()
187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    Win32ThreadImplementation *imp = (Win32ThreadImplementation*)fImplementation;
189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(imp->fHandle != NULL) {
190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // The thread appears to have already been started.
191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        //   This is probably an error on the part of our caller.
192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return -1;
193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    imp->fHandle = (HANDLE) _beginthreadex(
196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        NULL,                                 // Security
197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        0x20000,                              // Stack Size
198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        SimpleThreadProc,                     // Function to Run
199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        (void *)this,                         // Arg List
200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        0,                                    // initflag.  Start running, not suspended
201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        &imp->fThreadID                       // thraddr
202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        );
203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (imp->fHandle == 0) {
205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // An error occured
206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int err = errno;
207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (err == 0) {
208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            err = -1;
209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return err;
211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return 0;
213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool  SimpleThread::isRunning() {
217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //
218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //  Test whether the thread associated with the SimpleThread object is
219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //    still actually running.
220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //
221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //  NOTE:  on Win64 on Itanium processors, a crashes
222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //    occur if the main thread of a process exits concurrently with some
223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //    other thread(s) exiting.  To avoid the possibility, we wait until the
224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //    OS indicates that all threads have  terminated, rather than waiting
225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //    only until the end of the user's Run function has been reached.
226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //
227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //   I don't know whether the crashes represent a Windows bug, or whether
228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //    main() programs are supposed to have to wait for their threads.
229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //
230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    Win32ThreadImplementation *imp = (Win32ThreadImplementation*)fImplementation;
231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    bool      success;
233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    DWORD     threadExitCode;
234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (imp->fHandle == 0) {
236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // No handle, thread must not be running.
237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return FALSE;
238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    success = GetExitCodeThread(imp->fHandle,   &threadExitCode) != 0;
240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (! success) {
241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Can't get status, thread must not be running.
242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return FALSE;
243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return (threadExitCode == STILL_ACTIVE);
245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void SimpleThread::sleep(int32_t millis)
249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ::Sleep(millis);
251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-----------------------------------------------------------------------------------
254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//   class SimpleThread   NULL  Implementation
256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-----------------------------------------------------------------------------------
258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#elif defined XP_MAC
259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// since the Mac has no preemptive threading (at least on MacOS 8), only
261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// cooperative threading, threads are a no-op.  We have no yield() calls
262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// anywhere in the ICU, so we are guaranteed to be thread-safe.
263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define HAVE_IMP
265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleThread::SimpleThread()
267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){}
268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleThread::~SimpleThread()
270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){}
271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t
273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleThread::start()
274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ return 0; }
275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleThread::run()
278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){}
279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void
281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleThread::sleep(int32_t millis)
282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){}
283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool
285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleThread::isRunning() {
286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return FALSE;
287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-----------------------------------------------------------------------------------
293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//   class SimpleThread   POSIX implementation
295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//        A note on the POSIX vs the Windows implementations of this class..
297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//        On Windows, the main thread must verify that other threads have finished
298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//        before exiting, or crashes occasionally occur.  (Seen on Itanium Win64 only)
299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//        The function SimpleThread::isRunning() is used for this purpose.
300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//        On POSIX, there is NO reliable non-blocking mechanism to determine
302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//        whether a thread has exited.  pthread_kill(thread, 0) almost works,
303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//        but the system can recycle thread ids immediately, so seeing that a
304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//        thread exists with this call could mean that the original thread has
305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//        finished and a new one started with the same ID.  Useless.
306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//        So we need to do the check with user code, by setting a flag just before
308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//        the thread function returns.  A technique that is guaranteed to fail
309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//        on Windows, because it indicates that the thread is done before all
310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//        system level cleanup has happened.
311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-----------------------------------------------------------------------------------
313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if defined(POSIX)||defined(U_SOLARIS)||defined(U_AIX)||defined(U_HPUX)
314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define HAVE_IMP
315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)struct PosixThreadImplementation
317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    pthread_t        fThread;
319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool            fRunning;
320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool            fRan;          // True if the thread was successfully started
321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)extern "C" void* SimpleThreadProc(void *arg)
324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // This is the code that is run in the new separate thread.
326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    SimpleThread *This = (SimpleThread *)arg;
327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    This->run();      // Run the user code.
328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // The user function has returned.  Set the flag indicating that this thread
330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // is done.  Need a mutex for memory barrier purposes only, so that other thread
331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //   will reliably see that the flag has changed.
332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    PosixThreadImplementation *imp = (PosixThreadImplementation*)This->fImplementation;
333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    umtx_lock(NULL);
334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    imp->fRunning = FALSE;
335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    umtx_unlock(NULL);
336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return 0;
337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleThread::SimpleThread()
340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    PosixThreadImplementation *imp = new PosixThreadImplementation;
342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    imp->fRunning   = FALSE;
343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    imp->fRan       = FALSE;
344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fImplementation = imp;
345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleThread::~SimpleThread()
348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    PosixThreadImplementation *imp = (PosixThreadImplementation*)fImplementation;
350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (imp->fRan) {
351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        pthread_join(imp->fThread, NULL);
352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    delete imp;
354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fImplementation = (void *)0xdeadbeef;
355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t SimpleThread::start()
358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t        rc;
360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    static pthread_attr_t attr;
361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    static UBool attrIsInitialized = FALSE;
362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    PosixThreadImplementation *imp = (PosixThreadImplementation*)fImplementation;
364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    imp->fRunning = TRUE;
365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    imp->fRan     = TRUE;
366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifdef HPUX_CMA
368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (attrIsInitialized == FALSE) {
369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        rc = pthread_attr_create(&attr);
370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        attrIsInitialized = TRUE;
371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    rc = pthread_create(&(imp->fThread),attr,&SimpleThreadProc,(void*)this);
373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#else
374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (attrIsInitialized == FALSE) {
375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        rc = pthread_attr_init(&attr);
376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if defined(OS390)
377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            int detachstate = 0;  // jdc30: detach state of zero causes
379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                  //threads created with this attr to be in
380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                  //an undetached state.  An undetached
381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                  //thread will keep its resources after
382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                  //termination.
383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            pthread_attr_setdetachstate(&attr, &detachstate);
384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#else
386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        attrIsInitialized = TRUE;
390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    rc = pthread_create(&(imp->fThread),&attr,&SimpleThreadProc,(void*)this);
392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (rc != 0) {
395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // some kind of error occured, the thread did not start.
396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        imp->fRan     = FALSE;
397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        imp->fRunning = FALSE;
398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return rc;
401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool
405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)SimpleThread::isRunning() {
406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Note:  Mutex functions are used here not for synchronization,
407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //        but to force memory barriors to exist, to ensure that one thread
408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //        can see changes made by another when running on processors
409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //        with memory models having weak coherency.
410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    PosixThreadImplementation *imp = (PosixThreadImplementation*)fImplementation;
411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    umtx_lock(NULL);
412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool retVal = imp->fRunning;
413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    umtx_unlock(NULL);
414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return retVal;
415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void SimpleThread::sleep(int32_t millis)
419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifdef U_SOLARIS
421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    sigignore(SIGALRM);
422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifdef HPUX_CMA
425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    cma_sleep(millis/100);
426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#elif defined(U_HPUX) || defined(OS390)
427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    millis *= 1000;
428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while(millis >= 1000000) {
429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        usleep(999999);
430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        millis -= 1000000;
431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(millis > 0) {
433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        usleep(millis);
434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#else
436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    usleep(millis * 1000);
437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// end POSIX
442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifndef HAVE_IMP
445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#error  No implementation for threads! Cannot test.
446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)0 = 216; //die
447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-------------------------------------------------------------------------------------------
450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// class ThreadWithStatus - a thread that we can check the status and error condition of
452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-------------------------------------------------------------------------------------------
454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)class ThreadWithStatus : public SimpleThread
455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)public:
457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool  getError() { return (fErrors > 0); }
458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool  getError(UnicodeString& fillinError) { fillinError = fErrorString; return (fErrors > 0); }
459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    virtual ~ThreadWithStatus(){}
460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)protected:
461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ThreadWithStatus() :  fErrors(0) {}
462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    void error(const UnicodeString &error) {
463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fErrors++; fErrorString = error;
464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        SimpleThread::errorFunc();
465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    void error() { error("An error occured."); }
467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)private:
468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t fErrors;
469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString fErrorString;
470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif // ICU_USE_THREADS
473