PageRenderTime 52ms CodeModel.GetById 29ms app.highlight 17ms RepoModel.GetById 2ms app.codeStats 0ms

/libimagekit/error.c

https://github.com/cleure/Py-ImageKit
C | 206 lines | 138 code | 32 blank | 36 comment | 14 complexity | 40a3b51a11c7c79cd4a67cc52718acc8 MD5 | raw file
  1#include <stdio.h>
  2#include <stdlib.h>
  3#include <string.h>
  4#include <pthread.h>
  5
  6#include "imagekit.h"
  7#include "threading.h"
  8#include "hashtable.h"
  9
 10PRIVATE int  INITIALIZED = 0;
 11PRIVATE struct htable *thread_table = NULL;
 12PRIVATE MUTEX_T thread_table_mutex = MUTEX_T_INITIALIZER;
 13
 14/* Error Strings */
 15const char *ImageKit_ErrorStrings[IMAGEKIT_NUM_ERRORS] = {
 16    "Not Implemented",
 17    "Standard Error",
 18    "Value Error",
 19    "Type Error",
 20    "OS Error",
 21    "IO Error",
 22    "Memory Error",
 23    "Index Error",
 24    "Argument Error"
 25};
 26
 27PRIVATE int thread_table_cmpfn(void *A, void *B)
 28{
 29    if (*(void **)A == *(void **)B) {
 30        return 0;
 31    }
 32    
 33    return -1;
 34}
 35
 36static void thread_table_copyfn(struct htable_entry *ent, void *key, void *value)
 37{
 38    ent->key = malloc(sizeof(uintptr_t));
 39    ent->data = malloc(sizeof(ImageKit_Error));
 40    
 41    memcpy(ent->key, key, sizeof(uintptr_t));
 42    memcpy(ent->data, value, sizeof(ImageKit_Error));
 43}
 44
 45static void thread_table_freefn(struct htable_entry *ent)
 46{
 47    free(ent->key);
 48    free(ent->data);
 49}
 50
 51PRIVATE void init()
 52{
 53    srand((unsigned int)time(NULL));
 54
 55    thread_table = htable_new(
 56        1024,
 57        rand(),
 58        &thread_table_cmpfn,
 59        &thread_table_copyfn,
 60        &thread_table_freefn
 61    );
 62    
 63    INITIALIZED = 1;
 64}
 65
 66PRIVATE
 67void
 68GetLastError(int *code, char **msg, uintptr_t thread_id)
 69{
 70    struct htable_entry *table_ent;
 71    ImageKit_Error *error_ent;
 72    
 73    BEGIN_SYNCHRONIZED(thread_table_mutex) {
 74    
 75        *msg = NULL;
 76        *code = -1;
 77        
 78        if (INITIALIZED) {
 79        
 80            table_ent = htable_get(
 81                thread_table,
 82                sizeof(void *),
 83                &thread_id
 84            );
 85            
 86            if (table_ent != NULL) {
 87                error_ent = table_ent->data;
 88                
 89                *code = error_ent->code;
 90                *msg = (char *)&error_ent->msg;
 91            }
 92        }
 93        
 94    } END_SYNCHRONIZED(thread_table_mutex);
 95}
 96
 97/**
 98* Get Last Error
 99*
100* @param    int *code
101* @param    char **msg
102* @return   void
103**/
104API
105void
106ImageKit_LastError(int *code, char **msg)
107{
108    GetLastError(code, msg, THREAD_ID());
109}
110
111/**
112* Get Last Error for Thread ID
113*
114* @param    int *code
115* @param    char **msg
116* @param    uintptr_t thread_id
117* @return   void
118**/
119API
120void
121ImageKit_LastErrorForThread(int *code, char **msg, uintptr_t thread_id)
122{
123    GetLastError(code, msg, thread_id);
124}
125
126/**
127* Set Error
128*
129* @param    int code
130* @param    char *msg
131* @return   int, 1 on success
132**/
133API
134int
135ImageKit_SetError(int code, const char *msg)
136{
137    int result;
138    ImageKit_Error ent;
139    uintptr_t addr;
140
141    BEGIN_SYNCHRONIZED(thread_table_mutex) {
142    
143        if (!INITIALIZED) {
144            init();
145        }
146    
147        if (code < 0 || !(code < IMAGEKIT_NUM_ERRORS)) {
148            result = 0;
149        } else if (!(strlen(msg) <= IMAGEKIT_ERROR_MAX)) {
150            result = 0;
151        } else {
152            ent.code = code;
153            strcpy((char *)&ent.msg, msg);
154            addr = THREAD_ID();
155            
156            result = htable_add_loop(
157                thread_table,
158                sizeof(void *),
159                &addr,
160                &ent,
161                8
162            );
163        }
164        
165    } END_SYNCHRONIZED(thread_table_mutex);
166    
167    return result;
168}
169
170/**
171* Get Error String, for specified code
172*
173* @param    int code
174* @param    char **msg
175* @return   void
176**/
177API
178void
179ImageKit_GetErrorString(int code, char **msg)
180{
181    if (code < 0 || !(code < IMAGEKIT_NUM_ERRORS)) {
182        *msg = NULL;
183        return;
184    }
185    
186    *msg = (char *)(ImageKit_ErrorStrings[code]);
187}
188
189/**
190* Cleanup function, frees and heap allocated data
191*
192* @return   void
193**/
194API
195void
196ImageKit_CleanupError()
197{
198    BEGIN_SYNCHRONIZED(thread_table_mutex) {
199        if (INITIALIZED) {
200            htable_delete(thread_table);
201            //pthread_mutex_destroy(&thread_table_mutex);
202        }
203        
204        INITIALIZED = 0;
205    } END_SYNCHRONIZED(thread_table_mutex);
206}