From: Wouter Wijngaards Date: Mon, 16 Jun 2008 13:39:46 +0000 (+0000) Subject: windows threads. detect gdi32. nicer DISABLED_THREADS define. Compiles on mingw32. X-Git-Tag: release-1.0.1~30 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f90f5a25839fcf78b0140fcbc52be5eb277d5ffa;p=thirdparty%2Funbound.git windows threads. detect gdi32. nicer DISABLED_THREADS define. Compiles on mingw32. git-svn-id: file:///svn/unbound/trunk@1122 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/configure b/configure index 795767f20..b6a14d78a 100755 --- 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 diff --git a/configure.ac b/configure.ac index 948a7c8be..eaab37d85 100644 --- a/configure.ac +++ b/configure.ac @@ -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" diff --git a/daemon/daemon.c b/daemon/daemon.c index f235f76fa..7a83cd708 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -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; inum; 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; diff --git a/doc/Changelog b/doc/Changelog index e9d6245d6..fdf4d106f 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -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). diff --git a/libunbound/libunbound.c b/libunbound/libunbound.c index 34891608e..f027e6e3c 100644 --- a/libunbound/libunbound.c +++ b/libunbound/libunbound.c @@ -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 diff --git a/libunbound/libworker.c b/libunbound/libworker.c index 151b15c92..8d9172df1 100644 --- a/libunbound/libworker.c +++ b/libunbound/libworker.c @@ -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; } diff --git a/testcode/asynclook.c b/testcode/asynclook.c index ae7466eb1..b2c8f5530 100644 --- a/testcode/asynclook.c +++ b/testcode/asynclook.c @@ -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 */ diff --git a/util/locks.c b/util/locks.c index 47c275889..dec7a1e6e 100644 --- a/util/locks.c +++ b/util/locks.c @@ -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 */ diff --git a/util/locks.h b/util/locks.h index cbbde67be..39663ebbd 100644 --- a/util/locks.h +++ b/util/locks.h @@ -201,41 +201,42 @@ void* ub_thread_key_get(ub_thread_key_t key); #ifdef HAVE_WINDOWS_THREADS #include -/* 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 */ diff --git a/util/storage/lruhash.c b/util/storage/lruhash.c index 3817a86f9..b49842014 100644 --- a/util/storage/lruhash.c +++ b/util/storage/lruhash.c @@ -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; isize_mask; #endif /* so, really, this task could also be threaded, per bin. */