upload http
[bottlenecks.git] / rubbos / app / httpd-2.0.64 / srclib / apr / locks / win32 / thread_cond.c
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
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include "apr.h"
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"
24
25 static apr_status_t thread_cond_cleanup(void *data)
26 {
27     apr_thread_cond_t *cond = data;
28     CloseHandle(cond->event);
29     return APR_SUCCESS;
30 }
31
32 APR_DECLARE(apr_status_t) apr_thread_cond_create(apr_thread_cond_t **cond,
33                                                  apr_pool_t *pool)
34 {
35     *cond = apr_palloc(pool, sizeof(**cond));
36     (*cond)->pool = pool;
37     (*cond)->event = CreateEvent(NULL, TRUE, FALSE, NULL);
38     (*cond)->signal_all = 0;
39     (*cond)->num_waiting = 0;
40     return APR_SUCCESS;
41 }
42
43 static APR_INLINE apr_status_t _thread_cond_timedwait(apr_thread_cond_t *cond,
44                                                       apr_thread_mutex_t *mutex,
45                                                       DWORD timeout_ms )
46 {
47     DWORD res;
48
49     while (1) {
50         cond->num_waiting++;
51
52         apr_thread_mutex_unlock(mutex);
53         res = WaitForSingleObject(cond->event, timeout_ms);
54         apr_thread_mutex_lock(mutex);
55         cond->num_waiting--;
56         if (res != WAIT_OBJECT_0) {
57             apr_status_t rv = apr_get_os_error();
58             if (res == WAIT_TIMEOUT) {
59                 return APR_TIMEUP;
60             }
61             return apr_get_os_error();
62         }
63         if (cond->signal_all) {
64             if (cond->num_waiting == 0) {
65                 cond->signal_all = 0;
66                 cond->signalled = 0;
67                 ResetEvent(cond->event);
68             }
69             break;
70         }
71         else if (cond->signalled) {
72             cond->signalled = 0;
73             ResetEvent(cond->event);
74             break;
75         }
76     }
77     return APR_SUCCESS;
78 }
79
80 APR_DECLARE(apr_status_t) apr_thread_cond_wait(apr_thread_cond_t *cond,
81                                                apr_thread_mutex_t *mutex)
82 {
83     return _thread_cond_timedwait(cond, mutex, INFINITE);
84 }
85
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)
89 {
90     DWORD timeout_ms = (DWORD) apr_time_as_msec(timeout);
91
92     return _thread_cond_timedwait(cond, mutex, timeout_ms);
93 }
94
95 APR_DECLARE(apr_status_t) apr_thread_cond_signal(apr_thread_cond_t *cond)
96 {
97     apr_status_t rv = APR_SUCCESS;
98     DWORD res;
99
100     cond->signalled = 1;
101     res = SetEvent(cond->event);
102     if (res == 0) {
103         rv = apr_get_os_error();
104     }
105     return rv;
106 }
107
108 APR_DECLARE(apr_status_t) apr_thread_cond_broadcast(apr_thread_cond_t *cond)
109 {
110     apr_status_t rv = APR_SUCCESS;
111     DWORD res;
112
113     cond->signalled = 1;
114     cond->signal_all = 1;
115     res = SetEvent(cond->event);
116     if (res == 0) {
117         rv = apr_get_os_error();
118     }
119     return rv;
120 }
121
122 APR_DECLARE(apr_status_t) apr_thread_cond_destroy(apr_thread_cond_t *cond)
123 {
124     return apr_pool_cleanup_run(cond->pool, cond, thread_cond_cleanup);
125 }
126
127 APR_POOL_IMPLEMENT_ACCESSOR(thread_cond)
128