Index: trunk/src/cf_thread.c
===================================================================
--- trunk/src/cf_thread.c	(revision 121)
+++ trunk/src/cf_thread.c	(revision 122)
@@ -26,37 +26,85 @@
 #endif // #if defined(_WIN32) || defined(_WIN64)
 
-#define ASSERT_THREAD(__h)	\
-	if (__h == NULL)		\
-		return CF_ERROR_THREAD_INVALID_ARGS
-
-#define ASSERT_MUTEX(__h)	\
-	if (__h == NULL)		\
-		return CF_ERROR_MUTEX_INVALID_ARGS
+#define ASSERT_THREAD_CTX(__ctx)	\
+	if (__ctx == NULL)				\
+		return CF_ERROR_THREAD_INVALID_CTX
+
+#define ASSERT_MUTEX_CTX(__ctx)	\
+	if (__ctx == NULL)			\
+		return CF_ERROR_MUTEX_INVALID_CTX
 
 typedef THREAD_RETURN (THREAD_CALL * THREAD_WORKER) (void *);
 
+typedef struct __cf_thread_ctx__
+{
+	THREAD_TYPE		tid;
+	THREAD_WORKER	callback;
+	void			* arg;
+} CF_THREAD_CTX;
+
+typedef struct __cf_ctx_ctx__
+{
+	MUTEX_TYPE	mid;
+} CF_MUTEX_CTX;
+
 static int
-CF_Thread_Local_Close (void * ctx)
-{
-#if defined(_WIN32) || defined(_WIN64)
-	CloseHandle (ctx);
-#else
-	free (ctx);
-#endif
-
-	return CF_OK;
-}
-
-/**
- * 스레드를 생성
- *
- * \return 성공 시, CF_OK; 실패 시, 오류 코드
- *
- * \param threadID	스레드 아이디 주소
+CF_Thread_Local_Close (THREAD_TYPE tid)
+{
+#if defined(_WIN32) || defined(_WIN64)
+	CloseHandle (tid);
+#endif
+
+	return CF_OK;
+}
+
+static int
+CF_Mutex_Local_Close (MUTEX_TYPE mid)
+{
+#if defined(_WIN32) || defined(_WIN64)
+	CloseHandle (mid);
+#else
+	pthread_mutex_destroy (&mid);
+#endif
+
+	return CF_OK;
+}
+
+/**
+ * 스레드 컨텍스트를 생성
+ *
+ * \return 성공 시, CF_OK; 실패 시, 오류 코드
+ *
+ * \param ctx		스레드 컨텍스트 주소
  * \param callback	스레드 워커 함수 이름
  * \param arg		스레드 함수로 전달할 인자
+ */
+int
+CF_Thread_CreateCtx (CF_Thread_Ctx		* ctx,
+					 CF_Thread_Function	callback,
+					 void				* arg)
+{
+	CF_THREAD_CTX * context = NULL;
+
+	context = (CF_THREAD_CTX *) calloc (sizeof (CF_THREAD_CTX), 1);
+	if (context == NULL)
+		return CF_ERROR_THREAD_CREATE_CTX;
+
+	context->callback	= (THREAD_WORKER) callback;
+	context->arg		= arg;
+
+	*ctx = (CF_Thread_Ctx) context;
+
+	return CF_OK;
+}
+
+/**
+ * 스레드를 실행
+ *
+ * \return 성공 시, CF_OK; 실패 시, 오류 코드
+ *
+ * \param ctx 스레드 컨텍스트
  *
  * \remarks
- * pthread(POSIX Thread)에서 지원되는 스케줄링 정책은 SCHED_OTHER, SCHED_FIFO, SCHED_RR 등이 존재 <br />
+ * pthread에서 지원되는 스케줄링 정책은 SCHED_OTHER, SCHED_FIFO, SCHED_RR 등이 존재 <br />
  * 일반적으로 설정되는 스케줄링 정책의 기본값은 SCHED_OTHER이며, 솔라리스 환경에서 SCHED_OTHER는 TS(timesharing) 방식으로 명시되어 있음 <br />
  * 그러나 개발 단계에서 테스트된 동작은 SCHED_FIFO와 동일하였으며, 때문에 솔라리스 환경에서는 스케줄링 정책을 SCHED_RR로 명시하도록 함 <br />
@@ -67,16 +115,16 @@
  */
 int
-CF_Thread_Create (CF_Thread_Ctx			* threadID,
-				  CF_Thread_Function	callback,
-				  void					* arg)
+CF_Thread_Start (CF_Thread_Ctx ctx)
 {
 	int result = 0;
 
-	THREAD_WORKER f = (THREAD_WORKER) callback;
-
-#if defined(_WIN32) || defined(_WIN64)
-	*threadID = (THREAD_TYPE) CreateThread (NULL, 0, f, arg, 0, NULL);
-	if (*threadID == NULL)
-		return CF_ERROR_THREAD_CREATE;
+	CF_THREAD_CTX * context = (CF_THREAD_CTX *) ctx;
+
+	ASSERT_THREAD_CTX (ctx);
+
+#if defined(_WIN32) || defined(_WIN64)
+	context->tid = CreateThread (NULL, 0, context->callback, context->arg, 0, NULL);
+	if (context->tid == NULL)
+		return CF_ERROR_THREAD_START;
 #else
 
@@ -106,106 +154,120 @@
 # endif // # if defined(_SOLARIS)
 
-	*threadID = (THREAD_TYPE *) calloc (sizeof (THREAD_TYPE), 1);
-	if (*threadID == NULL)
-		return CF_ERROR_THREAD_CREATE_CTX;
-
-	result = pthread_create ((THREAD_TYPE *) *threadID, attr, f, arg);
-	if (result)
+	result = pthread_create (&context->tid, attr, context->callback, context->arg);
+	if (result)
+		return CF_ERROR_THREAD_START;
+#endif
+	return result;
+}
+
+/**
+ * 스레드 컨텍스트를 해제
+ *
+ * \return 성공 시, CF_OK; 실패 시, 오류 코드
+ *
+ * \param ctx 스레드 컨텍스트
+ *
+ * \remarks 스레드 컨텍스트를 해제하는 것이며 워커 스레드가 종료되지 않음
+ */
+int
+CF_Thread_DestroyCtx (CF_Thread_Ctx ctx)
+{
+	CF_THREAD_CTX * context = (CF_THREAD_CTX *) ctx;
+
+	ASSERT_THREAD_CTX (ctx);
+
+	CF_Thread_Local_Close (context->tid);
+	free (context);
+
+	return CF_OK;
+}
+
+/**
+ * 스레드가 종료될 때 까지 대기
+ *
+ * \return CF_OK 반환
+ *
+ * \param ctx 스레드 컨텍스트
+ */
+int
+CF_Thread_Join (CF_Thread_Ctx ctx)
+{
+	CF_THREAD_CTX * context = (CF_THREAD_CTX *) ctx;
+
+	char status[16] = {0x00,};
+
+	ASSERT_THREAD_CTX (ctx);
+
+#if defined(_WIN32) || defined(_WIN64)
+	WaitForSingleObject (context->tid, INFINITE);
+#else
+	pthread_join (context->tid, (void **)status);
+#endif
+
+	return CF_OK;
+}
+
+/**
+ * 뮤텍스 컨텍스트를 생성
+ *
+ * \return 성공 시, CF_OK; 실패 시, 오류 코드
+ *
+ * \param ctx 뮤텍스 컨텍스트 주소
+ */
+int
+CF_Mutex_CreateCtx (CF_Mutex_Ctx * ctx)
+{
+	int result = 0;
+
+	CF_MUTEX_CTX * context = NULL;
+
+	context = (CF_MUTEX_CTX *) calloc (sizeof (CF_MUTEX_CTX), 1);
+	if (context == NULL)
+		return CF_ERROR_MUTEX_CREATE_CTX;
+
+	TRY
 	{
-		CF_Thread_DestroyCtx (threadID);
-		return CF_ERROR_THREAD_CREATE;
+#if defined(_WIN32) || defined(_WIN64)
+		context->mid = CreateMutexA (NULL, FALSE, NULL);
+		if (*ctx == NULL)
+		{
+			result = CF_ERROR_MUTEX_CREATE;
+			TRY_BREAK;
+		}
+#else
+		result = pthread_mutex_init (&context->mid, NULL);
+		if (result)
+		{
+			result = CF_ERROR_MUTEX_CREATE;
+			TRY_BREAK;
+		}
+#endif
 	}
-
-#endif
-	return result;
-}
-
-/**
- * 스레드 아이디를 해제
- *
- * \return 성공 시, CF_OK; 실패 시, 오류 코드
- *
- * \param threadID 스레드 아이디 주소
- *
- * \remarks 스레드 아이디를 해제하는 것이며 워커 스레드가 종료되지 않음
- */
-int
-CF_Thread_DestroyCtx (CF_Thread_Ctx * threadID)
-{
-	ASSERT_THREAD (*threadID);
-
-	return CF_Thread_Local_Close (*threadID);
-}
-
-/**
- * 스레드가 종료될 때 까지 대기
- *
- * \return CF_OK 반환
- *
- * \param threadID 스레드 아이디 주소
- */
-int
-CF_Thread_Join (CF_Thread_Ctx * threadID)
-{
-	ASSERT_THREAD (*threadID);
-
-#if defined(_WIN32) || defined(_WIN64)
-	WaitForSingleObject ((THREAD_TYPE) *threadID, INFINITE);
-#else
-	char status[16] = {0x00,};
-	pthread_join (*((THREAD_TYPE *) *threadID), (void **)status);
-#endif
-
-	return CF_OK;
-}
-
-/**
- * 뮤텍스 생성
- *
- * \return 성공 시, CF_OK; 실패 시, 오류 코드
- *
- * \param mutex 뮤텍스 아이디 주소
- *
- * \see CF_Thread_Create
- */
-int
-CF_Mutex_CreateCtx (CF_Mutex_Ctx * mutex)
-{
-	int result = 0;
-
-#if defined(_WIN32) || defined(_WIN64)
-	*mutex = (MUTEX_TYPE) CreateMutexA (NULL, FALSE, NULL);
-	if (*mutex == NULL)
-		return CF_ERROR_MUTEX_CREATE;
-#else
-	*mutex = (MUTEX_TYPE *) calloc (sizeof (MUTEX_TYPE), 1);
-	if (*mutex == NULL)
-		return CF_ERROR_MUTEX_CREATE;
-
-	result = pthread_mutex_init (*mutex, NULL);
-	if (result)
-		return CF_ERROR_MUTEX_CREATE;
-#endif
-
-	return CF_OK;
-}
-
-/**
- * 뮤텍스 해제
- *
- * \return 성공 시, CF_OK; 실패 시, 오류 코드
- *
- * \param mutex 뮤텍스 아이디 주소
- */
-int
-CF_Mutex_DestoryCtx (CF_Mutex_Ctx * mutex)
-{
-	ASSERT_MUTEX (*mutex);
-
-#if defined(_WIN32) || defined(_WIN64)
-#else
-	pthread_mutex_destroy (*mutex);
-#endif
-	return CF_Thread_Local_Close (*mutex);
+	CATCH_IF (result < 0)
+	{
+		CF_Mutex_DestoryCtx (ctx);
+	}
+
+	return CF_OK;
+}
+
+/**
+ * 뮤텍스 컨텍스트 해제
+ *
+ * \return 성공 시, CF_OK; 실패 시, 오류 코드
+ *
+ * \param ctx 뮤텍스 컨텍스트
+ */
+int
+CF_Mutex_DestoryCtx (CF_Mutex_Ctx ctx)
+{
+	CF_MUTEX_CTX * context = ctx;
+
+	ASSERT_MUTEX_CTX (ctx);
+
+	CF_Mutex_Local_Close (context->mid);
+	free (context);
+
+	return CF_OK;
 }
 
@@ -215,15 +277,17 @@
  * \return 성공 시, CF_OK; 실패 시, 오류 코드
  *
- * \param mutex 뮤텍스 아이디 주소
- */
-int
-CF_Mutex_Lock (CF_Mutex_Ctx * mutex)
-{
-	ASSERT_MUTEX (*mutex);
-
-#if defined(_WIN32) || defined(_WIN64)
-	WaitForSingleObject ((MUTEX_TYPE) *mutex, INFINITE);
-#else
-	pthread_mutex_lock ((MUTEX_TYPE *) *mutex);
+ * \param ctx 뮤텍스 컨텍스트
+ */
+int
+CF_Mutex_Lock (CF_Mutex_Ctx ctx)
+{
+	CF_MUTEX_CTX * context = ctx;
+
+	ASSERT_MUTEX_CTX (ctx);
+
+#if defined(_WIN32) || defined(_WIN64)
+	WaitForSingleObject (context->mid, INFINITE);
+#else
+	pthread_mutex_lock (&context->mid);
 #endif
 
@@ -236,17 +300,19 @@
  * \return 성공 시, CF_OK; 실패 시, 오류 코드
  *
- * \param mutex 뮤텍스 아이디 주소
- */
-int
-CF_Mutex_Unlock (CF_Mutex_Ctx * mutex)
-{
-	ASSERT_MUTEX (*mutex);
-
-#if defined(_WIN32) || defined(_WIN64)
-	ReleaseMutex (*mutex);
-#else
-	pthread_mutex_unlock ((MUTEX_TYPE *) *mutex);
-#endif
-
-	return CF_OK;
-}
+ * \param ctx 뮤텍스 컨텍스트
+ */
+int
+CF_Mutex_Unlock (CF_Mutex_Ctx ctx)
+{
+	CF_MUTEX_CTX * context = ctx;
+
+	ASSERT_MUTEX_CTX (ctx);
+
+#if defined(_WIN32) || defined(_WIN64)
+	ReleaseMutex (context->mid);
+#else
+	pthread_mutex_unlock (&context->mid);
+#endif
+
+	return CF_OK;
+}
