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