From ca34a2f4a2edf6dfd59e71bed793e233abcaf844 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Sun, 20 Nov 2011 22:59:34 -0800 Subject: [PATCH] Added guac_error (thread-local) --- libguac/include/error.h | 4 +++ libguac/src/error.c | 62 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/libguac/include/error.h b/libguac/include/error.h index 2b897339..b6c569d6 100644 --- a/libguac/include/error.h +++ b/libguac/include/error.h @@ -104,4 +104,8 @@ typedef enum guac_status { */ const char* guac_status_string(guac_status status); +#define guac_error (*__guac_error()) + +guac_status* __guac_error(); + #endif diff --git a/libguac/src/error.c b/libguac/src/error.c index 310a7377..c48204fa 100644 --- a/libguac/src/error.c +++ b/libguac/src/error.c @@ -35,8 +35,13 @@ * * ***** END LICENSE BLOCK ***** */ -#include "error.h" +#include +#ifdef HAVE_LIBPTHREAD +#include +#endif + +#include "error.h" /* Error strings */ @@ -51,7 +56,7 @@ const char* __GUAC_STATUS_BAD_STATE_STR = "Illegal state"; const char* __GUAC_STATUS_INVALID_STATUS_STR = "UNKNOWN STATUS CODE"; -const char* guac_status_string(guac_status_t status) { +const char* guac_status_string(guac_status status) { switch (status) { @@ -94,3 +99,56 @@ const char* guac_status_string(guac_status_t status) { } +#ifdef HAVE_LIBPTHREAD + +/* PThread implementation of __guac_error */ + +static pthread_key_t __guac_error_key; +static pthread_once_t __guac_error_key_init = PTHREAD_ONCE_INIT; + +static void __guac_free_error(void* status) { + + /* Free memory allocated to status variable */ + free(status); + +} + +static void __guac_alloc_error_key() { + + /* Create key, destroy any allocated variable on thread exit */ + pthread_key_create(&__guac_error_key, __guac_free_error); + +} + +guac_status* __guac_error() { + + /* Pointer for thread-local data */ + guac_status* status; + + /* Init error key, if not already initialized */ + pthread_once(&__guac_error_key_init, __guac_alloc_error_key); + + /* Retrieve thread-local status variable */ + status = (guac_status*) pthread_getspecific(__guac_error_key); + + /* Allocate thread-local status variable if not already allocated */ + if (status == NULL) { + status = malloc(sizeof(guac_status)); + pthread_setspecific(__guac_error_key, status); + } + + return status; + +} + +#else + +/* Default (not-threadsafe) implementation */ +static guac_status __guac_error_unsafe_storage; + +guac_status* __guac_error() { + return &__guac_error_unsafe_storage; +} + +#endif +