Changeset 122 in libcf for trunk/src/cf_thread.c
- Timestamp:
- 06/12/13 11:05:07 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/cf_thread.c
r121 r122 26 26 #endif // #if defined(_WIN32) || defined(_WIN64) 27 27 28 #define ASSERT_THREAD (__h) \29 if (__ h == NULL)\30 return CF_ERROR_THREAD_INVALID_ ARGS31 32 #define ASSERT_MUTEX (__h) \33 if (__ h == NULL)\34 return CF_ERROR_MUTEX_INVALID_ ARGS28 #define ASSERT_THREAD_CTX(__ctx) \ 29 if (__ctx == NULL) \ 30 return CF_ERROR_THREAD_INVALID_CTX 31 32 #define ASSERT_MUTEX_CTX(__ctx) \ 33 if (__ctx == NULL) \ 34 return CF_ERROR_MUTEX_INVALID_CTX 35 35 36 36 typedef THREAD_RETURN (THREAD_CALL * THREAD_WORKER) (void *); 37 37 38 typedef struct __cf_thread_ctx__ 39 { 40 THREAD_TYPE tid; 41 THREAD_WORKER callback; 42 void * arg; 43 } CF_THREAD_CTX; 44 45 typedef struct __cf_ctx_ctx__ 46 { 47 MUTEX_TYPE mid; 48 } CF_MUTEX_CTX; 49 38 50 static int 39 CF_Thread_Local_Close (void * ctx) 40 { 41 #if defined(_WIN32) || defined(_WIN64) 42 CloseHandle (ctx); 43 #else 44 free (ctx); 45 #endif 46 47 return CF_OK; 48 } 49 50 /** 51 * 스레드를 생성 52 * 53 * \return 성공 시, CF_OK; 실패 시, 오류 코드 54 * 55 * \param threadID 스레드 아이디 주소 51 CF_Thread_Local_Close (THREAD_TYPE tid) 52 { 53 #if defined(_WIN32) || defined(_WIN64) 54 CloseHandle (tid); 55 #endif 56 57 return CF_OK; 58 } 59 60 static int 61 CF_Mutex_Local_Close (MUTEX_TYPE mid) 62 { 63 #if defined(_WIN32) || defined(_WIN64) 64 CloseHandle (mid); 65 #else 66 pthread_mutex_destroy (&mid); 67 #endif 68 69 return CF_OK; 70 } 71 72 /** 73 * 스레드 컨텍스트를 생성 74 * 75 * \return 성공 시, CF_OK; 실패 시, 오류 코드 76 * 77 * \param ctx 스레드 컨텍스트 주소 56 78 * \param callback 스레드 워커 함수 이름 57 79 * \param arg 스레드 함수로 전달할 인자 80 */ 81 int 82 CF_Thread_CreateCtx (CF_Thread_Ctx * ctx, 83 CF_Thread_Function callback, 84 void * arg) 85 { 86 CF_THREAD_CTX * context = NULL; 87 88 context = (CF_THREAD_CTX *) calloc (sizeof (CF_THREAD_CTX), 1); 89 if (context == NULL) 90 return CF_ERROR_THREAD_CREATE_CTX; 91 92 context->callback = (THREAD_WORKER) callback; 93 context->arg = arg; 94 95 *ctx = (CF_Thread_Ctx) context; 96 97 return CF_OK; 98 } 99 100 /** 101 * 스레드를 실행 102 * 103 * \return 성공 시, CF_OK; 실패 시, 오류 코드 104 * 105 * \param ctx 스레드 컨텍스트 58 106 * 59 107 * \remarks 60 * pthread (POSIX Thread)에서 지원되는 스케줄링 정책은 SCHED_OTHER, SCHED_FIFO, SCHED_RR 등이 존재 <br />108 * pthread에서 지원되는 스케줄링 정책은 SCHED_OTHER, SCHED_FIFO, SCHED_RR 등이 존재 <br /> 61 109 * 일반적으로 설정되는 스케줄링 정책의 기본값은 SCHED_OTHER이며, 솔라리스 환경에서 SCHED_OTHER는 TS(timesharing) 방식으로 명시되어 있음 <br /> 62 110 * 그러나 개발 단계에서 테스트된 동작은 SCHED_FIFO와 동일하였으며, 때문에 솔라리스 환경에서는 스케줄링 정책을 SCHED_RR로 명시하도록 함 <br /> … … 67 115 */ 68 116 int 69 CF_Thread_Create (CF_Thread_Ctx * threadID, 70 CF_Thread_Function callback, 71 void * arg) 117 CF_Thread_Start (CF_Thread_Ctx ctx) 72 118 { 73 119 int result = 0; 74 120 75 THREAD_WORKER f = (THREAD_WORKER) callback; 76 77 #if defined(_WIN32) || defined(_WIN64) 78 *threadID = (THREAD_TYPE) CreateThread (NULL, 0, f, arg, 0, NULL); 79 if (*threadID == NULL) 80 return CF_ERROR_THREAD_CREATE; 121 CF_THREAD_CTX * context = (CF_THREAD_CTX *) ctx; 122 123 ASSERT_THREAD_CTX (ctx); 124 125 #if defined(_WIN32) || defined(_WIN64) 126 context->tid = CreateThread (NULL, 0, context->callback, context->arg, 0, NULL); 127 if (context->tid == NULL) 128 return CF_ERROR_THREAD_START; 81 129 #else 82 130 … … 106 154 # endif // # if defined(_SOLARIS) 107 155 108 *threadID = (THREAD_TYPE *) calloc (sizeof (THREAD_TYPE), 1); 109 if (*threadID == NULL) 110 return CF_ERROR_THREAD_CREATE_CTX; 111 112 result = pthread_create ((THREAD_TYPE *) *threadID, attr, f, arg); 113 if (result) 156 result = pthread_create (&context->tid, attr, context->callback, context->arg); 157 if (result) 158 return CF_ERROR_THREAD_START; 159 #endif 160 return result; 161 } 162 163 /** 164 * 스레드 컨텍스트를 해제 165 * 166 * \return 성공 시, CF_OK; 실패 시, 오류 코드 167 * 168 * \param ctx 스레드 컨텍스트 169 * 170 * \remarks 스레드 컨텍스트를 해제하는 것이며 워커 스레드가 종료되지 않음 171 */ 172 int 173 CF_Thread_DestroyCtx (CF_Thread_Ctx ctx) 174 { 175 CF_THREAD_CTX * context = (CF_THREAD_CTX *) ctx; 176 177 ASSERT_THREAD_CTX (ctx); 178 179 CF_Thread_Local_Close (context->tid); 180 free (context); 181 182 return CF_OK; 183 } 184 185 /** 186 * 스레드가 종료될 때 까지 대기 187 * 188 * \return CF_OK 반환 189 * 190 * \param ctx 스레드 컨텍스트 191 */ 192 int 193 CF_Thread_Join (CF_Thread_Ctx ctx) 194 { 195 CF_THREAD_CTX * context = (CF_THREAD_CTX *) ctx; 196 197 char status[16] = {0x00,}; 198 199 ASSERT_THREAD_CTX (ctx); 200 201 #if defined(_WIN32) || defined(_WIN64) 202 WaitForSingleObject (context->tid, INFINITE); 203 #else 204 pthread_join (context->tid, (void **)status); 205 #endif 206 207 return CF_OK; 208 } 209 210 /** 211 * 뮤텍스 컨텍스트를 생성 212 * 213 * \return 성공 시, CF_OK; 실패 시, 오류 코드 214 * 215 * \param ctx 뮤텍스 컨텍스트 주소 216 */ 217 int 218 CF_Mutex_CreateCtx (CF_Mutex_Ctx * ctx) 219 { 220 int result = 0; 221 222 CF_MUTEX_CTX * context = NULL; 223 224 context = (CF_MUTEX_CTX *) calloc (sizeof (CF_MUTEX_CTX), 1); 225 if (context == NULL) 226 return CF_ERROR_MUTEX_CREATE_CTX; 227 228 TRY 114 229 { 115 CF_Thread_DestroyCtx (threadID); 116 return CF_ERROR_THREAD_CREATE; 230 #if defined(_WIN32) || defined(_WIN64) 231 context->mid = CreateMutexA (NULL, FALSE, NULL); 232 if (*ctx == NULL) 233 { 234 result = CF_ERROR_MUTEX_CREATE; 235 TRY_BREAK; 236 } 237 #else 238 result = pthread_mutex_init (&context->mid, NULL); 239 if (result) 240 { 241 result = CF_ERROR_MUTEX_CREATE; 242 TRY_BREAK; 243 } 244 #endif 117 245 } 118 119 #endif 120 return result; 121 } 122 123 /** 124 * 스레드 아이디를 해제 125 * 126 * \return 성공 시, CF_OK; 실패 시, 오류 코드 127 * 128 * \param threadID 스레드 아이디 주소 129 * 130 * \remarks 스레드 아이디를 해제하는 것이며 워커 스레드가 종료되지 않음 131 */ 132 int 133 CF_Thread_DestroyCtx (CF_Thread_Ctx * threadID) 134 { 135 ASSERT_THREAD (*threadID); 136 137 return CF_Thread_Local_Close (*threadID); 138 } 139 140 /** 141 * 스레드가 종료될 때 까지 대기 142 * 143 * \return CF_OK 반환 144 * 145 * \param threadID 스레드 아이디 주소 146 */ 147 int 148 CF_Thread_Join (CF_Thread_Ctx * threadID) 149 { 150 ASSERT_THREAD (*threadID); 151 152 #if defined(_WIN32) || defined(_WIN64) 153 WaitForSingleObject ((THREAD_TYPE) *threadID, INFINITE); 154 #else 155 char status[16] = {0x00,}; 156 pthread_join (*((THREAD_TYPE *) *threadID), (void **)status); 157 #endif 158 159 return CF_OK; 160 } 161 162 /** 163 * 뮤텍스 생성 164 * 165 * \return 성공 시, CF_OK; 실패 시, 오류 코드 166 * 167 * \param mutex 뮤텍스 아이디 주소 168 * 169 * \see CF_Thread_Create 170 */ 171 int 172 CF_Mutex_CreateCtx (CF_Mutex_Ctx * mutex) 173 { 174 int result = 0; 175 176 #if defined(_WIN32) || defined(_WIN64) 177 *mutex = (MUTEX_TYPE) CreateMutexA (NULL, FALSE, NULL); 178 if (*mutex == NULL) 179 return CF_ERROR_MUTEX_CREATE; 180 #else 181 *mutex = (MUTEX_TYPE *) calloc (sizeof (MUTEX_TYPE), 1); 182 if (*mutex == NULL) 183 return CF_ERROR_MUTEX_CREATE; 184 185 result = pthread_mutex_init (*mutex, NULL); 186 if (result) 187 return CF_ERROR_MUTEX_CREATE; 188 #endif 189 190 return CF_OK; 191 } 192 193 /** 194 * 뮤텍스 해제 195 * 196 * \return 성공 시, CF_OK; 실패 시, 오류 코드 197 * 198 * \param mutex 뮤텍스 아이디 주소 199 */ 200 int 201 CF_Mutex_DestoryCtx (CF_Mutex_Ctx * mutex) 202 { 203 ASSERT_MUTEX (*mutex); 204 205 #if defined(_WIN32) || defined(_WIN64) 206 #else 207 pthread_mutex_destroy (*mutex); 208 #endif 209 return CF_Thread_Local_Close (*mutex); 246 CATCH_IF (result < 0) 247 { 248 CF_Mutex_DestoryCtx (ctx); 249 } 250 251 return CF_OK; 252 } 253 254 /** 255 * 뮤텍스 컨텍스트 해제 256 * 257 * \return 성공 시, CF_OK; 실패 시, 오류 코드 258 * 259 * \param ctx 뮤텍스 컨텍스트 260 */ 261 int 262 CF_Mutex_DestoryCtx (CF_Mutex_Ctx ctx) 263 { 264 CF_MUTEX_CTX * context = ctx; 265 266 ASSERT_MUTEX_CTX (ctx); 267 268 CF_Mutex_Local_Close (context->mid); 269 free (context); 270 271 return CF_OK; 210 272 } 211 273 … … 215 277 * \return 성공 시, CF_OK; 실패 시, 오류 코드 216 278 * 217 * \param mutex 뮤텍스 아이디 주소 218 */ 219 int 220 CF_Mutex_Lock (CF_Mutex_Ctx * mutex) 221 { 222 ASSERT_MUTEX (*mutex); 223 224 #if defined(_WIN32) || defined(_WIN64) 225 WaitForSingleObject ((MUTEX_TYPE) *mutex, INFINITE); 226 #else 227 pthread_mutex_lock ((MUTEX_TYPE *) *mutex); 279 * \param ctx 뮤텍스 컨텍스트 280 */ 281 int 282 CF_Mutex_Lock (CF_Mutex_Ctx ctx) 283 { 284 CF_MUTEX_CTX * context = ctx; 285 286 ASSERT_MUTEX_CTX (ctx); 287 288 #if defined(_WIN32) || defined(_WIN64) 289 WaitForSingleObject (context->mid, INFINITE); 290 #else 291 pthread_mutex_lock (&context->mid); 228 292 #endif 229 293 … … 236 300 * \return 성공 시, CF_OK; 실패 시, 오류 코드 237 301 * 238 * \param mutex 뮤텍스 아이디 주소 239 */ 240 int 241 CF_Mutex_Unlock (CF_Mutex_Ctx * mutex) 242 { 243 ASSERT_MUTEX (*mutex); 244 245 #if defined(_WIN32) || defined(_WIN64) 246 ReleaseMutex (*mutex); 247 #else 248 pthread_mutex_unlock ((MUTEX_TYPE *) *mutex); 249 #endif 250 251 return CF_OK; 252 } 302 * \param ctx 뮤텍스 컨텍스트 303 */ 304 int 305 CF_Mutex_Unlock (CF_Mutex_Ctx ctx) 306 { 307 CF_MUTEX_CTX * context = ctx; 308 309 ASSERT_MUTEX_CTX (ctx); 310 311 #if defined(_WIN32) || defined(_WIN64) 312 ReleaseMutex (context->mid); 313 #else 314 pthread_mutex_unlock (&context->mid); 315 #endif 316 317 return CF_OK; 318 }
Note:
See TracChangeset
for help on using the changeset viewer.