From 0fc87fa2f38df7b293b650deacfa5e6c3d50eff9 Mon Sep 17 00:00:00 2001 From: Bob Halley Date: Fri, 23 Oct 1998 05:45:44 +0000 Subject: [PATCH] add --- lib/isc/win32/condition.c | 110 ++++++++++++++++++++++++++ lib/isc/win32/include/isc/condition.h | 25 ++++++ lib/isc/win32/include/isc/mutex.h | 20 +++++ lib/isc/win32/include/isc/thread.h | 21 +++++ lib/isc/win32/include/isc/time.h | 71 +++++++++++++++++ lib/isc/win32/thread.c | 41 ++++++++++ lib/isc/win32/time.c | 82 +++++++++++++++++++ 7 files changed, 370 insertions(+) create mode 100644 lib/isc/win32/condition.c create mode 100644 lib/isc/win32/include/isc/condition.h create mode 100644 lib/isc/win32/include/isc/mutex.h create mode 100644 lib/isc/win32/include/isc/thread.h create mode 100644 lib/isc/win32/include/isc/time.h create mode 100644 lib/isc/win32/thread.c create mode 100644 lib/isc/win32/time.c diff --git a/lib/isc/win32/condition.c b/lib/isc/win32/condition.c new file mode 100644 index 0000000000..ea3b2c87ff --- /dev/null +++ b/lib/isc/win32/condition.c @@ -0,0 +1,110 @@ + +#include +#include + +#define SIGNAL 0 +#define BROADCAST 1 + +isc_result_t +isc_condition_init(isc_condition_t *cond) { + HANDLE h; + + REQUIRE(cond != NULL); + + cond->waiters = 0; + h = CreateEvent(NULL, FALSE, FALSE, NULL); + if (h == NULL) { + /* XXX */ + return (ISC_R_UNEXPECTED); + } + cond->events[SIGNAL] = h; + h = CreateEvent(NULL, TRUE, FALSE, NULL); + if (h == NULL) { + (void)CloseHandle(cond->events[SIGNAL]); + /* XXX */ + return (ISC_R_UNEXPECTED); + } + cond->events[BROADCAST] = h; + return (ISC_R_SUCCESS); +} + +isc_result_t +isc_condition_signal(isc_condition_t *cond) { + + REQUIRE(cond != NULL); + + if (cond->waiters > 0 && + !SetEvent(cond->events[SIGNAL])) { + /* XXX */ + return (ISC_R_UNEXPECTED); + } + return (ISC_R_SUCCESS); +} + +isc_result_t +isc_condition_broadcast(isc_condition_t *cond) { + + REQUIRE(cond != NULL); + + if (cond->waiters > 0 && + !SetEvent(cond->events[BROADCAST])) { + /* XXX */ + return (ISC_R_UNEXPECTED); + } + return (ISC_R_SUCCESS); +} + +isc_result_t +isc_condition_destroy(isc_condition_t *cond) { + + REQUIRE(cond != NULL); + + (void)CloseHandle(cond->events[SIGNAL]); + (void)CloseHandle(cond->events[BROADCAST]); + return (ISC_R_SUCCESS); +} + +static +isc_result_t +wait(isc_condition_t *cond, isc_mutex_t *mutex, + DWORD milliseconds) +{ + DWORD result; + + cond->waiters++; + LeaveCriticalSection(mutex); + result = WaitForMultipleObjects(2, cond->events, FALSE, + milliseconds); + if (result == WAIT_FAILED) { + /* XXX */ + return (ISC_R_UNEXPECTED); + } + EnterCriticalSection(mutex); + cond->waiters--; + if (cond->waiters == 0 && + !ResetEvent(cond->events[BROADCAST])) { + /* XXX */ + LeaveCriticalSection(mutex); + return (ISC_R_UNEXPECTED); + } + + if (result == WAIT_TIMEOUT) + return (ISC_R_TIMEDOUT); + + return (ISC_R_SUCCESS); +} + +isc_result_t +isc_condition_wait(isc_condition_t *cond, isc_mutex_t *mutex) { + return (wait(cond, mutex, INFINITE)); +} + +isc_result_t +isc_condition_waituntil(isc_condition_t *cond, isc_mutex_t *mutex, + isc_time_t t) +{ + DWORD milliseconds; + + milliseconds = 100; /* XXX */ + return (wait(cond, mutex, milliseconds)); +} diff --git a/lib/isc/win32/include/isc/condition.h b/lib/isc/win32/include/isc/condition.h new file mode 100644 index 0000000000..9689b8e210 --- /dev/null +++ b/lib/isc/win32/include/isc/condition.h @@ -0,0 +1,25 @@ + +#ifndef ISC_CONDITION_H +#define ISC_CONDITION_H 1 + +#include + +#include +#include +#include +#include + +typedef struct isc_condition { + HANDLE events[2]; + unsigned int waiters; +} isc_condition_t; + +isc_result_t isc_condition_init(isc_condition_t *); +isc_result_t isc_condition_wait(isc_condition_t *, isc_mutex_t *); +isc_result_t isc_condition_signal(isc_condition_t *); +isc_result_t isc_condition_broadcast(isc_condition_t *); +isc_result_t isc_condition_destroy(isc_condition_t *); +isc_result_t isc_condition_waituntil(isc_condition_t *, isc_mutex_t *, + isc_time_t); + +#endif /* ISC_CONDITION_H */ diff --git a/lib/isc/win32/include/isc/mutex.h b/lib/isc/win32/include/isc/mutex.h new file mode 100644 index 0000000000..5564440338 --- /dev/null +++ b/lib/isc/win32/include/isc/mutex.h @@ -0,0 +1,20 @@ + +#ifndef ISC_MUTEX_H +#define ISC_MUTEX_H 1 + +#include + +#include + +typedef CRITICAL_SECTION isc_mutex_t; + +#define isc_mutex_init(mp) \ + (InitializeCriticalSection((mp)), ISC_R_SUCCESS) +#define isc_mutex_lock(mp) \ + (EnterCriticalSection((mp)), ISC_R_SUCCESS) +#define isc_mutex_unlock(mp) \ + (LeaveCriticalSection((mp)), ISC_R_SUCCESS) +#define isc_mutex_destroy(mp) \ + (DeleteCriticalSection((mp)), ISC_R_SUCCESS) + +#endif /* ISC_MUTEX_H */ diff --git a/lib/isc/win32/include/isc/thread.h b/lib/isc/win32/include/isc/thread.h new file mode 100644 index 0000000000..c22915ff86 --- /dev/null +++ b/lib/isc/win32/include/isc/thread.h @@ -0,0 +1,21 @@ + +#ifndef ISC_THREAD_H +#define ISC_THREAD_H 1 + +#include + +#include + +typedef HANDLE isc_thread_t; +typedef DWORD isc_threadresult_t; +typedef LPVOID isc_threadarg_t; +typedef isc_threadresult_t (WINAPI *isc_threadfunc_t)(isc_threadarg_t); + +isc_result_t isc_thread_create(isc_threadfunc_t, isc_threadarg_t, + isc_thread_t *); +isc_result_t isc_thread_join(isc_thread_t, isc_threadresult_t *); +isc_result_t isc_thread_detach(isc_thread_t); +#define isc_thread_self \ + (unsigned long)GetCurrentThreadId + +#endif /* ISC_THREAD_H */ diff --git a/lib/isc/win32/include/isc/time.h b/lib/isc/win32/include/isc/time.h new file mode 100644 index 0000000000..850a826fa2 --- /dev/null +++ b/lib/isc/win32/include/isc/time.h @@ -0,0 +1,71 @@ + +#ifndef ISC_TIME_H +#define ISC_TIME_H 1 + +#include +#include + +/* + * This structure can be used both to represent absolute times, and to + * to represent intervals. + */ + +typedef struct isc_time { + time_t seconds; + long nanoseconds; +} *isc_time_t; + +isc_result_t +isc_time_get(isc_time_t t); +/* + * Set 't' to the current absolute time (secs + nsec since January 1, 1970). + * + * Requires: + * + * 't' is a valid pointer. + * + * Returns: + * + * Success + * Unexpected error + */ + +int +isc_time_compare(isc_time_t t1, isc_time_t t2); +/* + * Compare the times referenced by 't1' and 't2' + * + * Requires: + * + * 't1' and 't2' are a valid. + * + * Returns: + * + * -1 t1 < t2 (comparing times, not pointers) + * 0 t1 = t2 + * 1 t1 > t2 + */ + +void +isc_time_add(isc_time_t t1, isc_time_t t2, isc_time_t t3); +/* + * Add 't1' to 't2', storing the result in 't3'. + * + * Requires: + * + * 't1', 't2', and 't3' are valid. + */ + +void +isc_time_subtract(isc_time_t t1, isc_time_t t2, isc_time_t t3); +/* + * Subtract 't2' from 't1', storing the result in 't3'. + * + * Requires: + * + * 't1', 't2', and 't3' are valid. + * + * t1 >= t2 (comparing times, not pointers) + */ + +#endif /* ISC_TIME_H */ diff --git a/lib/isc/win32/thread.c b/lib/isc/win32/thread.c new file mode 100644 index 0000000000..b5b90c18b5 --- /dev/null +++ b/lib/isc/win32/thread.c @@ -0,0 +1,41 @@ + +#include + +isc_result_t +isc_thread_create(isc_threadfunc_t start, isc_threadarg_t arg, + isc_thread_t *threadp) +{ + HANDLE h; + DWORD id; + + h = CreateThread(NULL, 0, start, arg, 0, &id); + if (h == NULL) { + /* XXX */ + return (ISC_R_UNEXPECTED); + } + + *threadp = h; + + return (ISC_R_SUCCESS); +} + +isc_result_t +isc_thread_join(isc_thread_t thread, isc_threadresult_t *rp) { + DWORD result; + + result = WaitForSingleObject(thread, INFINITE); + if (result != WAIT_OBJECT_0) { + /* XXX */ + return (ISC_R_UNEXPECTED); + } + if (rp != NULL && !GetExitCodeThread(thread, rp)) { + /* XXX */ + return (ISC_R_UNEXPECTED); + } + return (ISC_R_SUCCESS); +} + +isc_result_t isc_thread_detach(isc_thread_t thread) { + /* XXX */ + return (ISC_R_SUCCESS); +} diff --git a/lib/isc/win32/time.c b/lib/isc/win32/time.c new file mode 100644 index 0000000000..78c85f09d2 --- /dev/null +++ b/lib/isc/win32/time.c @@ -0,0 +1,82 @@ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +isc_result +isc_time_get(isc_time_t t) { + /* + * Set *timep to the current absolute time (secs + nsec since + * January 1, 1970). + */ + + REQUIRE(t != NULL); + + /* XXX No nanoseconds! */ + t->seconds = (unsigned long)time(NULL); + t->nanoseconds = 0; + return (ISC_R_SUCCESS); +} + +int +isc_time_compare(isc_time_t t1, isc_time_t t2) { + /* + * Compare the times referenced by 't1' and 't2' + */ + + REQUIRE(t1 != NULL && t2 != NULL); + + if (t1->seconds < t2->seconds) + return (-1); + if (t1->seconds > t2->seconds) + return (1); + if (t1->nanoseconds < t2->nanoseconds) + return (-1); + if (t1->nanoseconds > t2->nanoseconds) + return (1); + return (0); +} + +void +isc_time_add(isc_time_t t1, isc_time_t t2, isc_time_t t3) +{ + /* + * Add 't1' to 't2', storing the result in 't3'. + */ + + REQUIRE(t1 != NULL && t2 != NULL && t3 != NULL); + + t3->seconds = t1->seconds + t2->seconds; + t3->nanoseconds = t1->nanoseconds + t2->nanoseconds; + if (t3->nanoseconds > 1000000000) { + t3->seconds++; + t3->nanoseconds -= 1000000000; + } +} + +void +isc_time_subtract(isc_time_t t1, isc_time_t t2, isc_time_t t3) { + /* + * Subtract 't2' from 't1', storing the result in 't1'. + */ + + REQUIRE(t1 != NULL && t2 != NULL && t3 != NULL); + REQUIRE(isc_time_compare(t1, t2) >= 0); + + t3->seconds = t1->seconds - t2->seconds; + if (t1->nanoseconds >= t2->nanoseconds) + t3->nanoseconds = t1->nanoseconds - t2->nanoseconds; + else { + t3->nanoseconds = 1000000000 - t2->nanoseconds + + t1->nanoseconds; + t3->seconds--; + } +}