Code

Imported upstream version 1.3rc4.
[pkg-rrdtool.git] / src / rrd_thread_safe_nt.c
1 /*****************************************************************************
2  * RRDtool 1.3rc4  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  *                     for win32
9  *****************************************************************************
10  * $Id: rrd_thread_safe_nt.c 1366 2008-05-18 13:06:44Z oetiker $
11  *************************************************************************** */
13 #include <windows.h>
14 #include <string.h>
15 /* #include <error.h> */
16 #include "rrd.h"
17 #include "rrd_tool.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...
30  */
31 static void context_destroy_context(
32     void)
33 {
34     DeleteCriticalSection(&CriticalSection);
35     TlsFree(context_key);
36     context_key_once = 0;
37 }
38 static void context_init_context(
39     void)
40 {
41     if (!InterlockedExchange(&context_key_once, 1)) {
42         context_key = TlsAlloc();
43         InitializeCriticalSection(&CriticalSection);
44         atexit(context_destroy_context);
45     }
46 }
47 struct rrd_context *rrd_get_context(
48     void)
49 {
50     struct rrd_context *ctx;
52     context_init_context();
54     ctx = TlsGetValue(context_key);
55     if (!ctx) {
56         ctx = rrd_new_context();
57         TlsSetValue(context_key, ctx);
58     }
59     return ctx;
60 }
62 #undef strerror
63 const char *rrd_strerror(
64     int err)
65 {
66     struct rrd_context *ctx;
68     context_init_context();
70     ctx = rrd_get_context();
72     EnterCriticalSection(&CriticalSection);
73     strncpy(ctx->lib_errstr, strerror(err), ctx->errlen);
74     ctx->lib_errstr[ctx->errlen] = '\0';
75     LeaveCriticalSection(&CriticalSection);
77     return ctx->lib_errstr;
78 }
80 /*
81  * there much be a re-entrant version of these somewhere in win32 land
82  */
83 struct tm *localtime_r(
84     const time_t *timep,
85     struct tm *result)
86 {
87     struct tm *local;
89     context_init_context();
91     EnterCriticalSection(&CriticalSection);
92     local = localtime(timep);
93     memcpy(result, local, sizeof(struct tm));
94     LeaveCriticalSection(&CriticalSection);
95     return result;
96 }
98 char     *ctime_r(
99     const time_t *timep,
100     char *result)
102     char     *local;
104     context_init_context();
106     EnterCriticalSection(&CriticalSection);
107     local = ctime(timep);
108     strcpy(result, local);
109     LeaveCriticalSection(&CriticalSection);
110     return result;
113 struct tm *gmtime_r(
114     const time_t *timep,
115     struct tm *result)
117     struct tm *local;
119     context_init_context();
121     EnterCriticalSection(&CriticalSection);
122     local = gmtime(timep);
123     memcpy(result, local, sizeof(struct tm));
124     LeaveCriticalSection(&CriticalSection);
125     return result;
128 /* implementation from Apache's APR library */
129 char     *strtok_r(
130     char *str,
131     const char *sep,
132     char **last)
134     char     *token;
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))
144         ++str;
146     if (!*str)          /* no more tokens */
147         return NULL;
149     token = str;
151     /* skip valid token characters to terminate token and
152      * prepare for the next call (will terminate at '\0) 
153      */
154     *last = token + 1;
155     while (**last && !strchr(sep, **last))
156         ++ * last;
158     if (**last) {
159         **last = '\0';
160         ++*last;
161     }
163     return token;