blob: efdeaba8d57174aa16f13a39d1cc28a1ab6ce0bd (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
/*
******************************************************************************
* *
* Copyright (C) 2001-2005, International Business Machines *
* Corporation and others. All Rights Reserved. *
* *
******************************************************************************
* file name: uinit.c
* encoding: US-ASCII
* tab size: 8 (not used)
* indentation:4
*
* created on: 2001July05
* created by: George Rhoten
*/
#include "unicode/utypes.h"
#include "unicode/uclean.h"
#include "utracimp.h"
#include "ustr_imp.h"
#include "unormimp.h"
#include "ucln_cmn.h"
#include "ucnv_io.h"
#include "umutex.h"
#include "ucln.h"
#include "cmemory.h"
#include "uassert.h"
static UBool gICUInitialized = FALSE;
static UMTX gICUInitMutex = NULL;
static cleanupFunc *gLibCleanupFunctions[UCLN_COMMON];
U_CAPI void U_EXPORT2
ucln_registerCleanup(ECleanupLibraryType type,
cleanupFunc *func)
{
U_ASSERT(UCLN_START < type && type < UCLN_COMMON);
if (UCLN_START < type && type < UCLN_COMMON)
{
gLibCleanupFunctions[type] = func;
}
}
/************************************************
The cleanup order is important in this function.
Please be sure that you have read ucln.h
************************************************/
U_CAPI void U_EXPORT2
u_cleanup(void)
{
ECleanupLibraryType libType;
UTRACE_ENTRY_OC(UTRACE_U_CLEANUP);
umtx_lock(NULL); /* Force a memory barrier, so that we are sure to see */
umtx_unlock(NULL); /* all state left around by any other threads. */
for (libType = UCLN_START+1; libType<UCLN_COMMON; libType++) {
if (gLibCleanupFunctions[libType])
{
gLibCleanupFunctions[libType]();
gLibCleanupFunctions[libType] = NULL;
}
}
ucln_common_lib_cleanup();
umtx_destroy(&gICUInitMutex);
umtx_cleanup();
cmemory_cleanup(); /* undo any heap functions set by u_setMemoryFunctions(). */
gICUInitialized = FALSE;
UTRACE_EXIT(); /* Must be before utrace_cleanup(), which turns off tracing. */
#if U_ENABLE_TRACING
utrace_cleanup();
#endif
}
/*
*
* ICU Initialization Function. Force loading and/or initialization of
* any shared data that could potentially be used concurrently
* by multiple threads.
*/
U_CAPI void U_EXPORT2
u_init(UErrorCode *status) {
UTRACE_ENTRY_OC(UTRACE_U_INIT);
/* Make sure the global mutexes are initialized. */
umtx_init(NULL);
umtx_lock(&gICUInitMutex);
if (gICUInitialized || U_FAILURE(*status)) {
umtx_unlock(&gICUInitMutex);
UTRACE_EXIT_STATUS(*status);
return;
}
#if 1
/*
* 2005-may-02
*
* ICU4C 3.4 (jitterbug 4497) hardcodes the data for Unicode character
* properties for APIs that want to be fast.
* Therefore, we need not load them here nor check for errors.
* Instead, we load the converter alias table to see if any ICU data
* is available.
* Users should really open the service objects they need and check
* for errors there, to make sure that the actual items they need are
* available.
*/
#if !UCONFIG_NO_CONVERSION
ucnv_io_countStandards(status);
#endif
#else
/* Do any required init for services that don't have open operations
* and use "only" the double-check initialization method for performance
* reasons (avoiding a mutex lock even for _checking_ whether the
* initialization had occurred).
*/
/* Char Properties */
uprv_loadPropsData(status);
/* load the case and bidi properties but don't fail if they are not available */
u_isULowercase(0x61);
u_getIntPropertyValue(0x200D, UCHAR_JOINING_TYPE); /* ZERO WIDTH JOINER: Join_Causing */
#if !UCONFIG_NO_NORMALIZATION
/* Normalization */
unorm_haveData(status);
#endif
#endif
gICUInitialized = TRUE; /* TODO: don't set if U_FAILURE? */
umtx_unlock(&gICUInitMutex);
UTRACE_EXIT_STATUS(*status);
}
|