Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* |
michael@0 | 2 | ****************************************************************************** |
michael@0 | 3 | * Copyright (C) 2001-2013, International Business Machines |
michael@0 | 4 | * Corporation and others. All Rights Reserved. |
michael@0 | 5 | ****************************************************************************** |
michael@0 | 6 | * file name: ucln_cmn.c |
michael@0 | 7 | * encoding: US-ASCII |
michael@0 | 8 | * tab size: 8 (not used) |
michael@0 | 9 | * indentation:4 |
michael@0 | 10 | * |
michael@0 | 11 | * created on: 2001July05 |
michael@0 | 12 | * created by: George Rhoten |
michael@0 | 13 | */ |
michael@0 | 14 | |
michael@0 | 15 | #include "unicode/utypes.h" |
michael@0 | 16 | #include "unicode/uclean.h" |
michael@0 | 17 | #include "utracimp.h" |
michael@0 | 18 | #include "ucln_cmn.h" |
michael@0 | 19 | #include "cmutex.h" |
michael@0 | 20 | #include "ucln.h" |
michael@0 | 21 | #include "cmemory.h" |
michael@0 | 22 | #include "uassert.h" |
michael@0 | 23 | |
michael@0 | 24 | /** Auto-client for UCLN_COMMON **/ |
michael@0 | 25 | #define UCLN_TYPE_IS_COMMON |
michael@0 | 26 | #include "ucln_imp.h" |
michael@0 | 27 | |
michael@0 | 28 | static cleanupFunc *gCommonCleanupFunctions[UCLN_COMMON_COUNT]; |
michael@0 | 29 | static cleanupFunc *gLibCleanupFunctions[UCLN_COMMON]; |
michael@0 | 30 | |
michael@0 | 31 | |
michael@0 | 32 | /************************************************ |
michael@0 | 33 | The cleanup order is important in this function. |
michael@0 | 34 | Please be sure that you have read ucln.h |
michael@0 | 35 | ************************************************/ |
michael@0 | 36 | U_CAPI void U_EXPORT2 |
michael@0 | 37 | u_cleanup(void) |
michael@0 | 38 | { |
michael@0 | 39 | UTRACE_ENTRY_OC(UTRACE_U_CLEANUP); |
michael@0 | 40 | umtx_lock(NULL); /* Force a memory barrier, so that we are sure to see */ |
michael@0 | 41 | umtx_unlock(NULL); /* all state left around by any other threads. */ |
michael@0 | 42 | |
michael@0 | 43 | ucln_lib_cleanup(); |
michael@0 | 44 | |
michael@0 | 45 | cmemory_cleanup(); /* undo any heap functions set by u_setMemoryFunctions(). */ |
michael@0 | 46 | UTRACE_EXIT(); /* Must be before utrace_cleanup(), which turns off tracing. */ |
michael@0 | 47 | /*#if U_ENABLE_TRACING*/ |
michael@0 | 48 | utrace_cleanup(); |
michael@0 | 49 | /*#endif*/ |
michael@0 | 50 | } |
michael@0 | 51 | |
michael@0 | 52 | U_CAPI void U_EXPORT2 ucln_cleanupOne(ECleanupLibraryType libType) |
michael@0 | 53 | { |
michael@0 | 54 | if (gLibCleanupFunctions[libType]) |
michael@0 | 55 | { |
michael@0 | 56 | gLibCleanupFunctions[libType](); |
michael@0 | 57 | gLibCleanupFunctions[libType] = NULL; |
michael@0 | 58 | } |
michael@0 | 59 | } |
michael@0 | 60 | |
michael@0 | 61 | U_CFUNC void |
michael@0 | 62 | ucln_common_registerCleanup(ECleanupCommonType type, |
michael@0 | 63 | cleanupFunc *func) |
michael@0 | 64 | { |
michael@0 | 65 | U_ASSERT(UCLN_COMMON_START < type && type < UCLN_COMMON_COUNT); |
michael@0 | 66 | if (UCLN_COMMON_START < type && type < UCLN_COMMON_COUNT) |
michael@0 | 67 | { |
michael@0 | 68 | gCommonCleanupFunctions[type] = func; |
michael@0 | 69 | } |
michael@0 | 70 | #if !UCLN_NO_AUTO_CLEANUP && (defined(UCLN_AUTO_ATEXIT) || defined(UCLN_AUTO_LOCAL)) |
michael@0 | 71 | ucln_registerAutomaticCleanup(); |
michael@0 | 72 | #endif |
michael@0 | 73 | } |
michael@0 | 74 | |
michael@0 | 75 | U_CAPI void U_EXPORT2 |
michael@0 | 76 | ucln_registerCleanup(ECleanupLibraryType type, |
michael@0 | 77 | cleanupFunc *func) |
michael@0 | 78 | { |
michael@0 | 79 | U_ASSERT(UCLN_START < type && type < UCLN_COMMON); |
michael@0 | 80 | if (UCLN_START < type && type < UCLN_COMMON) |
michael@0 | 81 | { |
michael@0 | 82 | gLibCleanupFunctions[type] = func; |
michael@0 | 83 | } |
michael@0 | 84 | } |
michael@0 | 85 | |
michael@0 | 86 | U_CFUNC UBool ucln_lib_cleanup(void) { |
michael@0 | 87 | ECleanupLibraryType libType = UCLN_START; |
michael@0 | 88 | ECleanupCommonType commonFunc = UCLN_COMMON_START; |
michael@0 | 89 | |
michael@0 | 90 | for (libType++; libType<UCLN_COMMON; libType++) { |
michael@0 | 91 | ucln_cleanupOne(libType); |
michael@0 | 92 | } |
michael@0 | 93 | |
michael@0 | 94 | for (commonFunc++; commonFunc<UCLN_COMMON_COUNT; commonFunc++) { |
michael@0 | 95 | if (gCommonCleanupFunctions[commonFunc]) |
michael@0 | 96 | { |
michael@0 | 97 | gCommonCleanupFunctions[commonFunc](); |
michael@0 | 98 | gCommonCleanupFunctions[commonFunc] = NULL; |
michael@0 | 99 | } |
michael@0 | 100 | } |
michael@0 | 101 | #if !UCLN_NO_AUTO_CLEANUP && (defined(UCLN_AUTO_ATEXIT) || defined(UCLN_AUTO_LOCAL)) |
michael@0 | 102 | ucln_unRegisterAutomaticCleanup(); |
michael@0 | 103 | #endif |
michael@0 | 104 | return TRUE; |
michael@0 | 105 | } |