forked from somma/_MyLib
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathThreadManager.cpp
More file actions
126 lines (109 loc) · 3.94 KB
/
ThreadManager.cpp
File metadata and controls
126 lines (109 loc) · 3.94 KB
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
/*-----------------------------------------------------------------------------
* ThreadManager.cpp
*-----------------------------------------------------------------------------
*
*-----------------------------------------------------------------------------
* All rights reserved by somma (fixbrain@gmail.com, unsorted@msn.com)
*-----------------------------------------------------------------------------
* - 02.09.2010 created
**---------------------------------------------------------------------------*/
#include "stdafx.h"
#include "ThreadManager.h"
#include "Win32Utils.h"
/**----------------------------------------------------------------------------
\brief
\param
\return
\code
\endcode
-----------------------------------------------------------------------------*/
PDTTHREAD_CONTEXT
CreateThreadContext(
IN LPTHREAD_START_ROUTINE ThreadProcedure,
IN LPVOID Threadparam
)
{
_ASSERTE(NULL != ThreadProcedure);
if (NULL == ThreadProcedure) return NULL;
PDTTHREAD_CONTEXT ctx = (PDTTHREAD_CONTEXT) malloc(sizeof(DTTHREAD_CONTEXT));
if (NULL == ctx) return NULL;
RtlZeroMemory(ctx, sizeof(DTTHREAD_CONTEXT));
ctx->KillEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (NULL == ctx->KillEvent) {free(ctx); return NULL;}
ctx->ThreadParam = Threadparam;
ctx->ThreadProcedure = ThreadProcedure;
ctx->ThreadHandle = CreateThread(
NULL,
0,
ThreadProcedure,
Threadparam,
0,
&ctx->ThreadId
);
_ASSERTE(NULL != ctx->ThreadHandle);
if (NULL == ctx->ThreadHandle)
{
log_err "can not create CreateThread, gle = %u", GetLastError() log_end
free(ctx);
return NULL;
}
return ctx;
}
/**----------------------------------------------------------------------------
\brief
\param
\return
\code
\endcode
-----------------------------------------------------------------------------*/
void DestroyThreadContext(IN PDTTHREAD_CONTEXT& ctx)
{
if(NULL == ctx) return;
_ASSERTE(NULL != ctx->KillEvent);
_ASSERTE(NULL != ctx->ThreadHandle);
if (NULL == ctx || NULL == ctx->KillEvent || NULL == ctx->ThreadHandle) return;
// DAED-LOCK 체크
// - thread procedure 내에서 DestroyThreadContext() 를 호출한 경우
//
if (GetCurrentThreadId() == ctx->ThreadId)
{
log_err "!!CRITICAL!! DEAD LOCK DETECTED, invalid function call, caller tid=0x%08x, ctx tid=0x%08x", GetCurrentThreadId(), ctx->ThreadId log_end
return;
}
// thread 종료 이벤트 시그널
//
SetEvent(ctx->KillEvent);
// thread 가 종료된 경우 ctx 리소스를 해제
//
DWORD ExitCode=STILL_ACTIVE;
if (TRUE != GetExitCodeThread(ctx->ThreadHandle, &ExitCode))
{
log_err "GetExitCodeThread(tid=0x%08x, handle=0x%08x) failed, gle = %u", ctx->ThreadId, ctx->ThreadHandle, GetLastError() log_end
// progream 이 크래시 되도 별 수 없다.
//
CloseHandle(ctx->KillEvent);
free(ctx);
return;
}
if (STILL_ACTIVE != ExitCode)
{
// 이미 스레드가 종료된 경우라면 그냥 핸들만 닫아버려도 된다.
//
CloseHandle(ctx->KillEvent);
free(ctx);
return;
}
else
{
if (WAIT_OBJECT_0 != WaitForSingleObject(
ctx->ThreadHandle,
CONTEXT_TERMINATED_EVENT_TIMEOUT
))
{
log_err "!!CRITICAL!! thread is not responding, tid=0x%08x, handle=0x%08x", ctx->ThreadId, ctx->ThreadHandle log_end
}
CloseHandle(ctx->KillEvent);
free(ctx);
}
return;
}