Fix Win32 build. VC++ 6.0 and 7.0 now use the thread-safe code.
authorjake <jake@a5681a0c-68f1-0310-ab6d-d61299d08faa>
Tue, 1 Apr 2003 22:52:23 +0000 (22:52 +0000)
committerjake <jake@a5681a0c-68f1-0310-ab6d-d61299d08faa>
Tue, 1 Apr 2003 22:52:23 +0000 (22:52 +0000)
git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk/program@197 a5681a0c-68f1-0310-ab6d-d61299d08faa

THREADS
bindings/perl-shared/ntmake.pl
src/rrd.dsp
src/rrd.h
src/rrd.vcproj
src/rrd_graph.c
src/rrd_nan_inf.c
src/rrd_not_thread_safe.c
src/rrd_thread_safe_nt.c [new file with mode: 0644]
src/rrd_tool.h
src/rrdtool.dsp

diff --git a/THREADS b/THREADS
index 0dc5cec..152a2c3 100644 (file)
--- a/THREADS
+++ b/THREADS
@@ -54,4 +54,7 @@ thread-safe.
   It uses lots of global vars. You may use it in functions not
   designed to be thread-safe like functions wrapping the _r version of some
   operation (eg. rrd_create, but not in rrd_create_r)
-  
+
+WIN32 Platform Note (added 04/01/03):
+
+Both rrdtool.vcproj (MSVC++ 7.0) and rrd.dsw (MSVC++ 6.0) are configured to compile with rrd_thread_safe_nt.c.
index 75321fd..76eab97 100644 (file)
@@ -14,7 +14,8 @@ WriteMakefile(
    'INC'       => '-I../../src/ -I../../libraries/freetype-2.0.5/include -I ../../libraries/libart_lgpl-2.3.7 -I ../../libraries/zlib-1.1.4 -I ../../libraries/libpng-1.2.0',
    'OPTIMIZE' => '-O2 -MT',
 # change this path to refer to your libc.lib
-    'MYEXTLIB'  => '"$(VCINSTALLDIR)/vc7/lib/libcmt.lib" ../../src/debug/rrd.lib ../../libraries/libart_lgpl-2.3.7/debug/libart.lib ../../libraries/zlib-1.1.4/debug/zlib.lib ../../libraries/libpng-1.2.0/debug/png.lib ../../libraries/freetype-2.0.5/debug/freetype.lib', 
+# keep one line for MSVC++ 6.0 and one for 7.0
+    'MYEXTLIB'  => '"' . $ENV{'MSVCDir'} . '/lib/libc.lib" ../../src/release/rrd.lib ../../libraries/libart_lgpl-2.3.7/release/libart.lib ../../libraries/zlib-1.1.4/release/zlib.lib ../../libraries/libpng-1.2.0/release/png.lib ../../libraries/freetype-2.0.5/release/freetype.lib', 
 #   'MYEXTLIB'  => '"$(VCINSTALLDIR)/vc7/lib/libcmt.lib" ../../src/release/rrd.lib ../../libraries/libart_lgpl-2.3.7/release/libart.lib ../../libraries/zlib-1.1.4/release/zlib.lib ../../libraries/libpng-1.2.0\release\png.lib ../../libraries/freetype-2.0.5/release/freetype.lib', 
     'realclean'    => {FILES => 't/demo?.rrd t/demo?.png' },
     ($] ge '5.005') ? (
index d40a217..38aa7cc 100644 (file)
@@ -160,6 +160,10 @@ SOURCE=.\rrd_last.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\rrd_nan_inf.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\rrd_open.c
 # End Source File
 # Begin Source File
@@ -176,6 +180,10 @@ SOURCE=.\rrd_rpncalc.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\rrd_thread_safe_nt.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\rrd_tune.c
 # End Source File
 # Begin Source File
index bdcc720..078e29e 100644 (file)
--- a/src/rrd.h
+++ b/src/rrd.h
@@ -5,6 +5,9 @@
  *****************************************************************************
  * $Id$
  * $Log$
+ * Revision 1.4  2003/04/01 22:52:23  jake
+ * Fix Win32 build. VC++ 6.0 and 7.0 now use the thread-safe code.
+ *
  * Revision 1.3  2003/02/13 07:05:27  oetiker
  * Find attached the patch I promised to send to you. Please note that there
  * are three new source files (src/rrd_is_thread_safe.h, src/rrd_thread_safe.c
@@ -62,7 +65,7 @@ int    rrd_create_r(char *filename,
                    int argc, char **argv);
 /* NOTE: rrd_update_r is only thread-safe if no at-style time
    specifications get used!!! */
-int    rrd_update_r(char *filename, char *template,
+int    rrd_update_r(char *filename, char *_template,
                    int argc, char **argv);
 int    rrd_dump_r(char *filename);
 time_t rrd_last_r(char *filename);
index c1b0584..3c141fc 100644 (file)
@@ -65,7 +65,7 @@
                                Optimization="0"
                                AdditionalIncludeDirectories="..\libraries\libpng-1.2.0,..\libraries\zlib-1.1.4,..\libraries\libart_lgpl-2.3.7,..\libraries\freetype-2.0.5\include"
                                PreprocessorDefinitions="WIN32,_DEBUG,_CONSOLE,_CTYPE_DISABLE_MACROS"
-                               RuntimeLibrary="4"
+                               RuntimeLibrary="1"
                                PrecompiledHeaderFile=".\debug/rrd.pch"
                                AssemblerListingLocation=".\debug/"
                                ObjectFile=".\debug/"
                        RelativePath=".\rrd_last.c">
                </File>
                <File
+                       RelativePath="rrd_nan_inf.c">
+               </File>
+               <File
                        RelativePath=".\rrd_open.c">
                </File>
                <File
                        RelativePath=".\rrd_rpncalc.c">
                </File>
                <File
+                       RelativePath="rrd_thread_safe_nt.c">
+               </File>
+               <File
                        RelativePath=".\rrd_tune.c">
                </File>
                <File
index 715f0dc..e47c412 100644 (file)
@@ -29,7 +29,7 @@
 
 #ifndef RRD_DEFAULT_FONT
 #ifdef WIN32
-#define RRD_DEFAULT_FONT "c:/winnt/fonts/COUR.TTF"
+/* this is set in confignt/config.h */
 #else
 #define RRD_DEFAULT_FONT "/usr/share/fonts/truetype/openoffice/ariosor.ttf" 
 /* #define RRD_DEFAULT_FONT "/usr/share/fonts/truetype/Arial.ttf" */
index 9fc3b61..ce0873e 100644 (file)
@@ -2,6 +2,8 @@
 
 #if defined(WIN32)
 
+#include <math.h>
+
 double set_to_DNAN(void) { return (double)fmod(0.0,0.0); }
 double set_to_DINF(void) { return (double)fabs((double)log(0.0)); }
 
index 13160e6..8cdc00e 100644 (file)
@@ -13,6 +13,7 @@
 #include "rrd_tool.h"
 #define MAXLEN 4096
 #define ERRBUFLEN 256
+
 static char rrd_error[MAXLEN] = "\0";
 static char rrd_liberror[ERRBUFLEN] = "\0";
 /* The global context is very useful in the transition period to even
diff --git a/src/rrd_thread_safe_nt.c b/src/rrd_thread_safe_nt.c
new file mode 100644 (file)
index 0000000..337a994
--- /dev/null
@@ -0,0 +1,141 @@
+/*****************************************************************************
+ * RRDtool 1.1.x  Copyright Tobias Oetiker, 1997 - 2002
+ * This file:     Copyright 2003 Peter Stamfest <peter@stamfest.at> 
+ *                             & Tobias Oetiker
+ * Distributed under the GPL
+ *****************************************************************************
+ * rrd_thread_safe.c   Contains routines used when thread safety is required
+ *                     for win32
+ *****************************************************************************
+ * $Id$
+ *************************************************************************** */
+
+#include <windows.h>
+#include <string.h>
+/* #include <error.h> */
+#include "rrd.h"
+#include "rrd_tool.h"
+
+/* Key for the thread-specific rrd_context */
+static DWORD context_key;
+static CRITICAL_SECTION CriticalSection; 
+
+
+/* Once-only initialisation of the key */
+static DWORD context_key_once = 0;
+
+
+/* Free the thread-specific rrd_context - we might actually use
+   rrd_free_context instead...
+ */
+static void context_destroy_context(void)
+{
+       DeleteCriticalSection(&CriticalSection);
+    TlsFree(context_key);
+       context_key_once=0;
+}
+static void context_init_context(void)
+{
+       if (!InterlockedExchange(&context_key_once, 1)) {
+               context_key = TlsAlloc();
+               InitializeCriticalSection(&CriticalSection);
+               atexit(context_destroy_context);
+       }
+}
+struct rrd_context *rrd_get_context(void) {
+    struct rrd_context *ctx;
+               
+       context_init_context();
+    ctx = TlsGetValue(context_key);
+    if (!ctx) {
+               ctx = rrd_new_context();
+               TlsSetValue(context_key, ctx);
+    } 
+    return ctx;
+}
+#undef strerror
+const char *rrd_strerror(int err) {
+    struct rrd_context *ctx;
+       context_init_context();
+
+       ctx = rrd_get_context();
+
+    EnterCriticalSection(&CriticalSection); 
+    strncpy(ctx->lib_errstr, strerror(err), ctx->errlen);
+       LeaveCriticalSection(&CriticalSection); 
+
+    return ctx->lib_errstr;
+}
+/*
+ * there much be a re-entrant version of these somewhere in win32 land
+ */
+struct tm* localtime_r(const time_t *timep, struct tm* result)
+{
+       struct tm *local;
+       context_init_context();
+
+       EnterCriticalSection(&CriticalSection);
+       local = localtime(timep);
+       memcpy(result,local,sizeof(struct tm));
+       LeaveCriticalSection(&CriticalSection);
+       return result;
+}
+char* ctime_r(const time_t *timep, char* result)
+{
+       char *local;
+       context_init_context();
+
+       EnterCriticalSection(&CriticalSection);
+       local = ctime(timep);
+       strcpy(result,local);
+       LeaveCriticalSection(&CriticalSection);
+       return result;
+}
+
+struct tm* gmtime_r(const time_t *timep, struct tm* result)
+{
+       struct tm *local;
+       context_init_context();
+
+       EnterCriticalSection(&CriticalSection);
+       local = gmtime(timep);
+       memcpy(result,local,sizeof(struct tm));
+       LeaveCriticalSection(&CriticalSection);
+       return result;
+}
+
+/* implementation from Apache's APR library */
+char *strtok_r(char *str, const char *sep, char **last)
+{
+    char *token;
+       context_init_context();
+
+
+    if (!str)           /* subsequent call */
+        str = *last;    /* start where we left off */
+
+    /* skip characters in sep (will terminate at '\0') */
+    while (*str && strchr(sep, *str))
+        ++str;
+
+    if (!*str)          /* no more tokens */
+        return NULL;
+
+    token = str;
+
+    /* skip valid token characters to terminate token and
+     * prepare for the next call (will terminate at '\0) 
+     */
+    *last = token + 1;
+    while (**last && !strchr(sep, **last))
+        ++*last;
+
+    if (**last) {
+        **last = '\0';
+        ++*last;
+    }
+
+    return token;
+}
+
index 6d7652b..16bd4f2 100644 (file)
@@ -110,6 +110,10 @@ int isnan(double value);
 #define isnan _isnan
 #define finite _finite
 #define isinf(a) (_fpclass(a) == _FPCLASS_NINF || _fpclass(a) == _FPCLASS_PINF)
+struct tm* localtime_r(const time_t *timep, struct tm* result);
+char* ctime_r(const time_t *timep, char* result);
+struct tm* gmtime_r(const time_t *timep, struct tm* result);
+char *strtok_r(char *str, const char *sep, char **last);
 #endif
 
 /* local include files -- need to be after the system ones */
index ecffcc7..3f24fd8 100644 (file)
@@ -42,7 +42,7 @@ RSC=rc.exe
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /I "..\libraries\libpng-1.2.0" /I "..\libraries\zlib-1.1.4" /I "..\libraries\libart_lgpl-2.3.7" /I "..\libraries\freetype-2.0.5\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_CTYPE_DISABLE_MACROS" /FD /c
+# ADD CPP /nologo /MT /W3 /GX /I "..\libraries\libpng-1.2.0" /I "..\libraries\zlib-1.1.4" /I "..\libraries\libart_lgpl-2.3.7" /I "..\libraries\freetype-2.0.5\include" /D "NDEBUG" /D "_WINDOWS" /D "WIN32" /D "_MBCS" /D "_CTYPE_DISABLE_MACROS" /D MAKE_TIMESTAMP=\"WIN32\" /FD /c
 # SUBTRACT CPP /YX
 # ADD BASE RSC /l 0x100c /d "NDEBUG"
 # ADD RSC /l 0x100c /d "NDEBUG"
@@ -67,7 +67,7 @@ LINK32=link.exe
 # PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\libraries\libpng-1.2.0" /I "..\libraries\zlib-1.1.4" /I "..\libraries\libart_lgpl-2.3.7" /I "..\libraries\freetype-2.0.5\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "_CTYPE_DISABLE_MACROS" /FR /FD /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\libraries\libpng-1.2.0" /I "..\libraries\zlib-1.1.4" /I "..\libraries\libart_lgpl-2.3.7" /I "..\libraries\freetype-2.0.5\include" /D "_DEBUG" /D "_CONSOLE" /D "WIN32" /D "_MBCS" /D "_CTYPE_DISABLE_MACROS" /D MAKE_TIMESTAMP=\"WIN32\" /FR /FD /c
 # SUBTRACT CPP /YX
 # ADD BASE RSC /l 0x100c /d "_DEBUG"
 # ADD RSC /l 0x100c /d "_DEBUG"