Changeset 122 in libcf for trunk/src/cf_thread.c


Ignore:
Timestamp:
06/12/13 11:05:07 (11 years ago)
Author:
cheese
Message:

#1 modify id to context in thread

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/cf_thread.c

    r121 r122  
    2626#endif // #if defined(_WIN32) || defined(_WIN64)
    2727
    28 #define ASSERT_THREAD(__h)  \
    29     if (__h == NULL)        \
    30         return CF_ERROR_THREAD_INVALID_ARGS
    31 
    32 #define ASSERT_MUTEX(__h)   \
    33     if (__h == NULL)        \
    34         return CF_ERROR_MUTEX_INVALID_ARGS
     28#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
    3535
    3636typedef THREAD_RETURN (THREAD_CALL * THREAD_WORKER) (void *);
    3737
     38typedef struct __cf_thread_ctx__
     39{
     40    THREAD_TYPE     tid;
     41    THREAD_WORKER   callback;
     42    void            * arg;
     43} CF_THREAD_CTX;
     44
     45typedef struct __cf_ctx_ctx__
     46{
     47    MUTEX_TYPE  mid;
     48} CF_MUTEX_CTX;
     49
    3850static 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  스레드 아이디 주소
     51CF_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
     60static int
     61CF_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       스레드 컨텍스트 주소
    5678 * \param callback  스레드 워커 함수 이름
    5779 * \param arg       스레드 함수로 전달할 인자
     80 */
     81int
     82CF_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 스레드 컨텍스트
    58106 *
    59107 * \remarks
    60  * pthread(POSIX Thread)에서 지원되는 스케줄링 정책은 SCHED_OTHER, SCHED_FIFO, SCHED_RR 등이 존재 <br />
     108 * pthread에서 지원되는 스케줄링 정책은 SCHED_OTHER, SCHED_FIFO, SCHED_RR 등이 존재 <br />
    61109 * 일반적으로 설정되는 스케줄링 정책의 기본값은 SCHED_OTHER이며, 솔라리스 환경에서 SCHED_OTHER는 TS(timesharing) 방식으로 명시되어 있음 <br />
    62110 * 그러나 개발 단계에서 테스트된 동작은 SCHED_FIFO와 동일하였으며, 때문에 솔라리스 환경에서는 스케줄링 정책을 SCHED_RR로 명시하도록 함 <br />
     
    67115 */
    68116int
    69 CF_Thread_Create (CF_Thread_Ctx         * threadID,
    70                   CF_Thread_Function    callback,
    71                   void                  * arg)
     117CF_Thread_Start (CF_Thread_Ctx ctx)
    72118{
    73119    int result = 0;
    74120
    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;
    81129#else
    82130
     
    106154# endif // # if defined(_SOLARIS)
    107155
    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 */
     172int
     173CF_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 */
     192int
     193CF_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 */
     217int
     218CF_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
    114229    {
    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
    117245    }
    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 */
     261int
     262CF_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;
    210272}
    211273
     
    215277 * \return 성공 시, CF_OK; 실패 시, 오류 코드
    216278 *
    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 */
     281int
     282CF_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);
    228292#endif
    229293
     
    236300 * \return 성공 시, CF_OK; 실패 시, 오류 코드
    237301 *
    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 */
     304int
     305CF_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.