1
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
18
#include "apr_private.h"
19
#include "apr_general.h"
20
#include "apr_strings.h"
21
#include "win32/apr_arch_thread_mutex.h"
22
#include "win32/apr_arch_thread_cond.h"
23
#include "apr_portable.h"
25
static apr_status_t thread_cond_cleanup(void *data)
27
apr_thread_cond_t *cond = data;
28
CloseHandle(cond->event);
32
APR_DECLARE(apr_status_t) apr_thread_cond_create(apr_thread_cond_t **cond,
35
*cond = apr_palloc(pool, sizeof(**cond));
37
(*cond)->event = CreateEvent(NULL, TRUE, FALSE, NULL);
38
(*cond)->signal_all = 0;
39
(*cond)->num_waiting = 0;
43
static APR_INLINE apr_status_t _thread_cond_timedwait(apr_thread_cond_t *cond,
44
apr_thread_mutex_t *mutex,
52
apr_thread_mutex_unlock(mutex);
53
res = WaitForSingleObject(cond->event, timeout_ms);
54
apr_thread_mutex_lock(mutex);
56
if (res != WAIT_OBJECT_0) {
57
apr_status_t rv = apr_get_os_error();
58
if (res == WAIT_TIMEOUT) {
61
return apr_get_os_error();
63
if (cond->signal_all) {
64
if (cond->num_waiting == 0) {
67
ResetEvent(cond->event);
71
else if (cond->signalled) {
73
ResetEvent(cond->event);
80
APR_DECLARE(apr_status_t) apr_thread_cond_wait(apr_thread_cond_t *cond,
81
apr_thread_mutex_t *mutex)
83
return _thread_cond_timedwait(cond, mutex, INFINITE);
86
APR_DECLARE(apr_status_t) apr_thread_cond_timedwait(apr_thread_cond_t *cond,
87
apr_thread_mutex_t *mutex,
88
apr_interval_time_t timeout)
90
DWORD timeout_ms = (DWORD) apr_time_as_msec(timeout);
92
return _thread_cond_timedwait(cond, mutex, timeout_ms);
95
APR_DECLARE(apr_status_t) apr_thread_cond_signal(apr_thread_cond_t *cond)
97
apr_status_t rv = APR_SUCCESS;
101
res = SetEvent(cond->event);
103
rv = apr_get_os_error();
108
APR_DECLARE(apr_status_t) apr_thread_cond_broadcast(apr_thread_cond_t *cond)
110
apr_status_t rv = APR_SUCCESS;
114
cond->signal_all = 1;
115
res = SetEvent(cond->event);
117
rv = apr_get_os_error();
122
APR_DECLARE(apr_status_t) apr_thread_cond_destroy(apr_thread_cond_t *cond)
124
return apr_pool_cleanup_run(cond->pool, cond, thread_cond_cleanup);
127
APR_POOL_IMPLEMENT_ACCESSOR(thread_cond)