]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
windows threads. detect gdi32. nicer DISABLED_THREADS define. Compiles on mingw32.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Mon, 16 Jun 2008 13:39:46 +0000 (13:39 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Mon, 16 Jun 2008 13:39:46 +0000 (13:39 +0000)
git-svn-id: file:///svn/unbound/trunk@1122 be551aaa-1e26-0410-a405-d3ace91eadb9

configure
configure.ac
daemon/daemon.c
doc/Changelog
libunbound/libunbound.c
libunbound/libworker.c
testcode/asynclook.c
util/locks.c
util/locks.h
util/storage/lruhash.c

index 795767f20f772cea2c89fc10a76e443c6d7a2bb0..b6a14d78ac864c8abdcd4f49c38523bd30a9682d 100755 (executable)
--- a/configure
+++ b/configure
@@ -19738,10 +19738,58 @@ _ACEOF
 
 else
 
+               # check if -lwsock32 or -lgdi32 are needed.
+               LIBS="$LIBS -lcrypto -lgdi32"
+               echo "$as_me:$LINENO: checking if -lcrypto needs -lgdi32" >&5
+echo $ECHO_N "checking if -lcrypto needs -lgdi32... $ECHO_C" >&6
+               cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+       void HMAC_CTX_init(void);
+       (void)HMAC_CTX_init();
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+                   echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+                   echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
                     { { echo "$as_me:$LINENO: error: OpenSSL found in $ssldir, but version 0.9.7 or higher is required" >&5
 echo "$as_me: error: OpenSSL found in $ssldir, but version 0.9.7 or higher is required" >&2;}
    { (exit 1); exit 1; }; }
 
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+
 fi
 
         fi
@@ -23172,7 +23220,6 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
   (exit $ac_status); }; }; then
   ac_cv_func_getaddrinfo="yes"
-LDFLAGS="$LDFLAGS -lws2_32"
 
 else
   echo "$as_me: failed program was:" >&5
index 948a7c8be4d404a543bbb085f4bd595ac5d7ea52..eaab37d855bdf0f34ee2b1fd49b5e5840cd9d2c6 100644 (file)
@@ -511,8 +511,18 @@ AC_ARG_WITH(ssl, AC_HELP_STRING([--with-ssl=pathname],
                RUNTIME_PATH="$RUNTIME_PATH -R$ssldir/lib"
            fi
             AC_CHECK_LIB(crypto, HMAC_CTX_init,, [
+               # check if -lwsock32 or -lgdi32 are needed.     
+               LIBS="$LIBS -lcrypto -lgdi32"
+               AC_MSG_CHECKING([if -lcrypto needs -lgdi32])
+               AC_TRY_COMPILE([], [
+       void HMAC_CTX_init(void);
+       (void)HMAC_CTX_init();
+               ], [
+                   AC_MSG_RESULT(yes) ],[
+                   AC_MSG_RESULT(no)
                     AC_MSG_ERROR([OpenSSL found in $ssldir, but version 0.9.7 or higher is required])
-                ])
+               ])
+            ])
         fi
         AC_SUBST(HAVE_SSL)
        AC_SUBST(RUNTIME_PATH)
@@ -726,7 +736,7 @@ AC_LANG_PROGRAM(
 ]
 ),
 [ac_cv_func_getaddrinfo="yes"
-LDFLAGS="$LDFLAGS -lws2_32"
+dnl already: LIBS="$LIBS -lws2_32"
 ],
 [ac_cv_func_getaddrinfo="no"
 LIBS="$ORIGLIBS"
index f235f76fa4f7be5af8a520938b6615fc92f82291..7a83cd7080aec0d8a48c9584ef9cace2c8fa10a3 100644 (file)
@@ -303,7 +303,7 @@ thread_start(void* arg)
        struct worker* worker = (struct worker*)arg;
        log_thread_set(&worker->thread_num);
        ub_thread_blocksigs();
-#if !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS)
+#ifdef THREADS_DISABLED
        /* close pipe ends used by main */
        close(worker->cmd_send_fd);
        worker->cmd_send_fd = -1;
@@ -330,7 +330,7 @@ daemon_start_others(struct daemon* daemon)
        for(i=1; i<daemon->num; i++) {
                ub_thread_create(&daemon->workers[i]->thr_id,
                        thread_start, daemon->workers[i]);
-#if !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS)
+#ifdef THREADS_DISABLED
                /* close pipe end of child */
                close(daemon->workers[i]->cmd_recv_fd);
                daemon->workers[i]->cmd_recv_fd = -1;
index e9d6245d6d7b4d0570f914489baa349d7b8b8e0c..fdf4d106f4316d013884bb8b52effdefde7445fc 100644 (file)
@@ -1,3 +1,8 @@
+16 June 2008: Wouter
+       - on windows, use windows threads, mutex and thread-local-storage(Tls).
+       - detect if openssl needs gdi32.
+       - if no threading, THREADS_DISABLED is defined for use in the code.
+
 13 June 2008: Wouter
        - port mingw32, more signal ifdefs, detect sleep, usleep, 
          random, srandom (used inside the tests).
index 34891608ebc4dd58ea6c36076bd9cf86cb9006b4..f027e6e3c54edcbc763f1faac49351f42f073f40 100644 (file)
@@ -345,7 +345,7 @@ int ub_ctx_debugout(struct ub_ctx* ctx, void* out)
 int 
 ub_ctx_async(struct ub_ctx* ctx, int dothread)
 {
-#if !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS)
+#ifdef THREADS_DISABLED
        if(dothread) /* cannot do threading */
                return UB_NOERROR;
 #endif
index 151b15c92da213934461f73a53c5bcfbb2b31666..8d9172df1375090cb97fb66a87139c8674011fbb 100644 (file)
@@ -366,7 +366,7 @@ libworker_dobg(void* arg)
        struct libworker* w = (struct libworker*)arg;
        struct ub_ctx* ctx = w->ctx;
        log_thread_set(&w->thread_num);
-#if !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS)
+#ifdef THREADS_DISABLED
        /* we are forked */
        w->is_bg_thread = 0;
        /* close non-used parts of the pipes */
@@ -425,6 +425,10 @@ int libworker_bg(struct ub_ctx* ctx)
                ub_thread_create(&ctx->bg_tid, libworker_dobg, w);
        } else {
                lock_basic_unlock(&ctx->cfglock);
+#ifndef HAVE_FORK
+               /* no fork on windows */
+               return UB_FORKFAIL;
+#else /* HAVE_FORK */
                switch((ctx->bg_pid=fork())) {
                        case 0:
                                w = libworker_setup(ctx, 1);
@@ -442,6 +446,7 @@ int libworker_bg(struct ub_ctx* ctx)
                        default:
                                break;
                }
+#endif /* HAVE_FORK */ 
        }
        return UB_NOERROR;
 }
index ae7466eb1505f5313e794d5cd12623e5d501550a..b2c8f5530c87b12d016ab4b837c2e4bf58d775ba 100644 (file)
@@ -129,7 +129,7 @@ checkerr(const char* desc, int err)
        }
 }
 
-#if !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS)
+#ifdef THREADS_DISABLED
 /** only one process can communicate with async worker */
 #define NUMTHR 1
 #else /* have threads */
index 47c275889d6bad9cdd6178516b2507b2e7c5d54a..dec7a1e6e25089f7d54b04c40d372cdddc7e17b5 100644 (file)
@@ -96,7 +96,7 @@ void ub_thread_sig_unblock(int sig)
 #endif /* have signal stuff */
 }
 
-#if !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS)
+#if !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS) && !defined(HAVE_WINDOWS_THREADS)
 /**
  * No threading available: fork a new process.
  * This means no shared data structure, and no locking.
@@ -136,7 +136,7 @@ void ub_thr_fork_wait(ub_thread_t thread)
                log_warn("process %d abnormal exit with status %d",
                        (int)thread, status);
 }
-#endif /* !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS) */
+#endif /* !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS) && !defined(HAVE_WINDOWS_THREADS) */
 
 #ifdef HAVE_SOLARIS_THREADS
 void* ub_thread_key_get(ub_thread_key_t key)
@@ -146,3 +146,119 @@ void* ub_thread_key_get(ub_thread_key_t key)
        return ret;
 }
 #endif
+
+#ifdef HAVE_WINDOWS_THREADS
+/** log a windows GetLastError message */
+static void log_win_err(const char* str, DWORD err)
+{
+       LPTSTR buf;
+       if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | 
+               FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER, 
+               NULL, err, 0, (LPTSTR)&buf, 0, NULL) == 0) {
+               /* could not format error message */
+               log_err("%s, GetLastError=%d", str, (int)err);
+               return;
+       }
+       log_err("%s, (err=%d): %s", str, (int)err, buf);
+       LocalFree(buf);
+}
+
+void lock_basic_init(lock_basic_t* lock)
+{
+       *lock = CreateMutex(NULL, /* security attrs NULL, not process inherit*/
+               0,  /* false, we do not hold the lock initially */
+               NULL); /* create anonymous mutex */
+       if(*lock == NULL) {
+               log_win_err("CreateMutex failed", GetLastError());
+               fatal_exit("lock init failed");
+       }
+}
+
+void lock_basic_destroy(lock_basic_t* lock)
+{
+       if(!CloseHandle(*lock)) {
+               log_win_err("CloseHandle(Mutex) failed", GetLastError());
+       }
+       *lock = NULL;
+}
+
+void lock_basic_lock(lock_basic_t* lock)
+{
+       DWORD ret = WaitForSingleObject(*lock, INFINITE);
+       if(ret == WAIT_FAILED) {
+               log_win_err("WaitForSingleObject(Mutex):WAIT_FAILED", 
+                       GetLastError());
+       } else if(ret == WAIT_TIMEOUT) {
+               log_win_err("WaitForSingleObject(Mutex):WAIT_TIMEOUT", 
+                       GetLastError());
+       }
+       /* both WAIT_ABANDONED and WAIT_OBJECT_0 mean we have the lock */
+}
+
+void lock_basic_unlock(lock_basic_t* lock)
+{
+       if(!ReleaseMutex(*lock)) {
+               log_win_err("ReleaseMutex failed", GetLastError());
+       }
+}
+
+void ub_thread_key_create(ub_thread_key_t* key, void* f)
+{
+       *key = TlsAlloc();
+       if(*key == TLS_OUT_OF_INDEXES) {
+               *key = 0;
+               log_win_err("TlsAlloc Failed(OUT_OF_INDEXES)", GetLastError());
+       }
+       else ub_thread_key_set(*key, f);
+}
+
+void ub_thread_key_set(ub_thread_key_t key, void* v)
+{
+       if(!TlsSetValue(key, v)) {
+               log_win_err("TlsSetValue failed", GetLastError());
+       }
+}
+
+void* ub_thread_key_get(ub_thread_key_t key)
+{
+       void* ret = (void*)TlsGetValue(key);
+       if(ret == NULL && GetLastError() != ERROR_SUCCESS) {
+               log_win_err("TlsGetValue failed", GetLastError());
+       }
+       return ret;
+}
+
+void ub_thread_create(ub_thread_t* thr, void* (*func)(void*), void* arg)
+{
+       *thr = CreateThread(NULL, /* default security (no inherit handle) */
+               0, /* default stack size */
+               (LPTHREAD_START_ROUTINE)func, arg,
+               0, /* default flags, run immediately */
+               NULL); /* do not store thread identifier anywhere */
+       if(*thr == NULL) {
+               log_win_err("CreateThread failed", GetLastError());
+               fatal_exit("thread create failed");
+       }
+}
+
+ub_thread_t ub_thread_self(void)
+{
+       return GetCurrentThread();
+}
+
+void ub_thread_join(ub_thread_t thr)
+{
+       DWORD ret = WaitForSingleObject(thr, INFINITE);
+       if(ret == WAIT_FAILED) {
+               log_win_err("WaitForSingleObject(Thread):WAIT_FAILED", 
+                       GetLastError());
+       } else if(ret == WAIT_TIMEOUT) {
+               log_win_err("WaitForSingleObject(Thread):WAIT_TIMEOUT", 
+                       GetLastError());
+       }
+       /* and close the handle to the thread */
+       if(!CloseHandle(thr)) {
+               log_win_err("CloseHandle(Thread) failed", GetLastError());
+       }
+}
+#endif /* HAVE_WINDOWS_THREADS */
index cbbde67be9b6472206e2514fcc67f1c0c4734992..39663ebbdb86ff4a4e080402d7b73dce5c4fd3e8 100644 (file)
@@ -201,41 +201,42 @@ void* ub_thread_key_get(ub_thread_key_t key);
 #ifdef HAVE_WINDOWS_THREADS
 #include <windows.h>
 
-/* use basic mutex */
+/* Use a mutex */
 typedef HANDLE lock_rw_t;
-#define lock_rw_init(lock) windows_lock_init(lock)
-#define lock_rw_destroy(lock) LOCKRET(rwlock_destroy(lock))
-#define lock_rw_rdlock(lock) LOCKRET(rw_rdlock(lock))
-#define lock_rw_wrlock(lock) LOCKRET(rw_wrlock(lock))
-#define lock_rw_unlock(lock) LOCKRET(rw_unlock(lock))
+#define lock_rw_init(lock) lock_basic_init(lock)
+#define lock_rw_destroy(lock) lock_basic_destroy(lock)
+#define lock_rw_rdlock(lock) lock_basic_lock(lock)
+#define lock_rw_wrlock(lock) lock_basic_lock(lock)
+#define lock_rw_unlock(lock) lock_basic_unlock(lock)
 
-/** use mutex */
+/** the basic lock is a mutex, implemented opaquely, for error handling. */
 typedef HANDLE lock_basic_t;
-#define lock_basic_init(lock) LOCKRET(mutex_init(lock, USYNC_THREAD, NULL))
-#define lock_basic_destroy(lock) LOCKRET(mutex_destroy(lock))
-#define lock_basic_lock(lock) LOCKRET(mutex_lock(lock))
-#define lock_basic_unlock(lock) LOCKRET(mutex_unlock(lock))
+void lock_basic_init(lock_basic_t* lock);
+void lock_basic_destroy(lock_basic_t* lock);
+void lock_basic_lock(lock_basic_t* lock);
+void lock_basic_unlock(lock_basic_t* lock);
 
-/** Use mutex. */
+/** on windows no spinlock, use mutex too. */
 typedef HANDLE lock_quick_t;
-#define lock_quick_init(lock) LOCKRET(mutex_init(lock, USYNC_THREAD, NULL))
-#define lock_quick_destroy(lock) LOCKRET(mutex_destroy(lock))
-#define lock_quick_lock(lock) LOCKRET(mutex_lock(lock))
-#define lock_quick_unlock(lock) LOCKRET(mutex_unlock(lock))
+#define lock_quick_init(lock) lock_basic_init(lock)
+#define lock_quick_destroy(lock) lock_basic_destroy(lock)
+#define lock_quick_lock(lock) lock_basic_lock(lock)
+#define lock_quick_unlock(lock) lock_basic_unlock(lock)
 
 /** Thread creation, create a default thread. */
 typedef HANDLE ub_thread_t;
-#define ub_thread_create(thr, func, arg) windows_thread_create(thr, func, arg);
-#define ub_thread_self() windows_thread_self()
-#define ub_thread_join(thread) windows_thread_join(thread)
+void ub_thread_create(ub_thread_t* thr, void* (*func)(void*), void* arg);
+ub_thread_t ub_thread_self(void);
+void ub_thread_join(ub_thread_t thr);
 typedef DWORD ub_thread_key_t;
-#define ub_thread_key_create(key, f) windows_thread_key_create(key, f)
-#define ub_thread_key_set(key, v) windows_thread_key_set(key, v)
+void ub_thread_key_create(ub_thread_key_t* key, void* f);
+void ub_thread_key_set(ub_thread_key_t key, void* v);
 void* ub_thread_key_get(ub_thread_key_t key);
 
 #else /* we do not HAVE_SOLARIS_THREADS, PTHREADS or WINDOWS_THREADS */
 
 /******************* NO THREADS ************************/
+#define THREADS_DISABLED 1
 /** In case there is no thread support, define locks to do nothing */
 typedef int lock_rw_t;
 #define lock_rw_init(lock) /* nop */
index 3817a86f93769b5acebe3a1cc4a2fea5173f0f76..b49842014db3aa29eb60b6e001e082a7c19f35fc 100644 (file)
@@ -48,7 +48,7 @@ void
 bin_init(struct lruhash_bin* array, size_t size)
 {
        size_t i;
-#if !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS)
+#ifdef THREADS_DISABLED
        (void)array;
 #endif
        for(i=0; i<size; i++) {
@@ -122,7 +122,7 @@ bin_split(struct lruhash* table, struct lruhash_bin* newa,
        /* move entries to new table. Notice that since hash x is mapped to
         * bin x & mask, and new mask uses one more bit, so all entries in
         * one bin will go into the old bin or bin | newbit */
-#if defined(HAVE_PTHREAD) || defined(HAVE_SOLARIS_THREADS)
+#ifndef THREADS_DISABLED
        int newbit = newmask - table->size_mask;
 #endif
        /* so, really, this task could also be threaded, per bin. */