Updates for Windows WRT timing and condition vars
authorAdam Dickmeiss <adam@indexdata.dk>
Wed, 28 Apr 2010 11:11:16 +0000 (13:11 +0200)
committerAdam Dickmeiss <adam@indexdata.dk>
Wed, 28 Apr 2010 11:11:16 +0000 (13:11 +0200)
include/yaz/gettimeofday.h [new file with mode: 0644]
include/yaz/mutex.h
src/gettimeofday.c [new file with mode: 0644]
src/mutex.c
test/test_mutex.c
win/makefile

diff --git a/include/yaz/gettimeofday.h b/include/yaz/gettimeofday.h
new file mode 100644 (file)
index 0000000..f7b0c68
--- /dev/null
@@ -0,0 +1,59 @@
+/* This file is part of the YAZ toolkit.
+ * Copyright (C) 1995-2010 Index Data.
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Index Data nor the names of its contributors
+ *       may be used to endorse or promote products derived from this
+ *       software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file gettimeofday.h
+ * \brief Header for gettimeofday wrapper
+ */
+#ifndef YAZ_GETTIMEOFDAY_H
+#define YAZ_GETTIMEOFDAY_H
+
+#include <time.h>
+#include <yaz/yconfig.h>
+
+YAZ_BEGIN_CDECL
+
+/** \brief gettimeofday
+    \param tval timeval for resulting time
+
+    Semantics like gettimeofday.
+*/
+YAZ_EXPORT
+int yaz_gettimeofday(struct timeval *tval);
+
+YAZ_END_CDECL
+
+#endif
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * c-file-style: "Stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
+
index d7f2c6d..5787ec6 100644 (file)
@@ -84,6 +84,7 @@ YAZ_EXPORT void yaz_mutex_destroy(YAZ_MUTEX *mutexp);
     This function should be called after a MUTEX is created but before
     it is used for locking.
  */
+YAZ_EXPORT
 void yaz_mutex_set_name(YAZ_MUTEX mutex, int log_level, const char *name);
 
 /** \brief creates condition variable
@@ -92,13 +93,14 @@ void yaz_mutex_set_name(YAZ_MUTEX mutex, int log_level, const char *name);
     Upon successful completion *p holds the condition handle; *p = 0
     on error.
 */
-void yaz_cond_create(YAZ_COND *p);
+YAZ_EXPORT void yaz_cond_create(YAZ_COND *p);
 
 /** \brief destroys condition variable
     \param p reference to condition handle
     
     Upon completion *p holds 0.
 */
+YAZ_EXPORT
 void yaz_cond_destroy(YAZ_COND *p);
 
 /** \brief waits for condition
@@ -108,16 +110,19 @@ void yaz_cond_destroy(YAZ_COND *p);
 
     Semantics like pthread_cond_wait.
 */
-int yaz_cond_wait(YAZ_COND p, YAZ_MUTEX m, const struct timespec *abstime);
+YAZ_EXPORT
+int yaz_cond_wait(YAZ_COND p, YAZ_MUTEX m, const struct timeval *abstime);
 
 /** \brief unblock one thread waiting for block
     \param p condition variable handle
 */
+YAZ_EXPORT
 int yaz_cond_signal(YAZ_COND p);
 
 /** \brief unblock all threads waiting for block
     \param p condition variable handle
 */
+YAZ_EXPORT
 int yaz_cond_broadcast(YAZ_COND p);
 
 YAZ_END_CDECL
diff --git a/src/gettimeofday.c b/src/gettimeofday.c
new file mode 100644 (file)
index 0000000..c14c36e
--- /dev/null
@@ -0,0 +1,47 @@
+/* This file is part of the YAZ toolkit.
+ * Copyright (C) 1995-2010 Index Data
+ * See the file LICENSE for details.
+ */
+
+/**
+ * \file gettimeofday.c
+ * \brief Implements wrapper for gettimeofday
+ *
+ */
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef WIN32
+#include <windows.h>
+#include <sys/timeb.h>
+#endif
+#include <time.h>
+#include <yaz/gettimeofday.h>
+
+int yaz_gettimeofday(struct timeval *tval)
+{
+#ifdef WIN32
+    struct _timeb timeb;
+    _ftime(&timeb);
+    tval->tv_sec = timeb.time;
+    tval->tv_usec = timeb.millitm * 1000;
+    return 0;
+#else
+    return gettimeofday(tval, 0);
+#endif
+}
+
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * c-file-style: "Stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
+
index 7ff23ed..6b80fe5 100644 (file)
 #include <yaz/nmem.h>
 #include <yaz/log.h>
 #include <yaz/mutex.h>
-
+#include <yaz/gettimeofday.h>
 #ifdef WIN32
 #include <windows.h>
+#include <sys/timeb.h>
 #endif
+#include <time.h>
 
 #if HAVE_SYS_TIME_H
 #include <sys/time.h>
@@ -46,7 +48,7 @@ struct yaz_mutex {
 
 struct yaz_cond {
 #ifdef WIN32
-
+    CONDITION_VARIABLE cond;
 #elif YAZ_POSIX_THREADS
     pthread_cond_t cond;
 #endif
@@ -170,6 +172,7 @@ void yaz_cond_create(YAZ_COND *p)
 {
     *p = (YAZ_COND) malloc(sizeof(**p));
 #ifdef WIN32
+    InitializeConditionVariable(&(*p)->cond);
 #elif YAZ_POSIX_THREADS
     pthread_cond_init(&(*p)->cond, 0);
 #endif
@@ -188,13 +191,30 @@ void yaz_cond_destroy(YAZ_COND *p)
     }
 }
 
-int yaz_cond_wait(YAZ_COND p, YAZ_MUTEX m, const struct timespec *abstime)
+int yaz_cond_wait(YAZ_COND p, YAZ_MUTEX m, const struct timeval *abstime)
 {
 #ifdef WIN32
-    return -1;
+    if (abstime)
+    {
+        struct timeval tval_now;
+        int sec, msec;
+
+        yaz_gettimeofday(&tval_now);
+
+        sec = abstime->tv_sec - tval_now.tv_sec;
+        msec = (abstime->tv_usec - tval_now.tv_usec) / 1000;
+        return SleepConditionVariableCS(&p->cond, &m->handle, sec*1000 + msec);
+    }
+    else
+        return SleepConditionVariableCS(&p->cond, &m->handle, INFINITE);
 #elif YAZ_POSIX_THREADS
     if (abstime)
-        return pthread_cond_timedwait(&p->cond, &m->handle, abstime);
+    {
+        struct timespec s;
+        s.tv_sec = abstime->tv_sec;
+        s.tv_nsec = abstime->tv_usec * 1000;
+        return pthread_cond_timedwait(&p->cond, &m->handle, &s);
+    }
     else
         return pthread_cond_wait(&p->cond, &m->handle);
 #else
@@ -205,7 +225,8 @@ int yaz_cond_wait(YAZ_COND p, YAZ_MUTEX m, const struct timespec *abstime)
 int yaz_cond_signal(YAZ_COND p)
 {
 #ifdef WIN32
-    return -1;
+    WakeConditionVariable(&p->cond);
+    return 0;
 #elif YAZ_POSIX_THREADS
     return pthread_cond_signal(&p->cond);
 #else
@@ -216,7 +237,8 @@ int yaz_cond_signal(YAZ_COND p)
 int yaz_cond_broadcast(YAZ_COND p)
 {
 #ifdef WIN32
-    return -1;
+    WakeAllConditionVariable(&p->cond);
+    return 0;
 #elif YAZ_POSIX_THREADS
     return pthread_cond_broadcast(&p->cond);
 #else
index 9cef383..52853b1 100644 (file)
@@ -7,9 +7,16 @@
 #include <stdio.h>
 
 #include <yaz/mutex.h>
+#if HAVE_SYS_TIME_H
 #include <sys/time.h>
+#endif
+#ifdef WIN32
+#include <windows.h>
+#endif
+
 #include <yaz/test.h>
 #include <yaz/log.h>
+#include <yaz/gettimeofday.h>
 
 static void tst_mutex(void)
 {
@@ -37,8 +44,7 @@ static void tst_cond(void)
 {
     YAZ_MUTEX p = 0;
     YAZ_COND c;
-    struct timespec abstime;
-    struct timeval tval;
+    struct timeval abstime;
     int r;
 
     yaz_mutex_create(&p);
@@ -51,11 +57,10 @@ static void tst_cond(void)
     if (!c)
         return;
 
-    r = gettimeofday(&tval, 0);
+    r = yaz_gettimeofday(&abstime);
     YAZ_CHECK_EQ(r, 0);
     
-    abstime.tv_sec = tval.tv_sec + 1; /* wait 2 seconds */
-    abstime.tv_nsec = tval.tv_usec * 1000;
+    abstime.tv_sec += 1; /* wait 1 second */
     
     r = yaz_cond_wait(c, p, &abstime);
     YAZ_CHECK(r != 0);
index 83e3bcb..0afd57a 100644 (file)
@@ -122,6 +122,7 @@ YAZ_MARCDUMP=$(BINDIR)\yaz-marcdump.exe
 
 TSTLOG=$(BINDIR)\test_log.exe
 TST_TIMING=$(BINDIR)\test_timing.exe
+TEST_MUTEX=$(BINDIR)\test_mutex.exe
 
 # shortcut names defined here
 dll: dirs generate $(YAZ_DLL) 
@@ -135,7 +136,7 @@ zoomsh: $(ZOOMSH) $(ZOOMTST1) $(ZOOMTST2) $(ZOOMTST3) \
  $(ZOOMTST10)
 
 utilprog: $(CQL2PQF) $(CQL2XCQL) $(YAZ_MARCDUMP) 
-testprog: $(TSTLOG) $(TST_TIMING)
+testprog: $(TSTLOG) $(TST_TIMING) $(TEST_MUTEX)
 
 htmlhelp: $(DOCDIR)\htmlhelp.chm
 
@@ -371,6 +372,9 @@ TSTLOG_OBJS = \
 TST_TIMING_OBJS = \
    $(OBJDIR)\test_timing.obj
 
+TEST_MUTEX_OBJS = \
+   $(OBJDIR)\test_mutex.obj
+
 MISC_OBJS= \
    $(OBJDIR)\version.obj \
    $(OBJDIR)\oid_std.obj \
@@ -495,10 +499,12 @@ MISC_OBJS= \
    $(OBJDIR)\iconv_decode_iso5426.obj \
    $(OBJDIR)\iconv_decode_danmarc.obj \
    $(OBJDIR)\mutex.obj \
+   $(OBJDIR)\gettimeofday.obj \
    $(OBJDIR)\json.obj \
    $(OBJDIR)\sc.obj \
    $(OBJDIR)\xml_include.obj \
    $(OBJDIR)\file_glob.obj \
+   $(OBJDIR)\thread_id.obj \
    $(OBJDIR)\dirent.obj
 
 Z3950_OBJS= \
@@ -919,6 +925,10 @@ $(TST_TIMING) : "$(BINDIR)" $(TST_TIMING_OBJS) $(YAZ_DLL)
        $(LINK_PROGRAM) $(TST_TIMING_OBJS) /out:$@
        $(MT) -manifest $@.manifest -outputresource:$@;1
 
+$(TEST_MUTEX) : "$(BINDIR)" $(TEST_MUTEX_OBJS) $(YAZ_DLL)
+       $(LINK_PROGRAM) $(TEST_MUTEX_OBJS) /out:$@
+       $(MT) -manifest $@.manifest -outputresource:$@;1
+
 # Other rules
 
 $(DOCDIR)\htmlhelp.chm: $(DOCDIR)\htmlhelp.hhp