1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************
359d709d503bab6e2b61931737e662dd293b40578ccornelius* Copyright (C) 2001-2013, International Business Machines
450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho*                Corporation and others. All Rights Reserved.
5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************
6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   file name:  ucln_cmn.c
7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   encoding:   US-ASCII
8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   tab size:   8 (not used)
9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   indentation:4
10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   created on: 2001July05
12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   created by: George Rhoten
13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/
14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h"
16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/uclean.h"
17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "utracimp.h"
18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucln_cmn.h"
1959d709d503bab6e2b61931737e662dd293b40578ccornelius#include "cmutex.h"
20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucln.h"
21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h"
22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uassert.h"
23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
2450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/**  Auto-client for UCLN_COMMON **/
25103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#define UCLN_TYPE_IS_COMMON
2650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "ucln_imp.h"
2750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic cleanupFunc *gCommonCleanupFunctions[UCLN_COMMON_COUNT];
29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic cleanupFunc *gLibCleanupFunctions[UCLN_COMMON];
30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
3154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius
32103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius/************************************************
33103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius The cleanup order is important in this function.
34103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius Please be sure that you have read ucln.h
35103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius ************************************************/
36103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusU_CAPI void U_EXPORT2
37103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusu_cleanup(void)
38103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius{
39103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    UTRACE_ENTRY_OC(UTRACE_U_CLEANUP);
40103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    umtx_lock(NULL);     /* Force a memory barrier, so that we are sure to see   */
41103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    umtx_unlock(NULL);   /*   all state left around by any other threads.        */
4250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
43103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    ucln_lib_cleanup();
4450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
45103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    cmemory_cleanup();       /* undo any heap functions set by u_setMemoryFunctions(). */
46103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    UTRACE_EXIT();           /* Must be before utrace_cleanup(), which turns off tracing. */
47103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius/*#if U_ENABLE_TRACING*/
48103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius    utrace_cleanup();
49103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius/*#endif*/
50103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}
5150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
52103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusU_CAPI void U_EXPORT2 ucln_cleanupOne(ECleanupLibraryType libType)
5350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{
5450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (gLibCleanupFunctions[libType])
5550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    {
5650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        gLibCleanupFunctions[libType]();
5750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        gLibCleanupFunctions[libType] = NULL;
5850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
5950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho}
6050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CFUNC void
62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucln_common_registerCleanup(ECleanupCommonType type,
63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            cleanupFunc *func)
64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    U_ASSERT(UCLN_COMMON_START < type && type < UCLN_COMMON_COUNT);
66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (UCLN_COMMON_START < type && type < UCLN_COMMON_COUNT)
67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        gCommonCleanupFunctions[type] = func;
69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
7050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if !UCLN_NO_AUTO_CLEANUP && (defined(UCLN_AUTO_ATEXIT) || defined(UCLN_AUTO_LOCAL))
7150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ucln_registerAutomaticCleanup();
7250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif
73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2
76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucln_registerCleanup(ECleanupLibraryType type,
77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                     cleanupFunc *func)
78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    U_ASSERT(UCLN_START < type && type < UCLN_COMMON);
80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (UCLN_START < type && type < UCLN_COMMON)
81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    {
82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        gLibCleanupFunctions[type] = func;
83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CFUNC UBool ucln_lib_cleanup(void) {
87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ECleanupLibraryType libType = UCLN_START;
88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ECleanupCommonType commonFunc = UCLN_COMMON_START;
89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (libType++; libType<UCLN_COMMON; libType++) {
91103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius        ucln_cleanupOne(libType);
92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (commonFunc++; commonFunc<UCLN_COMMON_COUNT; commonFunc++) {
95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (gCommonCleanupFunctions[commonFunc])
96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            gCommonCleanupFunctions[commonFunc]();
98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            gCommonCleanupFunctions[commonFunc] = NULL;
99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
10150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if !UCLN_NO_AUTO_CLEANUP && (defined(UCLN_AUTO_ATEXIT) || defined(UCLN_AUTO_LOCAL))
10250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ucln_unRegisterAutomaticCleanup();
10350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif
104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return TRUE;
105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
106