Index: trunk/src/cf_log.c
===================================================================
--- trunk/src/cf_log.c	(revision 38)
+++ trunk/src/cf_log.c	(revision 40)
@@ -12,4 +12,5 @@
 #include "cf_thread.h"
 #include "cf_local.h"
+#include "cf_error.h"
 
 #include <stdio.h>
@@ -38,4 +39,11 @@
 
 #define CF_LOG_DATETIME_LENGTH			sizeof ("0000-00-00 00:00:00.000") - 1
+
+/**
+ * 로그 컨텍스트
+ * 
+ * @remark change from public to private
+ */
+typedef void *	CF_Log_Ctx;
 
 typedef struct __cf_util_datetime__
@@ -189,4 +197,6 @@
 				   const size_t	demandSize)
 {
+	int result = CF_OK;
+
 	if( ctx->size > 0 ) /* 버퍼단위 버퍼링.... */
 	{
@@ -213,7 +223,315 @@
 		ctx->length = demandSize;
 
-		if (CF_Log_Local_Flush (ctx) < 0)
-			return CF_ERROR_LOG_FLUSH;
-	}
+		result = CF_Log_Local_Flush (ctx);
+	}
+
+	return result;
+}
+
+/**
+ * 로그 컨텍스트에 멀티쓰레드 모드 설정
+ *
+ * @return 성공 시, CF_OK; 실패 시, 오류 코드 
+ *
+ * @param ctx 로그 컨텍스트
+ *
+ * @see CF_Log_UnsetMultiThread
+ */
+static int
+CF_Log_SetMultiThread (CF_Log_Ctx ctx)
+{
+	CF_LOG_CTX * context = (CF_LOG_CTX *) ctx;
+
+	if (CHECK_INVALID_CTX (ctx))
+		return CF_ERROR_LOG_INVALID_CTX;
+
+	if (CF_Mutex_Create (&context->mutex) < 0)
+		return CF_ERROR_LOG_SET_MULTITHREAD;
+
+	return CF_OK;
+}
+
+/**
+ * 로그 컨텍스트에 멀티쓰레드 모드 설정 해제
+ *
+ * @return 성공 시, CF_OK; 실패 시, 오류 코드 
+ *
+ * @param ctx 로그 컨텍스트
+ *
+ * @see CF_Log_SetMultiThread
+ */
+static int
+CF_Log_UnsetMultiThread (CF_Log_Ctx ctx)
+{
+	CF_LOG_CTX * context = (CF_LOG_CTX *) ctx;
+
+	if (CHECK_INVALID_CTX (ctx))
+		return CF_ERROR_LOG_INVALID_CTX;
+
+	if (CF_Mutex_Destory (&context->mutex) < 0)
+		return CF_ERROR_LOG_UNSET_MULTITHREAD;
+
+	return CF_OK;
+}
+
+/**
+ * 로그 컨텍스트에 따라 로그 쓰기
+ *
+ * @return 성공 시, CF_OK; 실패 시, 오류 코드
+ *
+ * @param ctx		로그 컨텍스트
+ * @param prefix	로그의 프리픽스 문자열
+ * @param fmt		포맷 스트링
+ * @param ...		가변 인자
+ */
+static int
+CF_Log_WriteCtx (CF_Log_Ctx	ctx,
+				 const char	* prefix,
+				 const char	* fmt,
+//				 ...)
+				 va_list	valist)
+{
+	CF_LOG_CTX	* context = (CF_LOG_CTX *) ctx;
+//	va_list		valist;
+	char		buffer[16 * 1024] = {0x00,};
+	char		datetime[CF_LOG_DATETIME_LENGTH + 1] = {0x00,};
+
+	if (CHECK_INVALID_CTX (ctx))
+		return CF_ERROR_LOG_INVALID_CTX;
+
+	LOCK_LOG_CTX (context);
+//	va_start (valist, fmt);
+
+	CF_Log_Local_GetTimeString (datetime);
+	sprintf (buffer, "[%s][%s] ", datetime, prefix);
+	vsprintf (buffer + strlen (buffer), fmt, valist);
+
+	CF_Log_Local_Push (context, buffer, strlen (buffer));
+
+//	va_end (valist);
+	UNLOCK_LOG_CTX (context);
+
+	return CF_OK;
+}
+
+/**
+ * 로그 버퍼의 데이터를 즉시 로그 파일에 쓰기
+ *
+ * @return 성공 시, CF_OK; 실패 시, 오류 코드
+ *
+ * @param ctx 로그 컨텍스트
+ */
+static int
+CF_Log_FlushCtx (CF_Log_Ctx ctx)
+{
+	CF_LOG_CTX * context = (CF_LOG_CTX *) ctx;
+
+	if (CHECK_INVALID_CTX (ctx))
+		return CF_ERROR_LOG_INVALID_CTX;
+
+	LOCK_LOG_CTX (context);
+	CF_Log_Local_Flush (context);
+	UNLOCK_LOG_CTX (context);
+
+	return CF_OK;
+}
+
+/**
+ * 로그 컨텍스트 해제
+ *
+ * @return 성공 시, CF_OK; 실패 시, 오류 코드 
+ *
+ * @param ctx 로그 컨텍스트
+ */
+static int
+CF_Log_DestroyCtx (CF_Log_Ctx ctx)
+{
+	CF_LOG_CTX * context = (CF_LOG_CTX *) ctx;
+
+	if (CHECK_INVALID_CTX (ctx))
+		return CF_ERROR_LOG_INVALID_CTX;
+
+	if (context->size > 0)
+	{
+		CF_Log_FlushCtx (ctx);
+		free (context->buffer);
+		context->buffer = NULL;
+		context->size = 0;
+	}
+
+	CF_File_Close (context->fd);
+
+	if (context->mutex != NULL)
+	{
+		if (CF_Mutex_Destory (&context->mutex) < 0)
+			/* do something ? */;
+
+		context->mutex = NULL;
+	}
+
+	return CF_OK;
+}
+
+/**
+ * 로그 컨텍스트 생성
+ *
+ * @return 성공 시, 로그 컨텍스트; 실패 시, NULL
+ *
+ * @param path		로그 파일 경로
+ * @param memsize	로그 버퍼 크기
+ * @param ctx		로그 컨텍스트 받을 주소
+ *
+ * @see CF_LOG_BUFFER_DEFAULT, CF_LOG_BUFFER_NO
+ */
+static int
+CF_Log_CreateCtx (const char	* path,
+				  const int		memsize,
+				  CF_Log_Ctx	* ctx)
+{
+	int result = 0;
+	int size = (memsize == CF_LOG_BUFFER_DEFAULT)
+			 ? CF_LOG_BUFFER_DEFAULT_SIZE
+			 : memsize;
+	CF_LOG_CTX	* context = NULL;
+
+	if (path == NULL)
+		return CF_ERROR_LOG_INVALID_ARGS;
+
+	TRY
+	{
+		context = (CF_LOG_CTX *) calloc (sizeof (CF_LOG_CTX), 1);
+		if (context == NULL)
+		{
+			result = CF_ERROR_LOG_ALLOCATE_CTX;
+			TRY_BREAK;
+		}
+
+		context->fd = CF_File_Create (path);
+		if (context->fd < 0)
+		{
+			result = CF_ERROR_LOG_CREATE_FILE;
+			TRY_BREAK;
+		}
+		sprintf (context->path, "%s", path);
+
+		if (size > 0)
+		{
+			context->buffer = (char *) calloc ((size_t) size + 1, 1);
+			if (context->buffer == NULL)
+			{
+				result = CF_ERROR_LOG_ALLOCATE_BUFFER;
+				TRY_BREAK;
+			}
+			context->size = (size_t) size;
+		}
+	}
+	CATCH_IF (result < 0)
+	{
+		CF_Log_DestroyCtx ((CF_Log_Ctx) context);
+		return result;
+	}
+
+	*ctx = (CF_Log_Ctx) context;
+
+	return CF_OK;
+}
+
+/**
+ * 로그 컨텍스트에 아이디 넘버 할당<br />
+ * 로그 기록 시, 아이디 넘버를 사용하면 해당 로그로 기록할 수 있음
+ *
+ * @return 성공 시, CF_OK; 실패 시, 오류 코드
+ *
+ * @param mapid	부여할 아이디 넘버
+ * @param ctx	로그 컨텍스트
+ *
+ * @remark 반드시 먼저 초기화 해야하며, 초기화 시에 주어진 번호보다 작은 아이디 넘버를 사용해야 함
+ *
+ * @see CF_LOG_OPEN, CF_Log_CreateCtx
+ */
+static int
+CF_Log_MapCtxID (const int			mapid,
+				 const CF_Log_Ctx	ctx)
+{
+	int result = 0;
+
+	TRY
+	{
+		if (CHECK_INITIALIZED ())
+		{
+			result = CF_ERROR_LOG_NOT_INITIALIZE;
+			TRY_BREAK;
+		}
+		if (CHECK_INVALID_MAPID (mapid))
+		{
+			result = CF_ERROR_LOG_INVALID_MAPID;
+			TRY_BREAK;
+		}
+		if (CHECK_MAPPED_ID (mapid))
+		{
+			result = CF_ERROR_LOG_ALREADY_MAPPED_ID;
+			TRY_BREAK;
+		}
+	}
+	CATCH_IF (result < 0)
+	{
+		CF_Log_DestroyCtx (ctx);
+		return result;
+	}
+
+	gLogEnvironment.ctxPool[mapid] = ctx;
+
+	return CF_OK;
+}
+
+/**
+ * 아이디 넘버에 해당하는 로그를 닫고 해당하는 컨텍스트를 해제
+ *
+ * @return 성공 시, CF_OK; 실패 시, 오류 코드
+ *
+ * @param mapid 로그의 아이디 넘버
+ *
+ * @remark 아이디 넘버에 해당하는 컨텍스트가 해제되므로 주의
+ *
+ * @see CF_LOG_CLOSE, CF_Log_DestroyCtx
+ */
+static int
+CF_Log_UnmapCtxID (const int mapid)
+{
+	if (CHECK_INITIALIZED ())
+		return CF_ERROR_LOG_NOT_INITIALIZE;
+	if (CHECK_INVALID_MAPID (mapid))
+		return CF_ERROR_LOG_INVALID_MAPID;
+	if (!CHECK_MAPPED_ID (mapid))
+		return CF_ERROR_LOG_NOT_MAPPED_ID;
+
+	CF_Log_DestroyCtx (gLogEnvironment.ctxPool[mapid]);
+
+	free (gLogEnvironment.ctxPool[mapid]);
+	gLogEnvironment.ctxPool[mapid] = NULL;
+
+	return CF_OK;
+}
+
+/**
+ * 아이디 넘버에 해당하는 로그 컨텍스트를 얻기
+ *
+ * @return 성공 시, CF_OK; 실패 시, 오류 코드
+ *
+ * @param mapid	로그의 아이디 넘버
+ * @param ctx	로그 컨텍스트 받을 주소
+ */
+static int
+CF_Log_GetMappedCtx (const int	mapid,
+					 CF_Log_Ctx	* ctx)
+{
+	if (CHECK_INITIALIZED ())
+		return CF_ERROR_LOG_NOT_INITIALIZE;
+	if (CHECK_INVALID_MAPID (mapid))
+		return CF_ERROR_LOG_INVALID_MAPID;
+	if (!CHECK_MAPPED_ID (mapid))
+		return CF_ERROR_LOG_NOT_MAPPED_ID;
+
+	*ctx = gLogEnvironment.ctxPool[mapid];
 
 	return CF_OK;
@@ -268,8 +586,9 @@
 
 /**
- * 로그 컨텍스트 생성
- *
- * @return 성공 시, 로그 컨텍스트; 실패 시, NULL
- *
+ * 로그 열기
+ *
+ * @return 성공 시, CF_OK; 실패 시, 오류 코드
+ *
+ * @param mapid 로그의 아이디 넘버
  * @param path		로그 파일 경로
  * @param memsize	로그 버퍼 크기
@@ -277,138 +596,40 @@
  * @see CF_LOG_BUFFER_DEFAULT, CF_LOG_BUFFER_NO
  */
-CF_Log_Ctx
-CF_Log_CreateCtx (const char	* path,
-				  const int		memsize)
-{
-	int result = 0;
-	int size = (memsize == CF_LOG_BUFFER_DEFAULT)
-			 ? CF_LOG_BUFFER_DEFAULT_SIZE
-			 : memsize;
-	CF_LOG_CTX	* context = NULL;
-
-	if (path == NULL)
-		return NULL;
-
-	TRY
-	{
-		context = (CF_LOG_CTX *) calloc (sizeof (CF_LOG_CTX), 1);
-		if (context == NULL)
-		{
-			result = -1;
-			TRY_BREAK;
-		}
-
-		context->fd = CF_File_Create (path);
-		if (context->fd < 0)
-		{
-			result = -2;
-			TRY_BREAK;
-		}
-		sprintf (context->path, "%s", path);
-
-		if (size > 0)
-		{
-			context->buffer = (char *) calloc ((size_t) size + 1, 1);
-			if (context->buffer == NULL)
-			{
-				result = -3;
-				TRY_BREAK;
-			}
-			context->size = (size_t) size;
-		}
-	}
-	CATCH_IF (result < 0)
-	{
-		CF_Log_DestroyCtx ((CF_Log_Ctx) context);
-		return NULL;
-	}
-
-	return (CF_Log_Ctx) context;
-}
-
-/**
- * 로그 컨텍스트 해제
- *
- * @return 성공 시, CF_OK; 실패 시, 오류 코드 
- *
- * @param ctx 로그 컨텍스트
- */
 int
-CF_Log_DestroyCtx (CF_Log_Ctx ctx)
-{
-	CF_LOG_CTX * context = (CF_LOG_CTX *) ctx;
-
-	if (CHECK_INVALID_CTX (ctx))
-		return CF_ERROR_LOG_INVALID_CTX;
-
-	if (context->size > 0)
-	{
-		CF_Log_Flush (ctx);
-		free (context->buffer);
-		context->buffer = NULL;
-		context->size = 0;
-	}
-
-	CF_File_Close (context->fd);
-
-	if (context->mutex != NULL)
-	{
-		if (CF_Mutex_Destory (&context->mutex) < 0)
-			/* do something ? */;
-
-		context->mutex = NULL;
-	}
-
-	return CF_OK;
-}
-
-/**
- * 로그 컨텍스트에 멀티쓰레드 모드 설정
- *
- * @return 성공 시, CF_OK; 실패 시, 오류 코드 
- *
- * @param ctx 로그 컨텍스트
+CF_Log_Open (const int	mapid,
+			 const char	* path,
+			 const int	memsize)
+{
+	int			result = 0;
+	CF_Log_Ctx	ctx = NULL;
+
+	result = CF_Log_CreateCtx (path, memsize, &ctx);
+	if (result < 0)
+		return result;
+
+	result = CF_Log_MapCtxID (mapid, ctx);
+
+	return result;
+}
+
+/**
+ * 로그 닫기
+ *
+ * @return 성공 시, CF_OK; 실패 시, 오류 코드
+ *
+ * @param mapid 로그의 아이디 넘버
  */
 int
-CF_Log_SetMultiThread (CF_Log_Ctx ctx)
-{
-	CF_LOG_CTX * context = (CF_LOG_CTX *) ctx;
-
-	if (CHECK_INVALID_CTX (ctx))
-		return CF_ERROR_LOG_INVALID_CTX;
-
-	if (CF_Mutex_Create (&context->mutex) < 0)
-		return CF_ERROR_LOG_SET_MULTITHREAD;
-
-	return CF_OK;
-}
-
-/**
- * 로그 컨텍스트에 멀티쓰레드 모드 설정 해제
- *
- * @return 성공 시, CF_OK; 실패 시, 오류 코드 
- *
- * @param ctx 로그 컨텍스트
- */
-int
-CF_Log_UnsetMultiThread (CF_Log_Ctx ctx)
-{
-	CF_LOG_CTX * context = (CF_LOG_CTX *) ctx;
-
-	if (CHECK_INVALID_CTX (ctx))
-		return CF_ERROR_LOG_INVALID_CTX;
-
-	if (CF_Mutex_Destory (&context->mutex) < 0)
-		return CF_ERROR_LOG_UNSET_MULTITHREAD;
-
-	return CF_OK;
-}
-
-/**
- * 로그 컨텍스트에 따라 로그 쓰기
- *
- * @return 성공 시, CF_OK; 실패 시, 오류 코드
- *
- * @param ctx		로그 컨텍스트
+CF_Log_Close (const int mapid)
+{
+	return CF_Log_UnmapCtxID (mapid);
+}
+
+/**
+ * 로그 쓰기
+ *
+ * @return 성공 시, CF_OK; 실패 시, 오류 코드
+ *
+ * @param mapid		로그의 아이디 넘버
  * @param prefix	로그의 프리픽스 문자열
  * @param fmt		포맷 스트링
@@ -416,29 +637,21 @@
  */
 int
-CF_Log_Write (CF_Log_Ctx	ctx,
+CF_Log_Write (const int		mapid,
 			  const char	* prefix,
 			  const char	* fmt, ...)
 {
-	CF_LOG_CTX	* context = (CF_LOG_CTX *) ctx;
+	int			result = 0;
+	CF_Log_Ctx	ctx = NULL;
 	va_list		valist;
-	char		buffer[16 * 1024] = {0x00,};
-	char		datetime[CF_LOG_DATETIME_LENGTH + 1] = {0x00,};
-
-	if (CHECK_INVALID_CTX (ctx))
-		return CF_ERROR_LOG_INVALID_CTX;
-
-	LOCK_LOG_CTX (context);
+
+	result = CF_Log_GetMappedCtx (mapid, &ctx);
+	if (result < 0)
+		return result;
+
 	va_start (valist, fmt);
-
-	CF_Log_Local_GetTimeString (datetime);
-	sprintf (buffer, "[%s][%s] ", datetime, prefix);
-	vsprintf (buffer + strlen (buffer), fmt, valist);
-
-	CF_Log_Local_Push (context, buffer, strlen (buffer));
-
+	result = CF_Log_WriteCtx (ctx, prefix, fmt, valist);
 	va_end (valist);
-	UNLOCK_LOG_CTX (context);
-
-	return CF_OK;
+
+	return result;
 }
 
@@ -448,115 +661,46 @@
  * @return 성공 시, CF_OK; 실패 시, 오류 코드
  *
- * @param ctx 로그 컨텍스트
+ * @param mapid 로그의 아이디 넘버
  */
 int
-CF_Log_Flush (CF_Log_Ctx ctx)
-{
-	CF_LOG_CTX * context = (CF_LOG_CTX *) ctx;
-
-	if (CHECK_INVALID_CTX (ctx))
-		return CF_ERROR_LOG_INVALID_CTX;
-
-	LOCK_LOG_CTX (context);
-	CF_Log_Local_Flush (context);
-	UNLOCK_LOG_CTX (context);
-
-	return CF_OK;
-}
-
-/**
- * 로그 컨텍스트에 아이디 넘버 할당<br />
- * 로그 기록 시, 아이디 넘버를 사용하면 해당 로그로 기록할 수 있음
- *
- * @return 성공 시, CF_OK; 실패 시, 오류 코드
- *
- * @param mapid	부여할 아이디 넘버
- * @param ctx	로그 컨텍스트
- *
- * @remark 반드시 먼저 초기화 해야하며, 초기화 시에 주어진 번호보다 작은 아이디 넘버를 사용해야 함
- *
- * @see CF_LOG_OPEN, CF_Log_CreateCtx
+CF_Log_Flush (const int mapid)
+{
+	int			result = 0;
+	CF_Log_Ctx	ctx = NULL;
+
+	result = CF_Log_GetMappedCtx (mapid, &ctx);
+	if (result < 0)
+		return result;
+
+	result = CF_Log_FlushCtx (ctx);
+
+	return result;
+}
+
+/**
+ * 로그 컨텍스트에 멀티쓰레드 모드 설정
+ *
+ * @return 성공 시, CF_OK; 실패 시, 오류 코드 
+ *
+ * @param mapid	로그의 아이디 넘버
+ * @param flag	설정/해제 bool 플래그
+ *
+ * @see CF_BOOL
  */
 int
-CF_Log_MapCtxID (const int			mapid,
-				 const CF_Log_Ctx	ctx)
-{
-	int result = 0;
-
-	TRY
-	{
-		if (CHECK_INITIALIZED())
-		{
-			result = CF_ERROR_LOG_NOT_INITIALIZE;
-			TRY_BREAK;
-		}
-		if (CHECK_INVALID_MAPID(mapid))
-		{
-			result = CF_ERROR_LOG_INVALID_MAPID;
-			TRY_BREAK;
-		}
-		if (CHECK_MAPPED_ID(mapid))
-		{
-			result = CF_ERROR_LOG_ALREADY_MAPPED_ID;
-			TRY_BREAK;
-		}
-	}
-	CATCH_IF (result < 0)
-	{
-		CF_Log_DestroyCtx (ctx);
+CF_Log_SetMT (const int		mapid,
+			  const CF_BOOL	flag)
+{
+	int			result = 0;
+	CF_Log_Ctx	ctx = NULL;
+
+	result = CF_Log_GetMappedCtx (mapid, &ctx);
+	if (result < 0)
 		return result;
-	}
-
-	gLogEnvironment.ctxPool[mapid] = ctx;
-
-	return CF_OK;
-}
-
-/**
- * 아이디 넘버에 해당하는 로그를 닫고 해당하는 컨텍스트를 해제
- *
- * @return 성공 시, CF_OK; 실패 시, 오류 코드
- *
- * @param mapid 로그의 아이디 넘버
- *
- * @remark 아이디 넘버에 해당하는 컨텍스트가 해제되므로 주의
- *
- * @see CF_LOG_CLOSE, CF_Log_DestroyCtx
- */
-int
-CF_Log_UnmapCtxID (const int mapid)
-{
-	if (CHECK_INITIALIZED())
-		return CF_ERROR_LOG_NOT_INITIALIZE;
-	if (CHECK_INVALID_MAPID(mapid))
-		return CF_ERROR_LOG_INVALID_MAPID;
-	if (!CHECK_MAPPED_ID(mapid))
-		return CF_ERROR_LOG_NOT_MAPPED_ID;
-
-	CF_Log_DestroyCtx (gLogEnvironment.ctxPool[mapid]);
-
-	free (gLogEnvironment.ctxPool[mapid]);
-	gLogEnvironment.ctxPool[mapid] = NULL;
-
-	return CF_OK;
-}
-
-/**
- * 아이디 넘버에 해당하는 로그 컨텍스트를 얻기
- *
- * @return 성공 시, 로그 컨텍스트; 실패 시, NULL
- *
- * @param mapid 로그의 아이디 넘버
- */
-CF_Log_Ctx
-CF_Log_GetMappedCtx (const int mapid)
-{
-	if (CHECK_INITIALIZED())
-		return NULL;
-	if (CHECK_INVALID_MAPID(mapid))
-		return NULL;
-	if (!CHECK_MAPPED_ID(mapid))
-		return NULL;
-
-	return gLogEnvironment.ctxPool[mapid];
-}
+
+	result = (flag == CF_TRUE)
+		   ? CF_Log_SetMultiThread (ctx)
+		   : CF_Log_UnsetMultiThread (ctx);
+
+	return result;
+}
