DCL 3.7.4
Loading...
Searching...
No Matches
LibMain.cpp
Go to the documentation of this file.
1#include <dcl/Config.h>
2
3#include <stdlib.h> // malloc, free
4#if __DCL_PTHREAD
5#include <pthread.h> // pthread_mutex_lock, pthread_mutex_unlock
6#elif defined(__WINNT__)
7#include <windows.h> // InterlockedIncrement, InterlockedDecrement
8#endif
9
10#include <dcl/Object.h>
11#include <dcl/Exception.h>
12#include <dcl/Thread.h>
13#include <dcl/StringWriter.h>
14#include "LibState.h"
15
16#if __DCL_HAVE_ALLOC_DEBUG
17#undef __DCL_ALLOC_LEVEL
18#define __DCL_ALLOC_LEVEL __DCL_ALLOC_INTERNAL
19#endif
20
21#if __DCL_HAVE_THIS_FILE__
22#undef __THIS_FILE__
23static const char_t __THIS_FILE__[] = __T("dcl/LibMain.cpp");
24#endif
25
26//#undef new
27#undef malloc
28#undef realloc
29#undef calloc
30#undef free
31
32__DCL_BEGIN_NAMESPACE
33
34#if __DCL_PTHREAD
35static pthread_mutex_t __mutex = PTHREAD_MUTEX_INITIALIZER;
36
37inline long __incrementAndGet(volatile long& _n)
38{
39 pthread_mutex_lock(&__mutex);
40 long n = ++_n;
41 pthread_mutex_unlock(&__mutex);
42 return n;
43}
44
45inline long __decrementAndGet(volatile long& _n)
46{
47 pthread_mutex_lock(&__mutex);
48 long n = --_n;
49 pthread_mutex_unlock(&__mutex);
50 return n;
51}
52#elif defined(__WINNT__)
53inline long __incrementAndGet(volatile long& _n)
54{
55 return InterlockedIncrement(&_n);
56}
57
58inline long __decrementAndGet(volatile long& _n)
59{
60 return InterlockedDecrement(&_n);
61}
62#endif
63
65static long __initializeCount__ = 0;
66
67// Thread.cpp
69extern void __cleanupThreadEnvironment();
70
71static int __DCLInitialize()
72{
73 long initCount =__incrementAndGet(__initializeCount__);
74#ifdef __DCL_DEBUG
75 if (__LibState__) {
76 __DCL_TRACE1(__T("__DCLInitialize initCount [%d]\n"), initCount);
77 }
78#endif
79
80 if (initCount == 1) {
82
83#if __DCL_HAVE_ALLOC_DEBUG
84#undef new
85#endif
86 /*
87 __LibState__ = new LibState();
88 Object.h에서 정의한 new가 호출되기 때문에 이것을 사용할 수 없다.
89 */
90 __LibState__ = (LibState*) malloc(sizeof(LibState));
91 new((void*)__LibState__) LibState;
92
93#if __DCL_HAVE_ALLOC_DEBUG
94#define new __DCL_DEBUG_NEW
95#endif
96 }
97
98 return initCount;
99}
100
101static void __DCLCleanup()
102{
103 if (__decrementAndGet(__initializeCount__) == 0) {
104 if (__LibState__->pfnSQLCleanup) {
105 __LibState__->pfnSQLCleanup();
106 __LibState__->pfnSQLCleanup = NULL;
107 }
108#ifndef __DCL_HAVE_ALLOC_DEBUG
109 // 2024-11-16
110 // regex에서
111 // 메모리 디버깅을 위한 DCL의 new, new[]이 호출 된다.
112 // 이들은 main을 빠져 나간 후, 프로세스 종료 직전에 컴파일러에에 의해
113 // delete가 호출된다.
114 // ALLOC_DEBUG 상태의 delete, delete[]가 사용될 수 있도록 남겨놓는다.
115 __LibState__->~LibState();
116 free(__LibState__);
118#endif
120 }
121}
122
123__DCL_END_NAMESPACE
124
125__DCL_USING_NAMESPACE
126
127#ifdef __DCL_DEBUG
129
130static Writer* __pGlobalDebugOut = NULL;
131
132DCLCAPI __DCL_NAMESPACE Writer* DCLDebugSetGlobalReport(
133 __DCL_NAMESPACE Writer* _newOutput
134)
135{
136 __LibState__->lockGlobalOutput.lock();
137 Writer* oldOutput = __pGlobalDebugOut;
138 __pGlobalDebugOut = _newOutput;
139 __LibState__->lockGlobalOutput.unlock();
140
141 return oldOutput;
142}
143
144DCLCAPI __DCL_NAMESPACE Writer* DCLDebugSetThreadReport(
145 thread_t _threadId,
146 __DCL_NAMESPACE Writer* _newOutput
147)
148{
149 Writer* oldOutput = NULL;
150
151 __LibState__->lockThreadOutput.lock();
152 PtrHashMap::Node* node = __LibState__->mapThreadOutput.find((const void*)(size_t) _threadId);
153 if (node) {
154 oldOutput = (Writer*)(node->value);
155 node->value = _newOutput;
156 }
157 else {
158 __LibState__->mapThreadOutput[(const void*)(size_t) _threadId] = _newOutput;
159 }
160 __LibState__->lockThreadOutput.unlock();
161
162 return oldOutput;
163}
164
166
167DCLCAPI void DCLDebugAssert(
168 const char_t* _filename,
169 unsigned int _line,
170 const char_t* _expr,
171 const char_t* _message
173{
174 throw new AssertError(_filename, _line, _expr, _message);
175}
176
178
179DCLCAPI void DCLDebugTrace(
180 const char_t* _filename,
181 unsigned int _line,
182 const char_t* _format,
183 ...
184)
185{
186 Writer* output = NULL;
187 __LibState__->lockThreadOutput.lock();
188 PtrHashMap::Node* node =
189 __LibState__->mapThreadOutput.find((const void*)(size_t) Thread::self());
190 if (node) {
191 output = (Writer*)(node->value);
192 }
193 __LibState__->lockThreadOutput.unlock();
194
195 if (!output) {
196 output = __pGlobalDebugOut;
197 }
198
199 if (output) {
200 // Writer::vprintf의 구현에 __DCL_TRACE 코드가 있으면 이 부분이 재귀적으로 호출된다.
201 StringWriter sw(256);
202 sw.printf(__T("%ls:%u "), _filename, _line);
203
204 va_list arglist;
205 va_start(arglist, _format);
206 sw.vprintf(_format, arglist);
207 va_end(arglist);
208
209 // __LibState__->lockGlobalOutput
210 // WIndows CriticalSection, pthread_mutex로 구현되어 있다.
211 // CriticalSection의 경우 단일 프로세스, 단일 스레드에서 Block되지 않는다.
212 // pthread_mutex는 단일 프로세스, 단일 스레데에서 Block된다.
213 if (output == __pGlobalDebugOut) {
214 __LibState__->lockGlobalOutput.lock();
215 }
216 try {
217 *output << sw.toString();
218 output->flush();
219 }
220 catch(IOException* e) {
221 *output << e->toStringAll() << endl;
222 e->destroy();
223 }
224 if (output == __pGlobalDebugOut) {
225 __LibState__->lockGlobalOutput.unlock();
226 }
227 }
228}
229
230#endif // __DCL_DEBUG
231
232#if __DCL_HAVE_MANUAL_INITIALIZE
233DCLCAPI int DCLInitialize()
234{
235 return __DCLInitialize();
236}
237
238DCLCAPI void DCLCleanup()
239{
240 __DCLCleanup();
241}
242#elif defined(__DCL_CORE_EXPORTS)
243// DSO Initialize
244#ifdef __WINNT__
245BOOL WINAPI DllMain(
246 HINSTANCE hinstDLL, // handle to DLL module
247 DWORD fdwReason, // reason for calling function
248 LPVOID lpReserved // reserved
249)
250{
251 switch (fdwReason) {
252 case DLL_PROCESS_ATTACH:
253 __DCLInitialize();
254 break;
255 case DLL_PROCESS_DETACH:
256 __DCLCleanup();
257 break;
258 case DLL_THREAD_ATTACH:
259 __DCL_TRACE0(__T("DCLCoreD.dll DLL_THREAD_ATTACH\n"));
260 break;
261 case DLL_THREAD_DETACH:
262 __DCL_TRACE0(__T("DCLCoreD.dll DLL_THREAD_DETACH\n"));
263 break;
264 }
265 return TRUE;
266}
267#else
268__attribute__((constructor))
269void _DCL_init()
270{
271 __DCLInitialize();
272}
273
274__attribute__((destructor))
275void _DCL_fini()
276{
277 __DCLCleanup();
278}
279#endif
280
281#else
282
283// Static Library
284#ifdef _MSC_VER
285#pragma optimize ("", off)
286#endif
287
289{
290public:
292 {
293 __DCLInitialize();
294 }
296 {
297 __DCLCleanup();
298 }
299};
300
301static __LibInitializer __libInitializer;
302
303#ifdef _MSC_VER
304#pragma optimize ("", off)
305#endif
306
307#endif
#define __THIS_FILE__
Definition _trace.h:14
#define NULL
Definition Config.h:312
#define DCLCAPI
Definition Config.h:95
wchar_t char_t
Definition Config.h:247
#define __DCL_THROWS1(e)
Definition Config.h:152
int BOOL
#define TRUE
void __cleanupThreadEnvironment()
Definition Thread.cpp:347
__DCL_BEGIN_NAMESPACE LibState * __LibState__
Definition LibMain.cpp:64
void __initializeThreadEnvironment()
Definition Thread.cpp:339
#define __DCL_TRACE0(psz)
Definition Object.h:398
#define __DCL_TRACE1(fmt, arg1)
Definition Object.h:399
#define __T(str)
Definition Object.h:60
pthread_t thread_t
Definition Object.h:27
DCLCVAR const struct __endl endl
virtual void destroy()
Definition Exception.cpp:74
String toStringAll() const
Definition Exception.cpp:45
virtual String toString() const
Definition Object.cpp:187
static thread_t self()
Definition Thread.cpp:175
const void * value
Definition LibState.h:148