1 /*****************************************************************************
2 * RRDtool 1.2.13 Copyright by Tobi Oetiker, 1997-2006
3 * This file: Copyright 2003 Peter Stamfest <peter@stamfest.at>
4 * & Tobias Oetiker
5 * Distributed under the GPL
6 *****************************************************************************
7 * rrd_thread_safe.c Contains routines used when thread safety is required
8 *****************************************************************************
9 * $Id$
10 *************************************************************************** */
12 #include <pthread.h>
13 #include <string.h>
14 /* #include <error.h> */
15 #include "rrd.h"
16 #include "rrd_tool.h"
18 /* Key for the thread-specific rrd_context */
19 static pthread_key_t context_key;
21 /* Once-only initialisation of the key */
22 static pthread_once_t context_key_once = PTHREAD_ONCE_INIT;
24 /* Free the thread-specific rrd_context - we might actually use
25 rrd_free_context instead...
26 */
27 static void context_destroy_context(void *ctx_)
28 {
29 struct rrd_context *ctx = ctx_;
30 if (ctx) rrd_free_context(ctx);
31 }
33 /* Allocate the key */
34 static void context_get_key()
35 {
36 pthread_key_create(&context_key, context_destroy_context);
37 }
39 struct rrd_context *rrd_get_context(void) {
40 struct rrd_context *ctx;
42 pthread_once(&context_key_once, context_get_key);
43 ctx = pthread_getspecific(context_key);
44 if (!ctx) {
45 ctx = rrd_new_context();
46 pthread_setspecific(context_key, ctx);
47 }
48 return ctx;
49 }
51 #ifdef HAVE_STRERROR_R
52 const char *rrd_strerror(int err) {
53 struct rrd_context *ctx = rrd_get_context();
54 return strerror_r(err, ctx->lib_errstr, ctx->errlen);
55 }
56 #else
57 #undef strerror
58 const char *rrd_strerror(int err) {
59 static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
60 struct rrd_context *ctx;
61 ctx = rrd_get_context();
62 pthread_mutex_lock(&mtx);
63 strncpy(ctx->lib_errstr, strerror(err), ctx->errlen);
64 pthread_mutex_unlock(&mtx);
65 return ctx->lib_errstr;
66 }
67 #endif