1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. 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)