michael@0: /* michael@0: ****************************************************************************** michael@0: * michael@0: * Copyright (C) 2009-2011, International Business Machines michael@0: * Corporation and others. All Rights Reserved. michael@0: * michael@0: ****************************************************************************** michael@0: * file name: ucln_imp.h michael@0: * encoding: US-ASCII michael@0: * tab size: 8 (not used) michael@0: * indentation:4 michael@0: * michael@0: * This file contains the platform specific implementation of per-library cleanup. michael@0: * michael@0: */ michael@0: michael@0: michael@0: #ifndef __UCLN_IMP_H__ michael@0: #define __UCLN_IMP_H__ michael@0: michael@0: #include "ucln.h" michael@0: #include michael@0: michael@0: /** michael@0: * Auto cleanup of ICU libraries michael@0: * There are several methods in per library cleanup of icu libraries: michael@0: * 1) Compiler/Platform based cleanup: michael@0: * a) Windows MSVC uses DllMain() michael@0: * b) GCC uses destructor function attribute michael@0: * c) Sun Studio, AIX VA, and HP-UX aCC uses a linker option to set the exit function michael@0: * 2) Using atexit() michael@0: * 3) Implementing own automatic cleanup functions michael@0: * michael@0: * For option 1, ensure that UCLN_NO_AUTO_CLEANUP is set to 0 by using --enable-auto-cleanup michael@0: * configure option or by otherwise setting UCLN_NO_AUTO_CLEANUP to 0 michael@0: * For option 2, follow option 1 and also define UCLN_AUTO_ATEXIT michael@0: * For option 3, follow option 1 and also define UCLN_AUTO_LOCAL (see below for more information) michael@0: */ michael@0: michael@0: #if !UCLN_NO_AUTO_CLEANUP michael@0: michael@0: /* michael@0: * The following declarations are for when UCLN_AUTO_LOCAL or UCLN_AUTO_ATEXIT michael@0: * are defined. They are commented out because they are static and will be defined michael@0: * later. The information is still here to provide some guidance for the developer michael@0: * who chooses to use UCLN_AUTO_LOCAL. michael@0: */ michael@0: /** michael@0: * Give the library an opportunity to register an automatic cleanup. michael@0: * This may be called more than once. michael@0: */ michael@0: /*static void ucln_registerAutomaticCleanup();*/ michael@0: /** michael@0: * Unregister an automatic cleanup, if possible. Called from cleanup. michael@0: */ michael@0: /*static void ucln_unRegisterAutomaticCleanup();*/ michael@0: michael@0: #ifdef UCLN_TYPE_IS_COMMON michael@0: # define UCLN_CLEAN_ME_UP u_cleanup() michael@0: #else michael@0: # define UCLN_CLEAN_ME_UP ucln_cleanupOne(UCLN_TYPE) michael@0: #endif michael@0: michael@0: /* ------------ automatic cleanup: registration. Choose ONE ------- */ michael@0: #if defined(UCLN_AUTO_LOCAL) michael@0: /* To use: michael@0: * 1. define UCLN_AUTO_LOCAL, michael@0: * 2. create ucln_local_hook.c containing implementations of michael@0: * static void ucln_registerAutomaticCleanup() michael@0: * static void ucln_unRegisterAutomaticCleanup() michael@0: */ michael@0: #include "ucln_local_hook.c" michael@0: michael@0: #elif defined(UCLN_AUTO_ATEXIT) michael@0: /* michael@0: * Use the ANSI C 'atexit' function. Note that this mechanism does not michael@0: * guarantee the order of cleanup relative to other users of ICU! michael@0: */ michael@0: static UBool gAutoCleanRegistered = FALSE; michael@0: michael@0: static void ucln_atexit_handler() michael@0: { michael@0: UCLN_CLEAN_ME_UP; michael@0: } michael@0: michael@0: static void ucln_registerAutomaticCleanup() michael@0: { michael@0: if(!gAutoCleanRegistered) { michael@0: gAutoCleanRegistered = TRUE; michael@0: atexit(&ucln_atexit_handler); michael@0: } michael@0: } michael@0: michael@0: static void ucln_unRegisterAutomaticCleanup () { michael@0: } michael@0: /* ------------end of automatic cleanup: registration. ------- */ michael@0: michael@0: #elif defined (UCLN_FINI) michael@0: /** michael@0: * If UCLN_FINI is defined, it is the (versioned, etc) name of a cleanup michael@0: * entrypoint. Add a stub to call ucln_cleanupOne michael@0: * Used on AIX, Solaris, and HP-UX michael@0: */ michael@0: U_CAPI void U_EXPORT2 UCLN_FINI (void); michael@0: michael@0: U_CAPI void U_EXPORT2 UCLN_FINI () michael@0: { michael@0: /* This function must be defined, if UCLN_FINI is defined, else link error. */ michael@0: UCLN_CLEAN_ME_UP; michael@0: } michael@0: michael@0: /* Windows: DllMain */ michael@0: #elif U_PLATFORM_HAS_WIN32_API michael@0: /* michael@0: * ICU's own DllMain. michael@0: */ michael@0: michael@0: /* these are from putil.c */ michael@0: /* READ READ READ READ! Are you getting compilation errors from windows.h? michael@0: Any source file which includes this (ucln_imp.h) header MUST michael@0: be defined with language extensions ON. */ michael@0: # define WIN32_LEAN_AND_MEAN michael@0: # define VC_EXTRALEAN michael@0: # define NOUSER michael@0: # define NOSERVICE michael@0: # define NOIME michael@0: # define NOMCX michael@0: # include michael@0: /* michael@0: * This is a stub DllMain function with icu specific process handling code. michael@0: */ michael@0: BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) michael@0: { michael@0: BOOL status = TRUE; michael@0: michael@0: switch(fdwReason) { michael@0: case DLL_PROCESS_ATTACH: michael@0: /* ICU does not trap process attach, but must pass these through properly. */ michael@0: /* ICU specific process attach could go here */ michael@0: break; michael@0: michael@0: case DLL_PROCESS_DETACH: michael@0: /* Here is the one we actually care about. */ michael@0: michael@0: UCLN_CLEAN_ME_UP; michael@0: michael@0: break; michael@0: michael@0: case DLL_THREAD_ATTACH: michael@0: /* ICU does not trap thread attach, but must pass these through properly. */ michael@0: /* ICU specific thread attach could go here */ michael@0: break; michael@0: michael@0: case DLL_THREAD_DETACH: michael@0: /* ICU does not trap thread detach, but must pass these through properly. */ michael@0: /* ICU specific thread detach could go here */ michael@0: break; michael@0: michael@0: } michael@0: return status; michael@0: } michael@0: michael@0: #elif defined(__GNUC__) michael@0: /* GCC - use __attribute((destructor)) */ michael@0: static void ucln_destructor() __attribute__((destructor)) ; michael@0: michael@0: static void ucln_destructor() michael@0: { michael@0: UCLN_CLEAN_ME_UP; michael@0: } michael@0: michael@0: #endif michael@0: michael@0: #endif /* UCLN_NO_AUTO_CLEANUP */ michael@0: michael@0: #else michael@0: #error This file can only be included once. michael@0: #endif