1 /*****************************************************************************
2 * RRDtool 1.3.1 Copyright by Tobi Oetiker, 1997-2008
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
9 *****************************************************************************
11 *************************************************************************** */
15 /* #include <error.h> */
19 /* Key for the thread-specific rrd_context */
20 static DWORD context_key;
21 static CRITICAL_SECTION CriticalSection;
24 /* Once-only initialisation of the key */
25 static DWORD context_key_once = 0;
28 /* Free the thread-specific rrd_context - we might actually use
29 rrd_free_context instead...
31 static void context_destroy_context(
34 DeleteCriticalSection(&CriticalSection);
38 static void context_init_context(
41 if (!InterlockedExchange(&context_key_once, 1)) {
42 context_key = TlsAlloc();
43 InitializeCriticalSection(&CriticalSection);
44 atexit(context_destroy_context);
47 rrd_context_t *rrd_get_context(
52 context_init_context();
54 ctx = TlsGetValue(context_key);
56 ctx = rrd_new_context();
57 TlsSetValue(context_key, ctx);
63 const char *rrd_strerror(
68 context_init_context();
70 ctx = rrd_get_context();
72 EnterCriticalSection(&CriticalSection);
73 strncpy(ctx->lib_errstr, strerror(err), sizeof(ctx->lib_errstr));
74 ctx->lib_errstr[sizeof(ctx->lib_errstr) - 1] = '\0';
75 LeaveCriticalSection(&CriticalSection);
77 return ctx->lib_errstr;
81 * there much be a re-entrant version of these somewhere in win32 land
83 struct tm *localtime_r(
89 context_init_context();
91 EnterCriticalSection(&CriticalSection);
92 local = localtime(timep);
93 memcpy(result, local, sizeof(struct tm));
94 LeaveCriticalSection(&CriticalSection);
104 context_init_context();
106 EnterCriticalSection(&CriticalSection);
107 local = ctime(timep);
108 strcpy(result, local);
109 LeaveCriticalSection(&CriticalSection);
119 context_init_context();
121 EnterCriticalSection(&CriticalSection);
122 local = gmtime(timep);
123 memcpy(result, local, sizeof(struct tm));
124 LeaveCriticalSection(&CriticalSection);
128 /* implementation from Apache's APR library */
136 context_init_context();
139 if (!str) /* subsequent call */
140 str = *last; /* start where we left off */
142 /* skip characters in sep (will terminate at '\0') */
143 while (*str && strchr(sep, *str))
146 if (!*str) /* no more tokens */
151 /* skip valid token characters to terminate token and
152 * prepare for the next call (will terminate at '\0)
155 while (**last && !strchr(sep, **last))