1/*
2******************************************************************************
3* Copyright (C) 2001-2010, International Business Machines
4*                Corporation and others. All Rights Reserved.
5******************************************************************************
6*   file name:  ucln_cmn.c
7*   encoding:   US-ASCII
8*   tab size:   8 (not used)
9*   indentation:4
10*
11*   created on: 2001July05
12*   created by: George Rhoten
13*/
14
15#include "unicode/utypes.h"
16#include "unicode/uclean.h"
17#include "utracimp.h"
18#include "ustr_imp.h"
19#include "ucln_cmn.h"
20#include "umutex.h"
21#include "ucln.h"
22#include "cmemory.h"
23#include "uassert.h"
24
25/**  Auto-client for UCLN_COMMON **/
26#define UCLN_TYPE UCLN_COMMON
27#include "ucln_imp.h"
28
29static cleanupFunc *gCommonCleanupFunctions[UCLN_COMMON_COUNT];
30static cleanupFunc *gLibCleanupFunctions[UCLN_COMMON];
31
32
33/* Enables debugging information about when a library is cleaned up. */
34#ifndef UCLN_DEBUG_CLEANUP
35#define UCLN_DEBUG_CLEANUP 0
36#endif
37
38
39#if defined(UCLN_DEBUG_CLEANUP)
40#include <stdio.h>
41#endif
42
43static void ucln_cleanup_internal(ECleanupLibraryType libType)
44{
45    if (gLibCleanupFunctions[libType])
46    {
47        gLibCleanupFunctions[libType]();
48        gLibCleanupFunctions[libType] = NULL;
49    }
50}
51
52U_CAPI void U_EXPORT2 ucln_cleanupOne(ECleanupLibraryType libType)
53{
54    if(libType==UCLN_COMMON) {
55#if UCLN_DEBUG_CLEANUP
56        fprintf(stderr, "Cleaning up: UCLN_COMMON with u_cleanup, type %d\n", (int)libType);
57#endif
58        u_cleanup();
59    } else {
60#if UCLN_DEBUG_CLEANUP
61        fprintf(stderr, "Cleaning up: using ucln_cleanup_internal, type %d\n", (int)libType);
62#endif
63        ucln_cleanup_internal(libType);
64    }
65}
66
67
68U_CFUNC void
69ucln_common_registerCleanup(ECleanupCommonType type,
70                            cleanupFunc *func)
71{
72    U_ASSERT(UCLN_COMMON_START < type && type < UCLN_COMMON_COUNT);
73    if (UCLN_COMMON_START < type && type < UCLN_COMMON_COUNT)
74    {
75        gCommonCleanupFunctions[type] = func;
76    }
77#if !UCLN_NO_AUTO_CLEANUP && (defined(UCLN_AUTO_ATEXIT) || defined(UCLN_AUTO_LOCAL))
78    ucln_registerAutomaticCleanup();
79#endif
80}
81
82U_CAPI void U_EXPORT2
83ucln_registerCleanup(ECleanupLibraryType type,
84                     cleanupFunc *func)
85{
86    U_ASSERT(UCLN_START < type && type < UCLN_COMMON);
87    if (UCLN_START < type && type < UCLN_COMMON)
88    {
89        gLibCleanupFunctions[type] = func;
90    }
91}
92
93U_CFUNC UBool ucln_lib_cleanup(void) {
94    ECleanupLibraryType libType = UCLN_START;
95    ECleanupCommonType commonFunc = UCLN_COMMON_START;
96
97    for (libType++; libType<UCLN_COMMON; libType++) {
98        ucln_cleanup_internal(libType);
99    }
100
101    for (commonFunc++; commonFunc<UCLN_COMMON_COUNT; commonFunc++) {
102        if (gCommonCleanupFunctions[commonFunc])
103        {
104            gCommonCleanupFunctions[commonFunc]();
105            gCommonCleanupFunctions[commonFunc] = NULL;
106        }
107    }
108#if !UCLN_NO_AUTO_CLEANUP && (defined(UCLN_AUTO_ATEXIT) || defined(UCLN_AUTO_LOCAL))
109    ucln_unRegisterAutomaticCleanup();
110#endif
111    return TRUE;
112}
113