diff options
author | Tavian Barnes <tavianator@gmail.com> | 2009-10-18 21:45:22 +0000 |
---|---|---|
committer | Tavian Barnes <tavianator@gmail.com> | 2009-10-18 21:45:22 +0000 |
commit | fe51d90d38d14412a5f173b34e7ba5e0d8ddac80 (patch) | |
tree | d482a34b32c83c7cf4d9eaf019889b37b5c254b4 | |
parent | 8646f32b25d5ae22b5483854059ee584dfc4a2c7 (diff) | |
download | dimension-fe51d90d38d14412a5f173b34e7ba5e0d8ddac80.tar.xz |
Allow custom fatal error handlers.
-rw-r--r-- | libdimension/dimension/error.h | 8 | ||||
-rw-r--r-- | libdimension/error.c | 46 |
2 files changed, 52 insertions, 2 deletions
diff --git a/libdimension/dimension/error.h b/libdimension/dimension/error.h index cc38d65..caee303 100644 --- a/libdimension/dimension/error.h +++ b/libdimension/dimension/error.h @@ -54,4 +54,12 @@ void dmnsn_report_error(dmnsn_severity severity, dmnsn_severity dmnsn_get_resilience(); void dmnsn_set_resilience(dmnsn_severity resilience); +/* Fatal error callback type */ +typedef void dmnsn_fatal_error_fn(); + +/* Get and set libdimension fatal error handling strategy - the default is + exit(EXIT_FAILURE) */ +dmnsn_fatal_error_fn *dmnsn_get_fatal_error_fn(); +void dmnsn_set_fatal_error_fn(dmnsn_fatal_error_fn *fatal); + #endif /* DIMENSION_ERROR_H */ diff --git a/libdimension/error.c b/libdimension/error.c index 3b7a430..57880f9 100644 --- a/libdimension/error.c +++ b/libdimension/error.c @@ -23,8 +23,12 @@ #include <stdio.h> /* For fprintf() */ #include <stdlib.h> /* For exit() */ +static void dmnsn_default_fatal_error_fn(); +static dmnsn_fatal_error_fn *dmnsn_fatal = &dmnsn_default_fatal_error_fn; + static dmnsn_severity dmnsn_resilience = DMNSN_SEVERITY_MEDIUM; static pthread_mutex_t dmnsn_resilience_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t dmnsn_fatal_mutex = PTHREAD_MUTEX_INITIALIZER; /* Called by dmnsn_error macro (don't call directly). */ void @@ -34,7 +38,7 @@ dmnsn_report_error(dmnsn_severity severity, const char *func, unsigned int line, if (severity >= dmnsn_get_resilience()) { /* An error more severe than our resilience happened, bail out */ fprintf(stderr, "Dimension ERROR: %s, line %u: %s\n", func, line, str); - exit(EXIT_FAILURE); + (*dmnsn_fatal)(); } else { /* A trivial error happened, warn and continue */ fprintf(stderr, "Dimension WARNING: %s, line %u: %s\n", func, line, str); @@ -71,7 +75,7 @@ dmnsn_set_resilience(dmnsn_severity resilience) /* Tried to set an illegal resilience, bail out */ fprintf(stderr, "Dimension ERROR: %s, line %u: %s\n", DMNSN_FUNC, __LINE__, "Resilience has wrong value."); - exit(EXIT_FAILURE); + (*dmnsn_fatal)(); } if (pthread_mutex_lock(&dmnsn_resilience_mutex) != 0) { @@ -89,3 +93,41 @@ dmnsn_set_resilience(dmnsn_severity resilience) "Couldn't unlock resilience mutex."); } } + +dmnsn_fatal_error_fn *dmnsn_get_fatal_error_fn() +{ + dmnsn_fatal_error_fn *fatal; + if (pthread_mutex_lock(&dmnsn_fatal_mutex) != 0) { + fprintf(stderr, "Dimension WARNING: %s, line %u: %s\n", + DMNSN_FUNC, __LINE__, + "Couldn't lock fatal error handler mutex."); + } + fatal = dmnsn_fatal; + if (pthread_mutex_unlock(&dmnsn_fatal_mutex) != 0) { + fprintf(stderr, "Dimension WARNING: %s, line %u: %s\n", + DMNSN_FUNC, __LINE__, + "Couldn't unlock fatal error handler mutex."); + } + return fatal; +} + +void dmnsn_set_fatal_error_fn(dmnsn_fatal_error_fn *fatal) +{ + if (pthread_mutex_lock(&dmnsn_fatal_mutex) != 0) { + fprintf(stderr, "Dimension WARNING: %s, line %u: %s\n", + DMNSN_FUNC, __LINE__, + "Couldn't lock fatal error handler mutex."); + } + dmnsn_fatal = fatal; + if (pthread_mutex_unlock(&dmnsn_fatal_mutex) != 0) { + fprintf(stderr, "Dimension WARNING: %s, line %u: %s\n", + DMNSN_FUNC, __LINE__, + "Couldn't unlock fatal error handler mutex."); + } +} + +static void +dmnsn_default_fatal_error_fn() +{ + exit(EXIT_FAILURE); +} |