michael@0: /* michael@0: ****************************************************************************** michael@0: * Copyright (C) 2001-2013, International Business Machines michael@0: * Corporation and others. All Rights Reserved. michael@0: ****************************************************************************** michael@0: * file name: ucln_cmn.c michael@0: * encoding: US-ASCII michael@0: * tab size: 8 (not used) michael@0: * indentation:4 michael@0: * michael@0: * created on: 2001July05 michael@0: * created by: George Rhoten michael@0: */ michael@0: michael@0: #include "unicode/utypes.h" michael@0: #include "unicode/uclean.h" michael@0: #include "utracimp.h" michael@0: #include "ucln_cmn.h" michael@0: #include "cmutex.h" michael@0: #include "ucln.h" michael@0: #include "cmemory.h" michael@0: #include "uassert.h" michael@0: michael@0: /** Auto-client for UCLN_COMMON **/ michael@0: #define UCLN_TYPE_IS_COMMON michael@0: #include "ucln_imp.h" michael@0: michael@0: static cleanupFunc *gCommonCleanupFunctions[UCLN_COMMON_COUNT]; michael@0: static cleanupFunc *gLibCleanupFunctions[UCLN_COMMON]; michael@0: michael@0: michael@0: /************************************************ michael@0: The cleanup order is important in this function. michael@0: Please be sure that you have read ucln.h michael@0: ************************************************/ michael@0: U_CAPI void U_EXPORT2 michael@0: u_cleanup(void) michael@0: { michael@0: UTRACE_ENTRY_OC(UTRACE_U_CLEANUP); michael@0: umtx_lock(NULL); /* Force a memory barrier, so that we are sure to see */ michael@0: umtx_unlock(NULL); /* all state left around by any other threads. */ michael@0: michael@0: ucln_lib_cleanup(); michael@0: michael@0: cmemory_cleanup(); /* undo any heap functions set by u_setMemoryFunctions(). */ michael@0: UTRACE_EXIT(); /* Must be before utrace_cleanup(), which turns off tracing. */ michael@0: /*#if U_ENABLE_TRACING*/ michael@0: utrace_cleanup(); michael@0: /*#endif*/ michael@0: } michael@0: michael@0: U_CAPI void U_EXPORT2 ucln_cleanupOne(ECleanupLibraryType libType) michael@0: { michael@0: if (gLibCleanupFunctions[libType]) michael@0: { michael@0: gLibCleanupFunctions[libType](); michael@0: gLibCleanupFunctions[libType] = NULL; michael@0: } michael@0: } michael@0: michael@0: U_CFUNC void michael@0: ucln_common_registerCleanup(ECleanupCommonType type, michael@0: cleanupFunc *func) michael@0: { michael@0: U_ASSERT(UCLN_COMMON_START < type && type < UCLN_COMMON_COUNT); michael@0: if (UCLN_COMMON_START < type && type < UCLN_COMMON_COUNT) michael@0: { michael@0: gCommonCleanupFunctions[type] = func; michael@0: } michael@0: #if !UCLN_NO_AUTO_CLEANUP && (defined(UCLN_AUTO_ATEXIT) || defined(UCLN_AUTO_LOCAL)) michael@0: ucln_registerAutomaticCleanup(); michael@0: #endif michael@0: } michael@0: michael@0: U_CAPI void U_EXPORT2 michael@0: ucln_registerCleanup(ECleanupLibraryType type, michael@0: cleanupFunc *func) michael@0: { michael@0: U_ASSERT(UCLN_START < type && type < UCLN_COMMON); michael@0: if (UCLN_START < type && type < UCLN_COMMON) michael@0: { michael@0: gLibCleanupFunctions[type] = func; michael@0: } michael@0: } michael@0: michael@0: U_CFUNC UBool ucln_lib_cleanup(void) { michael@0: ECleanupLibraryType libType = UCLN_START; michael@0: ECleanupCommonType commonFunc = UCLN_COMMON_START; michael@0: michael@0: for (libType++; libType