]> git.saurik.com Git - apple/icu.git/blame - icuSources/common/ucln_cmn.cpp
ICU-66108.tar.gz
[apple/icu.git] / icuSources / common / ucln_cmn.cpp
CommitLineData
f3c0d7a5
A
1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
b75a7d8f
A
3/*
4******************************************************************************
b331163b 5* Copyright (C) 2001-2014, International Business Machines
729e4ab9 6* Corporation and others. All Rights Reserved.
b75a7d8f 7******************************************************************************
b331163b 8* file name: ucln_cmn.cpp
f3c0d7a5 9* encoding: UTF-8
b75a7d8f
A
10* tab size: 8 (not used)
11* indentation:4
12*
13* created on: 2001July05
14* created by: George Rhoten
15*/
16
17#include "unicode/utypes.h"
18#include "unicode/uclean.h"
374ca955 19#include "cmemory.h"
b331163b 20#include "mutex.h"
374ca955 21#include "uassert.h"
b331163b
A
22#include "ucln.h"
23#include "ucln_cmn.h"
24#include "utracimp.h"
25#include "umutex.h"
b75a7d8f 26
729e4ab9 27/** Auto-client for UCLN_COMMON **/
4388f060 28#define UCLN_TYPE_IS_COMMON
729e4ab9
A
29#include "ucln_imp.h"
30
374ca955 31static cleanupFunc *gCommonCleanupFunctions[UCLN_COMMON_COUNT];
73c04bcf 32static cleanupFunc *gLibCleanupFunctions[UCLN_COMMON];
b75a7d8f 33
51004dcb 34
4388f060
A
35/************************************************
36 The cleanup order is important in this function.
37 Please be sure that you have read ucln.h
38 ************************************************/
39U_CAPI void U_EXPORT2
40u_cleanup(void)
41{
42 UTRACE_ENTRY_OC(UTRACE_U_CLEANUP);
3d1f044b
A
43 icu::umtx_lock(NULL); /* Force a memory barrier, so that we are sure to see */
44 icu::umtx_unlock(NULL); /* all state left around by any other threads. */
729e4ab9 45
4388f060 46 ucln_lib_cleanup();
729e4ab9 47
4388f060 48 cmemory_cleanup(); /* undo any heap functions set by u_setMemoryFunctions(). */
4388f060
A
49 UTRACE_EXIT(); /* Must be before utrace_cleanup(), which turns off tracing. */
50/*#if U_ENABLE_TRACING*/
51 utrace_cleanup();
52/*#endif*/
53}
729e4ab9 54
4388f060 55U_CAPI void U_EXPORT2 ucln_cleanupOne(ECleanupLibraryType libType)
729e4ab9
A
56{
57 if (gLibCleanupFunctions[libType])
58 {
59 gLibCleanupFunctions[libType]();
60 gLibCleanupFunctions[libType] = NULL;
61 }
62}
63
73c04bcf
A
64U_CFUNC void
65ucln_common_registerCleanup(ECleanupCommonType type,
66 cleanupFunc *func)
b75a7d8f 67{
340931cb
A
68 // Thread safety messiness: From ticket 10295, calls to registerCleanup() may occur
69 // concurrently. Although such cases should be storing the same value, they raise errors
70 // from the thread sanity checker. Doing the store within a mutex avoids those.
71 // BUT that can trigger a recursive entry into std::call_once() in umutex.cpp when this code,
72 // running from the call_once function, tries to grab the ICU global mutex, which
73 // re-enters the mutex init path. So, work-around by special casing UCLN_COMMON_MUTEX, not
74 // using the ICU global mutex for it.
75 //
76 // No other point in ICU uses std::call_once().
77
374ca955 78 U_ASSERT(UCLN_COMMON_START < type && type < UCLN_COMMON_COUNT);
340931cb
A
79 if (type == UCLN_COMMON_MUTEX) {
80 gCommonCleanupFunctions[type] = func;
81 } else if (UCLN_COMMON_START < type && type < UCLN_COMMON_COUNT) {
b331163b 82 icu::Mutex m; // See ticket 10295 for discussion.
374ca955 83 gCommonCleanupFunctions[type] = func;
b75a7d8f 84 }
729e4ab9
A
85#if !UCLN_NO_AUTO_CLEANUP && (defined(UCLN_AUTO_ATEXIT) || defined(UCLN_AUTO_LOCAL))
86 ucln_registerAutomaticCleanup();
87#endif
b75a7d8f
A
88}
89
b331163b
A
90// Note: ucln_registerCleanup() is called with the ICU global mutex locked.
91// Be aware if adding anything to the function.
92// See ticket 10295 for discussion.
93
73c04bcf
A
94U_CAPI void U_EXPORT2
95ucln_registerCleanup(ECleanupLibraryType type,
96 cleanupFunc *func)
97{
98 U_ASSERT(UCLN_START < type && type < UCLN_COMMON);
99 if (UCLN_START < type && type < UCLN_COMMON)
100 {
101 gLibCleanupFunctions[type] = func;
102 }
103}
104
105U_CFUNC UBool ucln_lib_cleanup(void) {
b331163b
A
106 int32_t libType = UCLN_START;
107 int32_t commonFunc = UCLN_COMMON_START;
73c04bcf
A
108
109 for (libType++; libType<UCLN_COMMON; libType++) {
b331163b 110 ucln_cleanupOne(static_cast<ECleanupLibraryType>(libType));
73c04bcf 111 }
b75a7d8f 112
73c04bcf 113 for (commonFunc++; commonFunc<UCLN_COMMON_COUNT; commonFunc++) {
374ca955 114 if (gCommonCleanupFunctions[commonFunc])
b75a7d8f 115 {
374ca955
A
116 gCommonCleanupFunctions[commonFunc]();
117 gCommonCleanupFunctions[commonFunc] = NULL;
b75a7d8f 118 }
b75a7d8f 119 }
729e4ab9
A
120#if !UCLN_NO_AUTO_CLEANUP && (defined(UCLN_AUTO_ATEXIT) || defined(UCLN_AUTO_LOCAL))
121 ucln_unRegisterAutomaticCleanup();
122#endif
374ca955 123 return TRUE;
b75a7d8f 124}