/** * \file cf_mutex.c * * \author myusgun * * \brief 뮤텍스 구현 */ #include "cf_mutex.h" #include "cf_local.h" #include "cf_error.h" #include #if defined(_WIN32) || defined(_WIN64) # include # include # define MUTEX_TYPE HANDLE #else // #if defined(_WIN32) || defined(_WIN64) # include # define MUTEX_TYPE pthread_mutex_t #endif // #if defined(_WIN32) || defined(_WIN64) #define ASSERT_MUTEX_CTX(__ctx) \ if (__ctx == NULL) \ return CF_ERROR_MUTEX_INVALID_CTX typedef struct __cf_ctx_ctx__ { MUTEX_TYPE mid; } CF_MUTEX_CONTEXT; /** * 뮤텍스 컨텍스트를 생성 * * \return 성공 시, CF_OK; 실패 시, 오류 코드 * * \param ctx 뮤텍스 컨텍스트 주소 */ int CF_Mutex_CreateCtx (CF_Mutex_Ctx * ctx) { int result = 0; CF_MUTEX_CONTEXT * context = NULL; context = (CF_MUTEX_CONTEXT *) calloc (sizeof (CF_MUTEX_CONTEXT), 1); if (context == NULL) return CF_ERROR_MUTEX_CREATE_CTX; TRY { #if defined(_WIN32) || defined(_WIN64) context->mid = CreateMutexA (NULL, FALSE, NULL); if (context->mid == 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 *ctx = context; } CATCH_IF (result < 0) { CF_Mutex_DestoryCtx ((CF_Mutex_Ctx) context); } return result; } /** * 뮤텍스 컨텍스트 해제 * * \return 성공 시, CF_OK; 실패 시, 오류 코드 * * \param ctx 뮤텍스 컨텍스트 */ int CF_Mutex_DestoryCtx (CF_Mutex_Ctx ctx) { CF_MUTEX_CONTEXT * context = ctx; ASSERT_MUTEX_CTX (ctx); #if defined(_WIN32) || defined(_WIN64) if (context->mid == NULL) return CF_ERROR_MUTEX_INVALID_ARGS; CloseHandle (context->mid); #else pthread_mutex_destroy (&context->mid); #endif free (context); return CF_OK; } /** * 뮤텍스 잠금 * * \return 성공 시, CF_OK; 실패 시, 오류 코드 * * \param ctx 뮤텍스 컨텍스트 */ int CF_Mutex_Lock (CF_Mutex_Ctx ctx) { CF_MUTEX_CONTEXT * context = ctx; ASSERT_MUTEX_CTX (ctx); #if defined(_WIN32) || defined(_WIN64) WaitForSingleObject (context->mid, INFINITE); #else pthread_mutex_lock (&context->mid); #endif return CF_OK; } /** * 뮤텍스 잠금 해제 * * \return 성공 시, CF_OK; 실패 시, 오류 코드 * * \param ctx 뮤텍스 컨텍스트 */ int CF_Mutex_Unlock (CF_Mutex_Ctx ctx) { CF_MUTEX_CONTEXT * context = ctx; ASSERT_MUTEX_CTX (ctx); #if defined(_WIN32) || defined(_WIN64) ReleaseMutex (context->mid); #else pthread_mutex_unlock (&context->mid); #endif return CF_OK; }