DCL 4.0
Loading...
Searching...
No Matches
LibState.cpp
Go to the documentation of this file.
1#include <dcl/Config.h>
2
3#include <stdlib.h>
4#include <string.h>
5#include <wchar.h> // wcslen, wcscpy, wcsncpy
6
7#if __DCL_PTHREAD
8 #include <pthread.h> // pthread_mutex_lock, pthread_mutex_unlock
9#elif __DCL_WINDOWS
10 #include <windows.h> // InterlockedIncrement, InterlockedDecrement
11#endif
12
13#include <dcl/Thread.h>
14#include "LibState.h"
15
16#undef new
17#undef malloc
18#undef realloc
19#undef calloc
20#undef free
21
22#define __strlen(s) wcslen(s)
23#define __strcpy(d, s) wcscpy(d, s)
24#define __strncpy(d, s, n) wcsncpy(d, s, n)
25
26#define __TRACE_THIS 0
27#define __DCL_ASSERT_N(expr)
28
29#undef __THIS_FILE__
30static const char_t __THIS_FILE__[] = __T("dcl/LibState.cpp");
31
32__DCL_BEGIN_NAMESPACE
33
34InternalMutex::InternalMutex(const char* pszName)
35{
36#if __DCL_PTHREAD
37 pthread_mutex_init(&m_mutex, NULL);
38#elif __DCL_WINDOWS
39 InitializeCriticalSection(&m_cs);
40#endif
41 m_pszName = pszName;
42}
43
45{
46#if __DCL_PTHREAD
47 pthread_mutex_destroy(&m_mutex);
48#elif __DCL_WINDOWS
49 DeleteCriticalSection(&m_cs);
50#endif
51}
52
54{
55#if __DCL_PTHREAD
56 pthread_mutex_lock(&m_mutex);
57#elif __DCL_WINDOWS
58 EnterCriticalSection(&m_cs);
59#endif
60}
61
63{
64#if __DCL_PTHREAD
65 pthread_mutex_unlock(&m_mutex);
66#elif __DCL_WINDOWS
67 LeaveCriticalSection(&m_cs);
68#endif
69}
70
71#if __DCL_HAVE_ALLOC_DEBUG
72size_t AllocList::Node::size()
73{
74 size_t r = sizeof(Node) % 8;
75 if (r)
76 return sizeof(Node) + 8 - r;
77 return sizeof(Node);
78}
79
80void* AllocList::Node::data() const
81{
82 return (char*)this + Node::size();
83}
84
85void AllocList::Node::assignFileName(const char_t* _filename)
86{
87 __DCL_ASSERT_N(_filename != NULL);
88
89 size_t nLen = __strlen(_filename);
90 if (nLen > __DCL_DEBUG_PATH_MAX) {
91 __strncpy(szFileName, _filename, 8);
92 __strncpy(szFileName + 8, __T("..."), 3);
93 _filename += nLen - __DCL_DEBUG_PATH_MAX + 8;
94 __strcpy(szFileName + 11, _filename);
95 }
96 else
97 __strcpy(szFileName, _filename);
98}
99
100AllocList::Node* AllocList::allocNode(
101 size_t nSize,
102 bool bCheck,
103 DCLAllocFunction allocFunction,
104 const char_t* _filename,
105 unsigned int _line
106 )
107{
108 __DCL_ASSERT_N(nSize > 0);
109
110 Node* pNewNode = (Node*)malloc(Node::size() + nSize);
111 if (pNewNode) {
112 pNewNode->uThreadId = Thread::getCurrentThreadId();
113 pNewNode->bCheck = bCheck;
114 pNewNode->allocFunction = allocFunction;
115
116 if (_filename)
117 pNewNode->assignFileName(_filename);
118 else
119 pNewNode->szFileName[0] = '\0';
120
121 pNewNode->nLine = _line;
122 pNewNode->nSize = nSize;
123 }
124 return pNewNode;
125}
126
127void* AllocList::addTail(Node* pNewNode)
128{
129 __DCL_ASSERT_N(pNewNode != NULL);
130
131 NodeBase* pMasterNode = &m_masterNode;
132
133 pNewNode->pNext = pMasterNode;
134 pNewNode->pPrev = pMasterNode->pPrev;
135
136 pNewNode->pPrev->pNext = pNewNode;
137 pMasterNode->pPrev = pNewNode;
138 m_nCount++;
139
140 return pNewNode->data();
141}
142
143AllocList::Node* AllocList::reallocNode(
144 Node* pNode,
145 size_t nSize,
146 const char_t* _filename,
147 unsigned int _line
148 )
149{
150 __DCL_ASSERT_N(pNode != NULL);
151 __DCL_ASSERT_N(nSize > 0);
152
153 // realloc은 realloc전과 후의 주소가 서로 다를 수 있다.
154 // 이전의 노드 정보를 저장한다.
155 NodeBase* pPrevSave = pNode->pPrev;
156 NodeBase* pNextSave = pNode->pNext;
157
158 bool bCheckSave = pNode->bCheck;
159 DCLAllocFunction allocTypeSave = pNode->allocFunction;
160
161 Node* pNewNode = (Node*)realloc(pNode, Node::size() + nSize);
162 if (pNewNode) {
163 if (pNewNode != pNode) {
164 pPrevSave->pNext = pNewNode;
165 pNextSave->pPrev = pNewNode;
166
167 // pNewNode->pPrev = pPrevSave;
168 // pNewNode->pNext = pNextSave;
169
170 pNewNode->uThreadId = Thread::getCurrentThreadId();
171 pNewNode->bCheck = bCheckSave;
172 pNewNode->allocFunction = allocTypeSave;
173 }
174
175 if (_filename)
176 pNewNode->assignFileName(_filename);
177 else
178 pNewNode->szFileName[0] = L'\0';
179
180 pNewNode->nLine = _line;
181 pNewNode->nSize = nSize;
182 }
183 return pNewNode;
184}
185
186AllocList::AllocList()
187{
188 NodeBase* pMasterNode = &m_masterNode;
189 pMasterNode->pPrev = pMasterNode;
190 pMasterNode->pNext = pMasterNode;
191
192 m_nCount = 0;
193}
194
195AllocList::~AllocList()
196{
197// if (m_nCount)
198// clear();
199}
200
201AllocList::Node* AllocList::begin() const
202{
203 const NodeBase* pMasterNode = &m_masterNode;
204
205 if (pMasterNode->pNext == pMasterNode)
206 return NULL;
207
208 return (Node*)pMasterNode->pNext;
209}
210
211AllocList::Node* AllocList::end() const
212{
213 const NodeBase* pMasterNode = &m_masterNode;
214
215 if (pMasterNode->pPrev == pMasterNode)
216 return NULL;
217
218 return (Node*)pMasterNode->pPrev;
219}
220
221AllocList::Node* AllocList::next(Node*& pNode) const
222{
223 __DCL_ASSERT_N(pNode != NULL);
224
225 const NodeBase* pMasterNode = &m_masterNode;
226
227 if (pNode->pNext == pMasterNode)
228 pNode = NULL;
229 else
230 pNode = (Node*)pNode->pNext;
231
232 return pNode;
233}
234
235AllocList::Node* AllocList::prev(Node*& pNode) const
236{
237 __DCL_ASSERT_N(pNode != NULL);
238
239 const NodeBase* pMasterNode = &m_masterNode;
240
241 if (pNode->pPrev == pMasterNode)
242 pNode = NULL;
243 else
244 pNode = (Node*)pNode->pPrev;
245
246 return pNode;
247}
248
249AllocList::Node* AllocList::find(const void* p) const
250{
251 const NodeBase* pMasterNode = &m_masterNode;
252 const NodeBase* pNode = pMasterNode->pNext;
253
254 while(pNode != pMasterNode) {
255 if (((Node*)pNode)->data() == p)
256 return (Node*)pNode;
257
258 pNode = pNode->pNext;
259 }
260 return NULL;
261}
262
263AllocList::Node* AllocList::rfind(const void* p) const
264{
265 const NodeBase* pMasterNode = &m_masterNode;
266 const NodeBase* pNode = pMasterNode->pPrev;
267
268 while(pNode != pMasterNode) {
269 if (((Node*)pNode)->data() == p)
270 return (Node*)pNode;
271
272 pNode = pNode->pPrev;
273 }
274 return NULL;
275}
276
277void* AllocList::allocAddTail(
278 size_t nSize,
279 bool bCheck,
280 DCLAllocFunction allocFunction,
281 const char_t* _filename,
282 unsigned int _line
283 )
284{
285 Node* pNewNode = allocNode(
286 nSize,
287 bCheck,
288 allocFunction,
289 _filename,
290 _line
291 );
292 if (pNewNode)
293 return addTail(pNewNode);
294
295 return NULL;
296}
297
298void AllocList::erase(Node* pNode)
299{
300 __DCL_ASSERT_N(pNode != NULL);
301 pNode->pPrev->pNext = pNode->pNext;
302 pNode->pNext->pPrev = pNode->pPrev;
303
304 free(pNode);
305 m_nCount--;
306}
307
308void AllocList::clear()
309{
310 NodeBase* pMasterNode = &m_masterNode;
311 NodeBase* pTempNode = NULL;
312 NodeBase* pNode = pMasterNode->pNext;
313 while(pNode != pMasterNode) {
314 pTempNode = pNode;
315 pNode = pNode->pNext;
316 free(pTempNode);
317 }
318
319 pMasterNode->pNext = pMasterNode;
320 pMasterNode->pPrev = pMasterNode;
321 m_nCount = 0;
322}
323
324#endif // __DCL_HAVE_ALLOC_DEBUG
325
326extern DCLCAPI size_t DCLGetNextPrimNumber(size_t _n);
327
329{
330 nBuckets = DCLGetNextPrimNumber(nBuckets);
331
332 size_t nBytes = sizeof(NodeBase) * nBuckets;
333 m_buckets = (NodeBase*)malloc(nBytes);
334 for(size_t i = 0; i < nBuckets; i++) {
335 NodeBase* pNode = &(m_buckets[i]);
336 pNode->pPrev = pNode->pNext = pNode;
337 }
338 m_nBuckets = nBuckets;
339 m_nCount = 0;
340}
341
343{
344 for(size_t i = 0; i < m_nBuckets; i++) {
345 NodeBase* pTempNode = NULL;
346 NodeBase* pMasterNode = &(m_buckets[i]);
347 NodeBase* pNode = pMasterNode->pNext;
348 while(pNode != pMasterNode) {
349 pTempNode = pNode;
350 pNode = pNode->pNext;
351 free(pTempNode);
352 }
353 }
354 free(m_buckets);
355}
356
357const void*& PtrHashMap::operator [] (const void* key)
358{
359 size_t nBucket = bucketNumber(key);
360 NodeBase* pMasterNode = &(m_buckets[nBucket]);
361 NodeBase* pNode = pMasterNode->pNext;
362 while(pNode != pMasterNode) {
363 if (((Node*)pNode)->key == key)
364 return ((Node*)pNode)->value;
365 pNode = pNode->pNext;
366 }
367
368 Node* pNewNode = (Node*)malloc(sizeof(Node));
369 pNewNode->pPrev = pMasterNode;
370 pNewNode->pNext = pMasterNode->pNext;
371 pNewNode->pNext->pPrev = pNewNode;
372 pMasterNode->pNext = pNewNode;
373 m_nCount++;
374 pNewNode->key = key;
375 return pNewNode->value;
376}
377
378PtrHashMap::Node* PtrHashMap::find(const void* key) const
379{
380 size_t nBucket = bucketNumber(key);
381 NodeBase* pMasterNode = &(m_buckets[nBucket]);
382 NodeBase* pNode = pMasterNode->pNext;
383// int i = 1;
384 while(pNode != pMasterNode) {
385 if (((Node*)pNode)->key == key)
386 return (Node*)pNode;
387 pNode = pNode->pNext;
388// printf("collision: %d\n", i++);
389
390 }
391 return NULL;
392}
393
395{
396 __DCL_ASSERT_N(pNode != NULL);
397
398 pNode->pPrev->pNext = pNode->pNext;
399 pNode->pNext->pPrev = pNode->pPrev;
400
401 free(pNode);
402 m_nCount--;
403}
404
406 : lockSQLDriverPool("LibState::lockSQLDriverPool")
407#if __DCL_DEBUG
408 , lockGlobalOutput("LibState::lockGlobalOutput")
409 , mapThreadOutput(MAP_THREAD_OUTPUT_BUCKET_COUNT)
410 , lockThreadOutput("LibState::lockThreadOutput")
411#if __DCL_HAVE_ALLOC_DEBUG
412 , lockAlloc("LibState::lockAlloc")
413#endif // __DCL_HAVE_ALLOC_DEBUG
414#endif // __DCL_DEBUG
415{
417}
421
422__DCL_END_NAMESPACE
#define __THIS_FILE__
Definition _trace.h:14
#define NULL
Definition Config.h:340
#define DCLCAPI
Definition Config.h:100
wchar_t char_t
Definition Config.h:275
DCLCAPI size_t DCLGetNextPrimNumber(size_t _n)
Definition HashFun.cpp:23
#define __strcpy(d, s)
Definition LibState.cpp:23
DCLCAPI size_t DCLGetNextPrimNumber(size_t _n)
Definition HashFun.cpp:23
#define __strlen(s)
Definition LibState.cpp:22
#define __DCL_ASSERT_N(expr)
Definition LibState.cpp:27
#define __strncpy(d, s, n)
Definition LibState.cpp:24
#define __T(str)
Definition Object.h:44
ByteString r
if(!__handle->open(bs, bs.length()))
InternalMutex(const char *pszName)
Definition LibState.cpp:34
void unlock()
Definition LibState.cpp:62
int m_nCount
Definition LibState.h:172
void erase(Node *pNode)
Definition LibState.cpp:394
size_t m_nBuckets
Definition LibState.h:171
size_t bucketNumber(const void *key) const
Definition LibState.h:175
PtrHashMap(size_t nBuckets)
Definition LibState.cpp:328
NodeBase * m_buckets
Definition LibState.h:170
Node * find(const void *key) const
Definition LibState.cpp:378
const void *& operator[](const void *key)
Definition LibState.cpp:357
static unsigned long getCurrentThreadId()
Definition Thread.cpp:173
DCLCleanupCallback pfnSQLCleanup
Definition LibState.h:188
InternalMutex lockSQLDriverPool
Definition LibState.h:187
NodeBase * pPrev
Definition ListBase.h:18
NodeBase * pNext
Definition ListBase.h:19
struct NodeBase * pPrev
Definition LibState.h:142
struct NodeBase * pNext
Definition LibState.h:143
const void * key
Definition LibState.h:148
const void * value
Definition LibState.h:149