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 19#if APR_HAS_THREADS 20 21#include "apr_arch_thread_mutex.h" 22#include "apr_arch_thread_cond.h" 23 24static apr_status_t thread_cond_cleanup(void *data) 25{ 26 apr_thread_cond_t *cond = (apr_thread_cond_t *)data; 27 apr_status_t rv; 28 29 rv = pthread_cond_destroy(&cond->cond); 30#ifdef HAVE_ZOS_PTHREADS 31 if (rv) { 32 rv = errno; 33 } 34#endif 35 return rv; 36} 37 38APR_DECLARE(apr_status_t) apr_thread_cond_create(apr_thread_cond_t **cond, 39 apr_pool_t *pool) 40{ 41 apr_thread_cond_t *new_cond; 42 apr_status_t rv; 43 44 new_cond = apr_palloc(pool, sizeof(apr_thread_cond_t)); 45 46 new_cond->pool = pool; 47 48 if ((rv = pthread_cond_init(&new_cond->cond, NULL))) { 49#ifdef HAVE_ZOS_PTHREADS 50 rv = errno; 51#endif 52 return rv; 53 } 54 55 apr_pool_cleanup_register(new_cond->pool, 56 (void *)new_cond, thread_cond_cleanup, 57 apr_pool_cleanup_null); 58 59 *cond = new_cond; 60 return APR_SUCCESS; 61} 62 63APR_DECLARE(apr_status_t) apr_thread_cond_wait(apr_thread_cond_t *cond, 64 apr_thread_mutex_t *mutex) 65{ 66 apr_status_t rv; 67 68 rv = pthread_cond_wait(&cond->cond, &mutex->mutex); 69#ifdef HAVE_ZOS_PTHREADS 70 if (rv) { 71 rv = errno; 72 } 73#endif 74 return rv; 75} 76 77APR_DECLARE(apr_status_t) apr_thread_cond_timedwait(apr_thread_cond_t *cond, 78 apr_thread_mutex_t *mutex, 79 apr_interval_time_t timeout) 80{ 81 apr_status_t rv; 82 apr_time_t then; 83 struct timespec abstime; 84 85 then = apr_time_now() + timeout; 86 abstime.tv_sec = apr_time_sec(then); 87 abstime.tv_nsec = apr_time_usec(then) * 1000; /* nanoseconds */ 88 89 rv = pthread_cond_timedwait(&cond->cond, &mutex->mutex, &abstime); 90#ifdef HAVE_ZOS_PTHREADS 91 if (rv) { 92 rv = errno; 93 } 94#endif 95 if (ETIMEDOUT == rv) { 96 return APR_TIMEUP; 97 } 98 return rv; 99} 100 101 102APR_DECLARE(apr_status_t) apr_thread_cond_signal(apr_thread_cond_t *cond) 103{ 104 apr_status_t rv; 105 106 rv = pthread_cond_signal(&cond->cond); 107#ifdef HAVE_ZOS_PTHREADS 108 if (rv) { 109 rv = errno; 110 } 111#endif 112 return rv; 113} 114 115APR_DECLARE(apr_status_t) apr_thread_cond_broadcast(apr_thread_cond_t *cond) 116{ 117 apr_status_t rv; 118 119 rv = pthread_cond_broadcast(&cond->cond); 120#ifdef HAVE_ZOS_PTHREADS 121 if (rv) { 122 rv = errno; 123 } 124#endif 125 return rv; 126} 127 128APR_DECLARE(apr_status_t) apr_thread_cond_destroy(apr_thread_cond_t *cond) 129{ 130 return apr_pool_cleanup_run(cond->pool, cond, thread_cond_cleanup); 131} 132 133APR_POOL_IMPLEMENT_ACCESSOR(thread_cond) 134 135#endif /* APR_HAS_THREADS */ 136