1 // © 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 /* 4 ****************************************************************************** 5 * Copyright (C) 2001-2014, International Business Machines 6 * Corporation and others. All Rights Reserved. 7 ****************************************************************************** 8 * file name: ucln_cmn.cpp 9 * encoding: UTF-8 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" 19 #include "cmemory.h" 20 #include "mutex.h" 21 #include "uassert.h" 22 #include "ucln.h" 23 #include "ucln_cmn.h" 24 #include "utracimp.h" 25 #include "umutex.h" 26 27 /** Auto-client for UCLN_COMMON **/ 28 #define UCLN_TYPE_IS_COMMON 29 #include "ucln_imp.h" 30 31 static cleanupFunc *gCommonCleanupFunctions[UCLN_COMMON_COUNT]; 32 static cleanupFunc *gLibCleanupFunctions[UCLN_COMMON]; 33 34 35 /************************************************ 36 The cleanup order is important in this function. 37 Please be sure that you have read ucln.h 38 ************************************************/ 39 U_CAPI void U_EXPORT2 u_cleanup(void)40u_cleanup(void) 41 { 42 UTRACE_ENTRY_OC(UTRACE_U_CLEANUP); 43 umtx_lock(NULL); /* Force a memory barrier, so that we are sure to see */ 44 umtx_unlock(NULL); /* all state left around by any other threads. */ 45 46 ucln_lib_cleanup(); 47 48 cmemory_cleanup(); /* undo any heap functions set by u_setMemoryFunctions(). */ 49 UTRACE_EXIT(); /* Must be before utrace_cleanup(), which turns off tracing. */ 50 /*#if U_ENABLE_TRACING*/ 51 utrace_cleanup(); 52 /*#endif*/ 53 } 54 ucln_cleanupOne(ECleanupLibraryType libType)55U_CAPI void U_EXPORT2 ucln_cleanupOne(ECleanupLibraryType libType) 56 { 57 if (gLibCleanupFunctions[libType]) 58 { 59 gLibCleanupFunctions[libType](); 60 gLibCleanupFunctions[libType] = NULL; 61 } 62 } 63 64 U_CFUNC void ucln_common_registerCleanup(ECleanupCommonType type,cleanupFunc * func)65ucln_common_registerCleanup(ECleanupCommonType type, 66 cleanupFunc *func) 67 { 68 U_ASSERT(UCLN_COMMON_START < type && type < UCLN_COMMON_COUNT); 69 if (UCLN_COMMON_START < type && type < UCLN_COMMON_COUNT) 70 { 71 icu::Mutex m; // See ticket 10295 for discussion. 72 gCommonCleanupFunctions[type] = func; 73 } 74 #if !UCLN_NO_AUTO_CLEANUP && (defined(UCLN_AUTO_ATEXIT) || defined(UCLN_AUTO_LOCAL)) 75 ucln_registerAutomaticCleanup(); 76 #endif 77 } 78 79 // Note: ucln_registerCleanup() is called with the ICU global mutex locked. 80 // Be aware if adding anything to the function. 81 // See ticket 10295 for discussion. 82 83 U_CAPI void U_EXPORT2 ucln_registerCleanup(ECleanupLibraryType type,cleanupFunc * func)84ucln_registerCleanup(ECleanupLibraryType type, 85 cleanupFunc *func) 86 { 87 U_ASSERT(UCLN_START < type && type < UCLN_COMMON); 88 if (UCLN_START < type && type < UCLN_COMMON) 89 { 90 gLibCleanupFunctions[type] = func; 91 } 92 } 93 ucln_lib_cleanup(void)94U_CFUNC UBool ucln_lib_cleanup(void) { 95 int32_t libType = UCLN_START; 96 int32_t commonFunc = UCLN_COMMON_START; 97 98 for (libType++; libType<UCLN_COMMON; libType++) { 99 ucln_cleanupOne(static_cast<ECleanupLibraryType>(libType)); 100 } 101 102 for (commonFunc++; commonFunc<UCLN_COMMON_COUNT; commonFunc++) { 103 if (gCommonCleanupFunctions[commonFunc]) 104 { 105 gCommonCleanupFunctions[commonFunc](); 106 gCommonCleanupFunctions[commonFunc] = NULL; 107 } 108 } 109 #if !UCLN_NO_AUTO_CLEANUP && (defined(UCLN_AUTO_ATEXIT) || defined(UCLN_AUTO_LOCAL)) 110 ucln_unRegisterAutomaticCleanup(); 111 #endif 112 return TRUE; 113 } 114