1251875Speter/* Licensed to the Apache Software Foundation (ASF) under one or more 2251875Speter * contributor license agreements. See the NOTICE file distributed with 3251875Speter * this work for additional information regarding copyright ownership. 4251875Speter * The ASF licenses this file to You under the Apache License, Version 2.0 5251875Speter * (the "License"); you may not use this file except in compliance with 6251875Speter * the License. You may obtain a copy of the License at 7251875Speter * 8251875Speter * http://www.apache.org/licenses/LICENSE-2.0 9251875Speter * 10251875Speter * Unless required by applicable law or agreed to in writing, software 11251875Speter * distributed under the License is distributed on an "AS IS" BASIS, 12251875Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13251875Speter * See the License for the specific language governing permissions and 14251875Speter * limitations under the License. 15251875Speter */ 16251875Speter 17251875Speter#include "apr.h" 18251875Speter 19251875Speter#if APR_HAS_THREADS 20251875Speter 21251875Speter#include "apr_arch_thread_mutex.h" 22251875Speter#include "apr_arch_thread_cond.h" 23251875Speter 24251875Speterstatic apr_status_t thread_cond_cleanup(void *data) 25251875Speter{ 26251875Speter apr_thread_cond_t *cond = (apr_thread_cond_t *)data; 27251875Speter apr_status_t rv; 28251875Speter 29251875Speter rv = pthread_cond_destroy(&cond->cond); 30251875Speter#ifdef HAVE_ZOS_PTHREADS 31251875Speter if (rv) { 32251875Speter rv = errno; 33251875Speter } 34251875Speter#endif 35251875Speter return rv; 36251875Speter} 37251875Speter 38251875SpeterAPR_DECLARE(apr_status_t) apr_thread_cond_create(apr_thread_cond_t **cond, 39251875Speter apr_pool_t *pool) 40251875Speter{ 41251875Speter apr_thread_cond_t *new_cond; 42251875Speter apr_status_t rv; 43251875Speter 44251875Speter new_cond = apr_palloc(pool, sizeof(apr_thread_cond_t)); 45251875Speter 46251875Speter new_cond->pool = pool; 47251875Speter 48251875Speter if ((rv = pthread_cond_init(&new_cond->cond, NULL))) { 49251875Speter#ifdef HAVE_ZOS_PTHREADS 50251875Speter rv = errno; 51251875Speter#endif 52251875Speter return rv; 53251875Speter } 54251875Speter 55251875Speter apr_pool_cleanup_register(new_cond->pool, 56251875Speter (void *)new_cond, thread_cond_cleanup, 57251875Speter apr_pool_cleanup_null); 58251875Speter 59251875Speter *cond = new_cond; 60251875Speter return APR_SUCCESS; 61251875Speter} 62251875Speter 63251875SpeterAPR_DECLARE(apr_status_t) apr_thread_cond_wait(apr_thread_cond_t *cond, 64251875Speter apr_thread_mutex_t *mutex) 65251875Speter{ 66251875Speter apr_status_t rv; 67251875Speter 68251875Speter rv = pthread_cond_wait(&cond->cond, &mutex->mutex); 69251875Speter#ifdef HAVE_ZOS_PTHREADS 70251875Speter if (rv) { 71251875Speter rv = errno; 72251875Speter } 73251875Speter#endif 74251875Speter return rv; 75251875Speter} 76251875Speter 77251875SpeterAPR_DECLARE(apr_status_t) apr_thread_cond_timedwait(apr_thread_cond_t *cond, 78251875Speter apr_thread_mutex_t *mutex, 79251875Speter apr_interval_time_t timeout) 80251875Speter{ 81251875Speter apr_status_t rv; 82251875Speter apr_time_t then; 83251875Speter struct timespec abstime; 84251875Speter 85251875Speter then = apr_time_now() + timeout; 86251875Speter abstime.tv_sec = apr_time_sec(then); 87251875Speter abstime.tv_nsec = apr_time_usec(then) * 1000; /* nanoseconds */ 88251875Speter 89251875Speter rv = pthread_cond_timedwait(&cond->cond, &mutex->mutex, &abstime); 90251875Speter#ifdef HAVE_ZOS_PTHREADS 91251875Speter if (rv) { 92251875Speter rv = errno; 93251875Speter } 94251875Speter#endif 95251875Speter if (ETIMEDOUT == rv) { 96251875Speter return APR_TIMEUP; 97251875Speter } 98251875Speter return rv; 99251875Speter} 100251875Speter 101251875Speter 102251875SpeterAPR_DECLARE(apr_status_t) apr_thread_cond_signal(apr_thread_cond_t *cond) 103251875Speter{ 104251875Speter apr_status_t rv; 105251875Speter 106251875Speter rv = pthread_cond_signal(&cond->cond); 107251875Speter#ifdef HAVE_ZOS_PTHREADS 108251875Speter if (rv) { 109251875Speter rv = errno; 110251875Speter } 111251875Speter#endif 112251875Speter return rv; 113251875Speter} 114251875Speter 115251875SpeterAPR_DECLARE(apr_status_t) apr_thread_cond_broadcast(apr_thread_cond_t *cond) 116251875Speter{ 117251875Speter apr_status_t rv; 118251875Speter 119251875Speter rv = pthread_cond_broadcast(&cond->cond); 120251875Speter#ifdef HAVE_ZOS_PTHREADS 121251875Speter if (rv) { 122251875Speter rv = errno; 123251875Speter } 124251875Speter#endif 125251875Speter return rv; 126251875Speter} 127251875Speter 128251875SpeterAPR_DECLARE(apr_status_t) apr_thread_cond_destroy(apr_thread_cond_t *cond) 129251875Speter{ 130251875Speter return apr_pool_cleanup_run(cond->pool, cond, thread_cond_cleanup); 131251875Speter} 132251875Speter 133251875SpeterAPR_POOL_IMPLEMENT_ACCESSOR(thread_cond) 134251875Speter 135251875Speter#endif /* APR_HAS_THREADS */ 136