1 /*****************************************************************************
2 * RRDtool 1.4.3 Copyright by Tobi Oetiker, 1997-2010
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((LONG*)(&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 = (rrd_context_t*)TlsGetValue(context_key);
56 ctx = rrd_new_context();
57 TlsSetValue(context_key, ctx);
63 /* this was added by the win32 porters Christof.Wegmann@exitgames.com */
65 rrd_context_t *rrd_force_new_context(
70 context_init_context();
72 ctx = rrd_new_context();
73 TlsSetValue(context_key, ctx);
80 const char *rrd_strerror(
85 context_init_context();
87 ctx = rrd_get_context();
89 EnterCriticalSection(&CriticalSection);
90 strncpy(ctx->lib_errstr, strerror(err), sizeof(ctx->lib_errstr));
91 ctx->lib_errstr[sizeof(ctx->lib_errstr) - 1] = '\0';
92 LeaveCriticalSection(&CriticalSection);
94 return ctx->lib_errstr;
98 * there much be a re-entrant version of these somewhere in win32 land
100 struct tm *localtime_r(
106 context_init_context();
108 EnterCriticalSection(&CriticalSection);
109 local = localtime(timep);
110 memcpy(result, local, sizeof(struct tm));
111 LeaveCriticalSection(&CriticalSection);
121 context_init_context();
123 EnterCriticalSection(&CriticalSection);
124 local = ctime(timep);
125 strcpy(result, local);
126 LeaveCriticalSection(&CriticalSection);
136 context_init_context();
138 EnterCriticalSection(&CriticalSection);
139 local = gmtime(timep);
140 memcpy(result, local, sizeof(struct tm));
141 LeaveCriticalSection(&CriticalSection);
145 /* implementation from Apache's APR library */
153 context_init_context();
156 if (!str) /* subsequent call */
157 str = *last; /* start where we left off */
159 /* skip characters in sep (will terminate at '\0') */
160 while (*str && strchr(sep, *str))
163 if (!*str) /* no more tokens */
168 /* skip valid token characters to terminate token and
169 * prepare for the next call (will terminate at '\0)
172 while (**last && !strchr(sep, **last))