Example #1
0
U_CDECL_BEGIN
static UBool U_CALLCONV timeZone_cleanup(void)
{
#ifdef U_USE_TIMEZONE_OBSOLETE_2_8
    delete []OLSON_IDS;
    OLSON_IDS = 0;
#endif

    delete DEFAULT_ZONE;
    DEFAULT_ZONE = NULL;

    delete _GMT;
    _GMT = NULL;

    uprv_memset(TZDATA_VERSION, 0, sizeof(TZDATA_VERSION));
    TZDataVersionInitialized = FALSE;

    if (LOCK) {
        umtx_destroy(&LOCK);
        LOCK = NULL;
    }
    if (TZSET_LOCK) {
        umtx_destroy(&TZSET_LOCK);
        TZSET_LOCK = NULL;
    }

    return TRUE;
}
/**
 * Cleanup callback func
 */
static UBool U_CALLCONV zoneMeta_cleanup(void)
{
     umtx_destroy(&gZoneMetaLock);

    if (gCanonicalMap != NULL) {
        uhash_close(gCanonicalMap);
        gCanonicalMap = NULL;
    }
    gCanonicalMapInitialized = FALSE;

    if (gOlsonToMeta != NULL) {
        uhash_close(gOlsonToMeta);
        gOlsonToMeta = NULL;
    }
    gOlsonToMetaInitialized = FALSE;

    if (gMetaToOlson != NULL) {
        uhash_close(gMetaToOlson);
        gMetaToOlson = NULL;
    }
    gMetaToOlsonInitialized = FALSE;
    
    freeUStringTable();

    return TRUE;
}
Example #3
0
/*
 *  Mutex Cleanup Function
 *
 *      Destroy the global mutex(es), and reset the mutex function callback pointers.
 */
U_CFUNC UBool umtx_cleanup(void) {
    umtx_destroy(NULL);
    pMutexInitFn    = NULL;
    pMutexDestroyFn = NULL;
    pMutexLockFn    = NULL;
    pMutexUnlockFn  = NULL;
    gMutexContext   = NULL;
    gGlobalMutex    = NULL;
    pIncFn          = NULL;
    pDecFn          = NULL;
    gIncDecContext  = NULL;
    gIncDecMutex    = NULL;

#if (ICU_USE_THREADS == 1)
    if (gMutexPoolInitialized) {
        int i;
        for (i=0; i<MAX_MUTEXES; i++) {
            if (gMutexesInUse[i]) {
#if defined (U_WINDOWS)
                DeleteCriticalSection(&gMutexes[i]);
#elif defined (POSIX)
                pthread_mutex_destroy(&gMutexes[i]);
#endif
                gMutexesInUse[i] = 0;
            }
        }
    }
    gMutexPoolInitialized = FALSE;
#endif

    return TRUE;
}
/**
 * Free static memory.
 */
void TransliteratorIDParser::cleanup() {
    if (SPECIAL_INVERSES) {
        delete SPECIAL_INVERSES;
        SPECIAL_INVERSES = NULL;
    }
    umtx_destroy(&LOCK);
}
Example #5
0
UBool timeZone_cleanup()
{
    // Aliases into UDATA_MEMORY; do NOT delete
    DATA = NULL;
    INDEX_BY_ID = NULL;
    INDEX_BY_OFFSET = NULL;
    INDEX_BY_COUNTRY = NULL;

    delete []ZONE_IDS;
    ZONE_IDS = NULL;

    delete DEFAULT_ZONE;
    DEFAULT_ZONE = NULL;

    delete _GMT;
    _GMT = NULL;

    if (UDATA_MEMORY) {
        udata_close(UDATA_MEMORY);
        UDATA_MEMORY = NULL;
    }

    if (LOCK) {
        umtx_destroy(&LOCK);
        LOCK = NULL;
    }

    return TRUE;
}
Example #6
0
 /* This doesn't need to be thread safe. It's for u_cleanup only. */
 static void cleanup(void) {
     while (gCRegHead) {
         CReg* n = gCRegHead;
         gCRegHead = gCRegHead->next;
         delete n;
     }
     umtx_destroy(&gCRegLock);
 }
Example #7
0
ICUNotifier::~ICUNotifier(void) {
    {
        Mutex lmx(&notifyLock);
        delete listeners;
        listeners = NULL;
    }
    umtx_destroy(&notifyLock);
}
Example #8
0
CollDataCache::~CollDataCache()
{
    umtx_lock(&lock);
    uhash_close(cache);
    cache = NULL;
    umtx_unlock(&lock);

    umtx_destroy(&lock);
}
ICUService::~ICUService()
{
    {
        Mutex mutex(&lock);
        clearCaches();
        delete factories;
        factories = NULL;
    }
    umtx_destroy(&lock);
}
Example #10
0
U_CDECL_BEGIN
static UBool calendar_islamic_cleanup(void) {
    if (gMonthCache) {
        delete gMonthCache;
        gMonthCache = NULL;
    }
    if (gIslamicCalendarAstro) {
        delete gIslamicCalendarAstro;
        gIslamicCalendarAstro = NULL;
    }
    umtx_destroy(&astroLock);
    return TRUE;
}
Example #11
0
U_CFUNC UBool umtx_cleanup(void) {
    ICUMutex *thisMutex = NULL;
    ICUMutex *nextMutex = NULL;

    /* Extra, do-nothing function call to suppress compiler warnings on platforms where
     *   mutexed_compare_and_swap is not otherwise used.  */
    mutexed_compare_and_swap(&globalUMTX, NULL, NULL);

    /* Delete all of the ICU mutexes.  Do the global mutex last because it is used during
     * the umtx_destroy operation of other mutexes.
     */
    for (thisMutex=mutexListHead; thisMutex!=NULL; thisMutex=nextMutex) {
        UMTX *umtx = thisMutex->owner;
        nextMutex = thisMutex->next;
        U_ASSERT(*umtx = (void *)thisMutex);
        if (umtx != &globalUMTX) {
            umtx_destroy(umtx);
        }
    }
    umtx_destroy(&globalUMTX);
        
    pMutexInitFn    = NULL;
    pMutexDestroyFn = NULL;
    pMutexLockFn    = NULL;
    pMutexUnlockFn  = NULL;
    gMutexContext   = NULL;
    pIncFn          = NULL;
    pDecFn          = NULL;
    gIncDecContext  = NULL;
    gIncDecMutex    = NULL;

#if defined (POSIX) 
    /* POSIX platforms must come out of u_cleanup() with a functioning global mutex 
     * to permit the safe resumption of use of ICU in multi-threaded environments. 
     */
    umtx_init(&globalUMTX);
#endif
    return TRUE;
}
Example #12
0
U_CAPI void  U_EXPORT2
umtx_init(UMTX *mutex)
{
#if (ICU_USE_THREADS == 1)

    if (mutex == NULL) /* initialize the global mutex */
    {
        /* Note:  The initialization of the global mutex is NOT thread safe.   */
        if (gGlobalMutex != NULL) {
            return;
        }
        gGlobalMutex = umtx_raw_init(&gPlatformMutex);

       # ifdef POSIX_DEBUG_REENTRANCY
           gInMutex = FALSE;
       # endif
       #ifdef _DEBUG
           gRecursionCount = 0;
       #endif

       #ifdef POSIX
       umtx_raw_init(&gIncDecMutex);
       #endif

    } else {
        /* Not the global mutex.
         *  Thread safe initialization, using the global mutex.
         */  
        UBool isInitialized; 
        UMTX tMutex = NULL;

        umtx_lock(NULL);
        isInitialized = (*mutex != NULL);
        umtx_unlock(NULL);
        if (isInitialized) {  
            return;
        }

        tMutex = umtx_raw_init(NULL);

        umtx_lock(NULL);
        if (*mutex == NULL) {
            *mutex = tMutex;
            tMutex = NULL;
        }
        umtx_unlock(NULL);
        
        umtx_destroy(&tMutex);  /* NOP if (tmutex == NULL)  */
    }
#endif /* ICU_USE_THREADS==1 */
}
Example #13
0
U_NAMESPACE_END

U_CFUNC UBool calendar_islamic_cleanup(void) {
    if (gMonthCache) {
        delete gMonthCache;
        gMonthCache = NULL;
    }
    if (gIslamicCalendarAstro) {
        delete gIslamicCalendarAstro;
        gIslamicCalendarAstro = NULL;
    }
    umtx_destroy(&astroLock);
    return TRUE;
}
Example #14
0
U_NAMESPACE_END

// Defined in ucln_in.h:

U_CFUNC UBool utrans_transliterator_cleanup(void) {
    U_NAMESPACE_USE
    TransliteratorIDParser::cleanup();
    if (registry) {
        delete registry;
        registry = NULL;
    }
    umtx_destroy(&registryMutex);
    return TRUE;
}
Example #15
0
/*                Not supported  API.  Marked U_CAPI only for use by test programs.    */
U_CFUNC UBool U_EXPORT2 ucnv_cleanup(void) {
    if (SHARED_DATA_HASHTABLE != NULL) {
        ucnv_flushCache();
        if (SHARED_DATA_HASHTABLE != NULL && uhash_count(SHARED_DATA_HASHTABLE) == 0) {
            uhash_close(SHARED_DATA_HASHTABLE);
            SHARED_DATA_HASHTABLE = NULL;
        }
    }

    umtx_destroy(&cnvCacheMutex);           /* Don't worry about destroying the mutex even  */
                                            /*  if the hash table still exists.  The mutex  */
                                            /*  will lazily re-init  itself if needed.      */
    return (SHARED_DATA_HASHTABLE == NULL);
}
Example #16
0
static UBool U_CALLCONV usprep_cleanup(void){
    if (SHARED_DATA_HASHTABLE != NULL) {
        usprep_internal_flushCache(TRUE);
        if (SHARED_DATA_HASHTABLE != NULL && uhash_count(SHARED_DATA_HASHTABLE) == 0) {
            uhash_close(SHARED_DATA_HASHTABLE);
            SHARED_DATA_HASHTABLE = NULL;
        }
    }

    umtx_destroy(&usprepMutex);             /* Don't worry about destroying the mutex even  */
                                            /*  if the hash table still exists.  The mutex  */
                                            /*  will lazily re-init  itself if needed.      */
    return (SHARED_DATA_HASHTABLE == NULL);
}
Example #17
0
U_CDECL_BEGIN
static UBool U_CALLCONV timeZone_cleanup(void)
{
    delete DEFAULT_ZONE;
    DEFAULT_ZONE = NULL;

    delete _GMT;
    _GMT = NULL;

    uprv_memset(TZDATA_VERSION, 0, sizeof(TZDATA_VERSION));
    TZDataVersionInitialized = FALSE;

    if (LOCK) {
        umtx_destroy(&LOCK);
        LOCK = NULL;
    }
    if (TZSET_LOCK) {
        umtx_destroy(&TZSET_LOCK);
        TZSET_LOCK = NULL;
    }

    return TRUE;
}
Example #18
0
/************************************************
 The cleanup order is important in this function.
 Please be sure that you have read ucln.h
 ************************************************/
U_CAPI void U_EXPORT2
u_cleanup(void)
{
    ECleanupLibraryType libType;

    UTRACE_ENTRY_OC(UTRACE_U_CLEANUP);
    umtx_lock(NULL);     /* Force a memory barrier, so that we are sure to see   */
    umtx_unlock(NULL);   /*   all state left around by any other threads.        */

    for (libType = UCLN_START+1; libType<UCLN_COMMON; libType++) {
        if (gCleanupFunctions[libType])
        {
            gCleanupFunctions[libType]();
            gCleanupFunctions[libType] = NULL;
        }
    }

#if !UCONFIG_NO_IDNA
    usprep_cleanup();
#endif
#if !UCONFIG_NO_BREAK_ITERATION
	breakiterator_cleanup();
#endif
#if !UCONFIG_NO_SERVICE
    service_cleanup();
#endif
    ures_cleanup();
    locale_cleanup();
    uloc_cleanup();
#if !UCONFIG_NO_NORMALIZATION
    unorm_cleanup();
#endif
    uset_cleanup();
    unames_cleanup();
    pname_cleanup();
    uchar_cleanup();
    ucnv_cleanup();
    ucnv_io_cleanup();
    udata_cleanup();
    putil_cleanup();

    umtx_destroy(&gICUInitMutex);
    umtx_cleanup();
    cmemory_cleanup();       /* undo any heap functions set by u_setMemoryFunctions(). */
    gICUInitialized = FALSE;
    UTRACE_EXIT();           /* Must be before utrace_cleanup(), which turns off tracing. */
    utrace_cleanup();       
}
Example #19
0
/************************************************
 The cleanup order is important in this function.
 Please be sure that you have read ucln.h
 ************************************************/
U_CAPI void U_EXPORT2
u_cleanup(void)
{
    UTRACE_ENTRY_OC(UTRACE_U_CLEANUP);
    umtx_lock(NULL);     /* Force a memory barrier, so that we are sure to see   */
    umtx_unlock(NULL);   /*   all state left around by any other threads.        */

    ucln_lib_cleanup();

    umtx_destroy(&gICUInitMutex);
    umtx_cleanup();
    cmemory_cleanup();       /* undo any heap functions set by u_setMemoryFunctions(). */
    gICUInitialized = FALSE;
    UTRACE_EXIT();           /* Must be before utrace_cleanup(), which turns off tracing. */
/*#if U_ENABLE_TRACING*/
    utrace_cleanup();
/*#endif*/
}
Example #20
0
U_CDECL_BEGIN


/**
 * Cleanup callback func
 */
static UBool U_CALLCONV zoneMeta_cleanup(void)
{
     umtx_destroy(&gZoneMetaLock);

    if (gOlsonToMeta != NULL) {
        uhash_close(gOlsonToMeta);
        gOlsonToMeta = NULL;
    }
    gOlsonToMetaInitialized = FALSE;

    delete gSingleZoneCountries;
    delete gMultiZonesCountries;
    gCountryInfoVectorsInitialized = FALSE;

    return TRUE;
}
Example #21
0
U_CAPI void U_EXPORT2 
u_setMutexFunctions(const void *context, UMtxInitFn *i, UMtxFn *d, UMtxFn *l, UMtxFn *u,
                    UErrorCode *status) {
    if (U_FAILURE(*status)) {
        return;
    }

    /* Can not set a mutex function to a NULL value  */
    if (i==NULL || d==NULL || l==NULL || u==NULL) {
        *status = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }

    /* If ICU is not in an initial state, disallow this operation. */
    if (cmemory_inUse()) {
        *status = U_INVALID_STATE_ERROR;
        return;
    }
    
    /* Kill any existing global mutex.  POSIX platforms have a global mutex
     * even before any other part of ICU is initialized.
     */
    umtx_destroy(&globalUMTX);

    /* Swap in the mutex function pointers.  */
    pMutexInitFn    = i;
    pMutexDestroyFn = d;
    pMutexLockFn    = l;
    pMutexUnlockFn  = u;
    gMutexContext   = context;

#if defined (POSIX) 
    /* POSIX platforms must have a pre-initialized global mutex 
     * to allow other mutexes to initialize safely. */
    umtx_init(&globalUMTX);
#endif
}
Example #22
0
/*
 *  umtx_destroy.    Un-initialize a mutex, releasing any underlying resources
 *                   that it may be holding.  Destroying an already destroyed
 *                   mutex has no effect.  Unlike umtx_init(), this function
 *                   is not thread safe;  two threads must not concurrently try to
 *                   destroy the same mutex.
 */                  
U_CAPI void  U_EXPORT2
umtx_destroy(UMTX *mutex) {
    if (mutex == NULL) {  /* destroy the global mutex */
        mutex = &gGlobalMutex;
    }
    
    if (*mutex == NULL) {  /* someone already did it. */
        return;
    }

    /*  The life of the inc/dec mutex is tied to that of the global mutex.  */
    if (mutex == &gGlobalMutex) {
        umtx_destroy(&gIncDecMutex);
    }

    if (pMutexDestroyFn != NULL) {
        /* Mutexes are being managed by the app.  Call back to it for the destroy. */
        (*pMutexDestroyFn)(gMutexContext, mutex);
    }
    else {
#if (ICU_USE_THREADS == 1)
        /* Return this mutex to the pool of available mutexes, if it came from the
         *  pool in the first place.
         */
        /* TODO use pointer math here, instead of iterating! */
        int i;
        for (i=0; i<MAX_MUTEXES; i++)  {
            if (*mutex == &gMutexes[i]) {
                gMutexesInUse[i] = 0;
                break;
            }
        }
#endif
    }

    *mutex = NULL;
}
Example #23
0
ICULocaleService::~ICULocaleService()
{
  umtx_destroy(&llock);
}
Example #24
0
int main (int argc, char **argv)
{
    //
    //  Parse the command line options, and create the specified kind of test.
    //
    parseCommandLine(argc, argv);


    //
    //  Fire off the requested number of parallel threads
    //

    if (gRunInfo.numThreads == 0)
        exit(0);

    gRunInfo.exitFlag = FALSE;
    gRunInfo.stopFlag = TRUE;      // Will cause the new threads to block 
    umtx_lock(&gStopMutex);

    gThreadInfo = new ThreadInfo[gRunInfo.numThreads];
    int threadNum;
    for (threadNum=0; threadNum < gRunInfo.numThreads; threadNum++)
    {
        gThreadInfo[threadNum].fThreadNum = threadNum;
        ThreadFuncs::startThread(threadMain, &gThreadInfo[threadNum]);
    }


    unsigned long startTime = ThreadFuncs::getCurrentMillis();
    int elapsedSeconds = 0;
    int timeSinceCheck = 0;

    //
    // Unblock the threads.
    //
    gRunInfo.stopFlag = FALSE;       // Unblocks the worker threads.
    umtx_unlock(&gStopMutex);      

    //
    //  Loop, watching the heartbeat of the worker threads.
    //    Each second,
    //            display "+" if all threads have completed at least one loop
    //            display "." if some thread hasn't since previous "+"
    //    Each "ctime" seconds,
    //            Stop all the worker threads at the top of their loop, then
    //            call the test's check function.
    //
    while (gRunInfo.totalTime == 0 || gRunInfo.totalTime > elapsedSeconds)
    {
        ThreadFuncs::Sleep(1000);      // We sleep while threads do their work ...

        if (gRunInfo.quiet == false && gRunInfo.verbose == false)
        {
            char c = '+';
            int threadNum;
            umtx_lock(&gInfoMutex);
            for (threadNum=0; threadNum < gRunInfo.numThreads; threadNum++)
            {
                if (gThreadInfo[threadNum].fHeartBeat == false)
                {
                    c = '.';
                    break;
                };
            }
            umtx_unlock(&gInfoMutex);
            fputc(c, stdout);
            fflush(stdout);
            if (c == '+')
                for (threadNum=0; threadNum < gRunInfo.numThreads; threadNum++)
                    gThreadInfo[threadNum].fHeartBeat = false;
        }

        //
        // Update running times.
        //
        timeSinceCheck -= elapsedSeconds;
        elapsedSeconds = (ThreadFuncs::getCurrentMillis() - startTime) / 1000;
        timeSinceCheck += elapsedSeconds;

        //
        //  Call back to the test to let it check its internal validity
        //
        if (timeSinceCheck >= gRunInfo.checkTime) {
            if (gRunInfo.verbose) {
                fprintf(stderr, "Main: suspending all threads\n");
            }
            umtx_lock(&gStopMutex);               // Block the worker threads at the top of their loop
            gRunInfo.stopFlag = TRUE;
            for (;;) {
                umtx_lock(&gInfoMutex);
                UBool done = gRunInfo.runningThreads == 0;
                umtx_unlock(&gInfoMutex);
                if (done) { break;}
                ThreadFuncs::yield();
            }


            
            gRunInfo.fTest->check();
            if (gRunInfo.quiet == false && gRunInfo.verbose == false) {
                fputc('C', stdout);
            }

            if (gRunInfo.verbose) {
                fprintf(stderr, "Main: starting all threads.\n");
            }
            gRunInfo.stopFlag = FALSE;       // Unblock the worker threads.
            umtx_unlock(&gStopMutex);      
            timeSinceCheck = 0;
        }
    };

    //
    //  Time's up, we are done.  (We only get here if this was a timed run)
    //  Tell the threads to exit.
    //
    gRunInfo.exitFlag = true;
    for (;;) {
        umtx_lock(&gInfoMutex);
        UBool done = gRunInfo.runningThreads == 0;
        umtx_unlock(&gInfoMutex);
        if (done) { break;}
        ThreadFuncs::yield();
    }

    //
    //  Tally up the total number of cycles completed by each of the threads.
    //
    double totalCyclesCompleted = 0;
    for (threadNum=0; threadNum < gRunInfo.numThreads; threadNum++) {
        totalCyclesCompleted += gThreadInfo[threadNum].fCycles;
    }

    double cyclesPerMinute = totalCyclesCompleted / (double(gRunInfo.totalTime) / double(60));
    printf("\n%8.1f cycles per minute.", cyclesPerMinute);

    //
    //  Memory should be clean coming out
    //
    delete gRunInfo.fTest;
    delete [] gThreadInfo;
    umtx_destroy(&gInfoMutex);
    umtx_destroy(&gStopMutex);
    u_cleanup();

    return 0;
}
Example #25
0
void MultithreadTest::TestMutex()
{
    // Start up the test threads.  They should all pile up waiting on
    // gTestMutexA, which we (the main thread) hold until the test threads
    //   all get there.
    gThreadsStarted = 0;
    gThreadsInMiddle = 0;
    gThreadsDone = 0;
    umtx_lock(&gTestMutexA);
    TestMutexThread  *threads[TESTMUTEX_THREAD_COUNT];
    int i;
    int32_t numThreadsStarted = 0;
    for (i=0; i<TESTMUTEX_THREAD_COUNT; i++) {
        threads[i] = new TestMutexThread;
        if (threads[i]->start() != 0) {
            errln("Error starting thread %d", i);
        }
        else {
            numThreadsStarted++;
        }
    }
    if (numThreadsStarted == 0) {
        errln("No threads could be started for testing!");
        return;
    }

    int patience = 0;
    while (safeIncr(gThreadsStarted, 0) != TESTMUTEX_THREAD_COUNT) {
        if (patience++ > 24) {
            TSMTHREAD_FAIL("Patience Exceeded");
            return;
        }
        SimpleThread::sleep(500);
    }
    // None of the test threads should have advanced past the first mutex.
    TSMTHREAD_ASSERT(gThreadsInMiddle==0);
    TSMTHREAD_ASSERT(gThreadsDone==0);

    //  All of the test threads have made it to the first mutex.
    //  We (the main thread) now let them advance to the second mutex,
    //   where they should all pile up again.
    umtx_lock(&gTestMutexB);
    umtx_unlock(&gTestMutexA);

    patience = 0;
    while (safeIncr(gThreadsInMiddle, 0) != TESTMUTEX_THREAD_COUNT) {
        if (patience++ > 24) {
            TSMTHREAD_FAIL("Patience Exceeded");
            return;
        }
        SimpleThread::sleep(500);
    }
    TSMTHREAD_ASSERT(gThreadsDone==0);

    //  All test threads made it to the second mutex.
    //   Now let them proceed from there.  They will all terminate.
    umtx_unlock(&gTestMutexB);    
    patience = 0;
    while (safeIncr(gThreadsDone, 0) != TESTMUTEX_THREAD_COUNT) {
        if (patience++ > 24) {
            TSMTHREAD_FAIL("Patience Exceeded");
            return;
        }
        SimpleThread::sleep(500);
    }

    // All threads made it by both mutexes.
    // Destroy the test mutexes.
    umtx_destroy(&gTestMutexA);
    umtx_destroy(&gTestMutexB);
    gTestMutexA=NULL;
    gTestMutexB=NULL;

    for (i=0; i<TESTMUTEX_THREAD_COUNT; i++) {
        delete threads[i];
    }

}