Code

Imported upstream version 1.3.5.
[pkg-rrdtool.git] / src / rrd_thread_safe.c
1 /*****************************************************************************
2  * RRDtool 1.3.5  Copyright by Tobi Oetiker, 1997-2008
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: rrd_thread_safe.c 1710 2008-12-15 22:06:22Z oetiker $
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(
28     void *ctx_)
29 {
30     rrd_context_t *ctx = ctx_;
32     if (ctx)
33         rrd_free_context(ctx);
34 }
36 /* Allocate the key */
37 static void context_get_key(
38     void)
39 {
40     pthread_key_create(&context_key, context_destroy_context);
41 }
43 rrd_context_t *rrd_get_context(
44     void)
45 {
46     rrd_context_t *ctx;
48     pthread_once(&context_key_once, context_get_key);
49     ctx = pthread_getspecific(context_key);
50     if (!ctx) {
51         ctx = rrd_new_context();
52         pthread_setspecific(context_key, ctx);
53     }
54     return ctx;
55 }
57 #ifdef HAVE_STRERROR_R
58 const char *rrd_strerror(
59     int err)
60 {
61     rrd_context_t *ctx = rrd_get_context();
63     if (strerror_r(err, ctx->lib_errstr, sizeof(ctx->lib_errstr)))
64         return "strerror_r failed. sorry!";
65     else
66         return ctx->lib_errstr;
67 }
68 #else
69 #undef strerror
70 const char *rrd_strerror(
71     int err)
72 {
73     static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
74     rrd_context_t *ctx;
76     ctx = rrd_get_context();
77     pthread_mutex_lock(&mtx);
78     strncpy(ctx->lib_errstr, strerror(err), sizeof(ctx->lib_errstr));
79     ctx->lib_errstr[sizeof(ctx->lib_errstr) - 1] = '\0';
80     pthread_mutex_unlock(&mtx);
81     return ctx->lib_errstr;
82 }
83 #endif