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