condition.c revision af1e34f918791cf8dc1ed649e306358c71934ddc
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff/*
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff * Copyright (C) 2004, 2006, 2007 Internet Systems Consortium, Inc. ("ISC")
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff * Copyright (C) 1998-2001 Internet Software Consortium.
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff *
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff * Permission to use, copy, modify, and distribute this software for any
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff * purpose with or without fee is hereby granted, provided that the above
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff * copyright notice and this permission notice appear in all copies.
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff *
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff * PERFORMANCE OF THIS SOFTWARE.
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff */
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff/* $Id: condition.c,v 1.22 2007/05/10 23:46:54 tbox Exp $ */
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff#include <config.h>
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff#include <isc/condition.h>
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff#include <isc/assertions.h>
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff#include <isc/util.h>
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff#include <isc/thread.h>
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff#include <isc/time.h>
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff#define LSIGNAL 0
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff#define LBROADCAST 1
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graffisc_result_t
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graffisc_condition_init(isc_condition_t *cond) {
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff HANDLE h;
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff REQUIRE(cond != NULL);
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff cond->waiters = 0;
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff /*
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff * This handle is shared across all threads
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff */
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff h = CreateEvent(NULL, FALSE, FALSE, NULL);
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff if (h == NULL) {
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff /* XXX */
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff return (ISC_R_UNEXPECTED);
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff }
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff cond->events[LSIGNAL] = h;
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff /*
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff * The threadlist will hold the actual events needed
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff * for the wait condition
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff */
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff ISC_LIST_INIT(cond->threadlist);
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff return (ISC_R_SUCCESS);
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff}
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff/*
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff * Add the thread to the threadlist along with the required events
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff */
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graffstatic isc_result_t
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graffregister_thread(unsigned long thrd, isc_condition_t *gblcond,
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff isc_condition_thread_t **localcond)
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff{
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff HANDLE hc;
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff isc_condition_thread_t *newthread;
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff REQUIRE(localcond != NULL && *localcond == NULL);
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff newthread = malloc(sizeof(isc_condition_thread_t));
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff if (newthread == NULL)
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff return (ISC_R_NOMEMORY);
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff /*
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff * Create the thread-specific handle
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff */
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff hc = CreateEvent(NULL, FALSE, FALSE, NULL);
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff if (hc == NULL) {
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff free(newthread);
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff return (ISC_R_UNEXPECTED);
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff }
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff /*
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff * Add the thread ID and handles to list of threads for broadcast
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff */
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff newthread->handle[LSIGNAL] = gblcond->events[LSIGNAL];
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff newthread->handle[LBROADCAST] = hc;
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff newthread->th = thrd;
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff /*
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff * The thread is holding the manager lock so this is safe
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff */
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff ISC_LIST_APPEND(gblcond->threadlist, newthread, link);
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff *localcond = newthread;
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff return (ISC_R_SUCCESS);
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff}
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graffstatic isc_result_t
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Grafffind_thread_condition(unsigned long thrd, isc_condition_t *cond,
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff isc_condition_thread_t **threadcondp)
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff{
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff isc_condition_thread_t *threadcond;
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff REQUIRE(threadcondp != NULL && *threadcondp == NULL);
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff /*
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff * Look for the thread ID.
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff */
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff for (threadcond = ISC_LIST_HEAD(cond->threadlist);
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff threadcond != NULL;
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff threadcond = ISC_LIST_NEXT(threadcond, link)) {
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff if (threadcond->th == thrd) {
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff *threadcondp = threadcond;
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff return (ISC_R_SUCCESS);
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff }
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff }
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff /*
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff * Not found, so add it.
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff */
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff return (register_thread(thrd, cond, threadcondp));
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff}
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graffisc_result_t
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graffisc_condition_signal(isc_condition_t *cond) {
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff /*
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff * Unlike pthreads, the caller MUST hold the lock associated with
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff * the condition variable when calling us.
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff */
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(cond != NULL);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff if (!SetEvent(cond->events[LSIGNAL])) {
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff /* XXX */
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff return (ISC_R_UNEXPECTED);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff }
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff return (ISC_R_SUCCESS);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff}
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graffisc_result_t
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graffisc_condition_broadcast(isc_condition_t *cond) {
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff isc_condition_thread_t *threadcond;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff isc_boolean_t failed = ISC_FALSE;
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff /*
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff * Unlike pthreads, the caller MUST hold the lock associated with
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff * the condition variable when calling us.
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff */
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff REQUIRE(cond != NULL);
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff /*
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff * Notify every thread registered for this
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff */
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff for (threadcond = ISC_LIST_HEAD(cond->threadlist);
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff threadcond != NULL;
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff threadcond = ISC_LIST_NEXT(threadcond, link)) {
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff
291b0d910d115e41a4b69d0603c3376aebf0c630Michael Graff if (!SetEvent(threadcond->handle[LBROADCAST]))
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff failed = ISC_TRUE;
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff }
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff
291b0d910d115e41a4b69d0603c3376aebf0c630Michael Graff if (failed)
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff return (ISC_R_UNEXPECTED);
dafb96ea512cffd84c2d1a2cc5bf0b1379915c8fMichael Graff
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff return (ISC_R_SUCCESS);
291b0d910d115e41a4b69d0603c3376aebf0c630Michael Graff}
291b0d910d115e41a4b69d0603c3376aebf0c630Michael Graff
291b0d910d115e41a4b69d0603c3376aebf0c630Michael Graffisc_result_t
291b0d910d115e41a4b69d0603c3376aebf0c630Michael Graffisc_condition_destroy(isc_condition_t *cond) {
291b0d910d115e41a4b69d0603c3376aebf0c630Michael Graff
291b0d910d115e41a4b69d0603c3376aebf0c630Michael Graff isc_condition_thread_t *next, *threadcond;
291b0d910d115e41a4b69d0603c3376aebf0c630Michael Graff
291b0d910d115e41a4b69d0603c3376aebf0c630Michael Graff REQUIRE(cond != NULL);
291b0d910d115e41a4b69d0603c3376aebf0c630Michael Graff REQUIRE(cond->waiters == 0);
291b0d910d115e41a4b69d0603c3376aebf0c630Michael Graff
291b0d910d115e41a4b69d0603c3376aebf0c630Michael Graff (void)CloseHandle(cond->events[LSIGNAL]);
291b0d910d115e41a4b69d0603c3376aebf0c630Michael Graff
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff /*
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff * Delete the threadlist
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff */
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff threadcond = ISC_LIST_HEAD(cond->threadlist);
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff while (threadcond != NULL) {
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff next = ISC_LIST_NEXT(threadcond, link);
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff DEQUEUE(cond->threadlist, threadcond, link);
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff (void) CloseHandle(threadcond->handle[LBROADCAST]);
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff free(threadcond);
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff threadcond = next;
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff }
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff return (ISC_R_SUCCESS);
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff}
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff/*
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff * This is always called when the mutex (lock) is held, but because
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff * we are waiting we need to release it and reacquire it as soon as the wait
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff * is over. This allows other threads to make use of the object guarded
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff * by the mutex but it should never try to delete it as long as the
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff * number of waiters > 0. Always reacquire the mutex regardless of the
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff * result of the wait. Note that EnterCriticalSection will wait to acquire
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff * the mutex.
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff */
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graffstatic isc_result_t
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graffwait(isc_condition_t *cond, isc_mutex_t *mutex, DWORD milliseconds) {
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff DWORD result;
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff isc_result_t tresult;
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff isc_condition_thread_t *threadcond = NULL;
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff /*
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff * Get the thread events needed for the wait
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff */
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff tresult = find_thread_condition(isc_thread_self(), cond, &threadcond);
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff if (tresult != ISC_R_SUCCESS)
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff return (tresult);
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff cond->waiters++;
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff LeaveCriticalSection(mutex);
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff result = WaitForMultipleObjects(2, threadcond->handle, FALSE,
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff milliseconds);
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff EnterCriticalSection(mutex);
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff cond->waiters--;
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff if (result == WAIT_FAILED) {
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff /* XXX */
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff return (ISC_R_UNEXPECTED);
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff }
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff if (result == WAIT_TIMEOUT)
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff return (ISC_R_TIMEDOUT);
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff return (ISC_R_SUCCESS);
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff}
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graffisc_result_t
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graffisc_condition_wait(isc_condition_t *cond, isc_mutex_t *mutex) {
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff return (wait(cond, mutex, INFINITE));
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff}
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graffisc_result_t
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graffisc_condition_waituntil(isc_condition_t *cond, isc_mutex_t *mutex,
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff isc_time_t *t) {
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff DWORD milliseconds;
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff isc_uint64_t microseconds;
7dbf5a0b64237aa3052f04f4c8f7d56be8ec5d79Michael Graff isc_time_t now;
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff
c05e003dce672b2f8555a3e56857f29ce89c1677Michael Graff if (isc_time_now(&now) != ISC_R_SUCCESS) {
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff /* XXX */
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff return (ISC_R_UNEXPECTED);
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff }
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff
ae7d0a4375abaecfd5c5b0816616d9882831e69bMichael Graff microseconds = isc_time_microdiff(t, &now);
e4f074a2c2340ea80099beebecc3b89aa234fa8fMichael Graff if (microseconds > 0xFFFFFFFFi64 * 1000)
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff milliseconds = 0xFFFFFFFF;
else
milliseconds = (DWORD)(microseconds / 1000);
return (wait(cond, mutex, milliseconds));
}