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
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
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)
]
),
[ac_cv_func_getaddrinfo="yes"
-LDFLAGS="$LDFLAGS -lws2_32"
+dnl already: LIBS="$LIBS -lws2_32"
],
[ac_cv_func_getaddrinfo="no"
LIBS="$ORIGLIBS"
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;
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;
+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).
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
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 */
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);
default:
break;
}
+#endif /* HAVE_FORK */
}
return UB_NOERROR;
}
}
}
-#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 */
#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.
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)
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 */
#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 */
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++) {
/* 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. */