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#ifndef APR_THREAD_COND_H 18251875Speter#define APR_THREAD_COND_H 19251875Speter 20251875Speter/** 21251875Speter * @file apr_thread_cond.h 22251875Speter * @brief APR Condition Variable Routines 23251875Speter */ 24251875Speter 25251875Speter#include "apr.h" 26251875Speter#include "apr_pools.h" 27251875Speter#include "apr_errno.h" 28251875Speter#include "apr_time.h" 29251875Speter#include "apr_thread_mutex.h" 30251875Speter 31251875Speter#ifdef __cplusplus 32251875Speterextern "C" { 33251875Speter#endif /* __cplusplus */ 34251875Speter 35251875Speter#if APR_HAS_THREADS || defined(DOXYGEN) 36251875Speter 37251875Speter/** 38251875Speter * @defgroup apr_thread_cond Condition Variable Routines 39251875Speter * @ingroup APR 40251875Speter * @{ 41251875Speter */ 42251875Speter 43251875Speter/** Opaque structure for thread condition variables */ 44251875Spetertypedef struct apr_thread_cond_t apr_thread_cond_t; 45251875Speter 46251875Speter/** 47251875Speter * Note: destroying a condition variable (or likewise, destroying or 48251875Speter * clearing the pool from which a condition variable was allocated) if 49251875Speter * any threads are blocked waiting on it gives undefined results. 50251875Speter */ 51251875Speter 52251875Speter/** 53251875Speter * Create and initialize a condition variable that can be used to signal 54251875Speter * and schedule threads in a single process. 55251875Speter * @param cond the memory address where the newly created condition variable 56251875Speter * will be stored. 57251875Speter * @param pool the pool from which to allocate the condition. 58251875Speter */ 59251875SpeterAPR_DECLARE(apr_status_t) apr_thread_cond_create(apr_thread_cond_t **cond, 60251875Speter apr_pool_t *pool); 61251875Speter 62251875Speter/** 63251875Speter * Put the active calling thread to sleep until signaled to wake up. Each 64251875Speter * condition variable must be associated with a mutex, and that mutex must 65251875Speter * be locked before calling this function, or the behavior will be 66251875Speter * undefined. As the calling thread is put to sleep, the given mutex 67251875Speter * will be simultaneously released; and as this thread wakes up the lock 68251875Speter * is again simultaneously acquired. 69251875Speter * @param cond the condition variable on which to block. 70251875Speter * @param mutex the mutex that must be locked upon entering this function, 71251875Speter * is released while the thread is asleep, and is again acquired before 72251875Speter * returning from this function. 73251875Speter * @remark Spurious wakeups may occur. Before and after every call to wait on 74251875Speter * a condition variable, the caller should test whether the condition is already 75251875Speter * met. 76251875Speter */ 77251875SpeterAPR_DECLARE(apr_status_t) apr_thread_cond_wait(apr_thread_cond_t *cond, 78251875Speter apr_thread_mutex_t *mutex); 79251875Speter 80251875Speter/** 81251875Speter * Put the active calling thread to sleep until signaled to wake up or 82251875Speter * the timeout is reached. Each condition variable must be associated 83251875Speter * with a mutex, and that mutex must be locked before calling this 84251875Speter * function, or the behavior will be undefined. As the calling thread 85251875Speter * is put to sleep, the given mutex will be simultaneously released; 86251875Speter * and as this thread wakes up the lock is again simultaneously acquired. 87251875Speter * @param cond the condition variable on which to block. 88251875Speter * @param mutex the mutex that must be locked upon entering this function, 89251875Speter * is released while the thread is asleep, and is again acquired before 90251875Speter * returning from this function. 91251875Speter * @param timeout The amount of time in microseconds to wait. This is 92251875Speter * a maximum, not a minimum. If the condition is signaled, we 93251875Speter * will wake up before this time, otherwise the error APR_TIMEUP 94251875Speter * is returned. 95251875Speter */ 96251875SpeterAPR_DECLARE(apr_status_t) apr_thread_cond_timedwait(apr_thread_cond_t *cond, 97251875Speter apr_thread_mutex_t *mutex, 98251875Speter apr_interval_time_t timeout); 99251875Speter 100251875Speter/** 101251875Speter * Signals a single thread, if one exists, that is blocking on the given 102251875Speter * condition variable. That thread is then scheduled to wake up and acquire 103251875Speter * the associated mutex. Although it is not required, if predictable scheduling 104251875Speter * is desired, that mutex must be locked while calling this function. 105251875Speter * @param cond the condition variable on which to produce the signal. 106251875Speter * @remark If no threads are waiting on the condition variable, nothing happens. 107251875Speter */ 108251875SpeterAPR_DECLARE(apr_status_t) apr_thread_cond_signal(apr_thread_cond_t *cond); 109251875Speter 110251875Speter/** 111251875Speter * Signals all threads blocking on the given condition variable. 112251875Speter * Each thread that was signaled is then scheduled to wake up and acquire 113251875Speter * the associated mutex. This will happen in a serialized manner. 114251875Speter * @param cond the condition variable on which to produce the broadcast. 115251875Speter * @remark If no threads are waiting on the condition variable, nothing happens. 116251875Speter */ 117251875SpeterAPR_DECLARE(apr_status_t) apr_thread_cond_broadcast(apr_thread_cond_t *cond); 118251875Speter 119251875Speter/** 120251875Speter * Destroy the condition variable and free the associated memory. 121251875Speter * @param cond the condition variable to destroy. 122251875Speter */ 123251875SpeterAPR_DECLARE(apr_status_t) apr_thread_cond_destroy(apr_thread_cond_t *cond); 124251875Speter 125251875Speter/** 126251875Speter * Get the pool used by this thread_cond. 127251875Speter * @return apr_pool_t the pool 128251875Speter */ 129251875SpeterAPR_POOL_DECLARE_ACCESSOR(thread_cond); 130251875Speter 131251875Speter#endif /* APR_HAS_THREADS */ 132251875Speter 133251875Speter/** @} */ 134251875Speter 135251875Speter#ifdef __cplusplus 136251875Speter} 137251875Speter#endif 138251875Speter 139251875Speter#endif /* ! APR_THREAD_COND_H */ 140