1 /*****************************************************************************
2 * RRDtool 1.2.23 Copyright by Tobi Oetiker, 1997-2007
3 * This file: Copyright 2003 Peter Stamfest <peter@stamfest.at>
5 * Distributed under the GPL
6 *****************************************************************************
7 * rrd_thread_safe.c Contains routines used when thread safety is required
8 *****************************************************************************
10 *************************************************************************** */
14 /* #include <error.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...
27 static void context_destroy_context(
30 struct rrd_context *ctx = ctx_;
33 rrd_free_context(ctx);
36 /* Allocate the key */
37 static void context_get_key(
40 pthread_key_create(&context_key, context_destroy_context);
43 struct rrd_context *rrd_get_context(
46 struct rrd_context *ctx;
48 pthread_once(&context_key_once, context_get_key);
49 ctx = pthread_getspecific(context_key);
51 ctx = rrd_new_context();
52 pthread_setspecific(context_key, ctx);
57 #ifdef HAVE_STRERROR_R
58 const char *rrd_strerror(
61 struct rrd_context *ctx = rrd_get_context();
63 if (strerror_r(err, ctx->lib_errstr, ctx->errlen))
64 return "strerror_r failed. sorry!";
66 return ctx->lib_errstr;
70 const char *rrd_strerror(
73 static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
74 struct rrd_context *ctx;
76 ctx = rrd_get_context();
77 pthread_mutex_lock(&mtx);
78 strncpy(ctx->lib_errstr, strerror(err), ctx->errlen);
79 ctx->lib_errstr[ctx->errlen] = '\0';
80 pthread_mutex_unlock(&mtx);
81 return ctx->lib_errstr;