fdqueue.c revision 43c3e6a4b559b76b750c245ee95e2782c15b4296
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer * applicable.
6b26240dca29e026900a83d51c75ca230a072a16Thiemo Wiedemeyer *
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer * Licensed under the Apache License, Version 2.0 (the "License");
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer * you may not use this file except in compliance with the License.
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer * You may obtain a copy of the License at
2eeec5240b424984e3ee26296da1eeab6c6d739eChristian Maeder *
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer * http://www.apache.org/licenses/LICENSE-2.0
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer *
7520452bb30b5abbd471f82352fc4c1c937e02c5Till Mossakowski * Unless required by applicable law or agreed to in writing, software
7520452bb30b5abbd471f82352fc4c1c937e02c5Till Mossakowski * distributed under the License is distributed on an "AS IS" BASIS,
7520452bb30b5abbd471f82352fc4c1c937e02c5Till Mossakowski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer * See the License for the specific language governing permissions and
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer * limitations under the License.
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer */
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer#include "fdqueue.h"
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer#include "apr_atomic.h"
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyertypedef struct recycled_pool
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer{
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer apr_pool_t *pool;
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer struct recycled_pool *next;
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer} recycled_pool;
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyerstruct fd_queue_info_t
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer{
38122cbf09ad3dcc31a826cc4093f630515a5cfcChristian Maeder apr_int32_t idlers; /**
83263d411f611d9902ef4d98c93be6ad9361c833Christian Maeder * 0 or positive: number of idle worker threads
521045d36343cd17dd217a81d4b9422ad6ab6a07Christian Maeder * negative: number of threads blocked waiting
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer * for an idle worker
0193c86704431f83731015a77cb613d67ae4e3c2Thiemo Wiedemeyer */
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer apr_thread_mutex_t *idlers_mutex;
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer apr_thread_cond_t *wait_for_idler;
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer int terminated;
8836fa284a241af325aa6f41234b5130b26ec4f9Thiemo Wiedemeyer int max_idlers;
8836fa284a241af325aa6f41234b5130b26ec4f9Thiemo Wiedemeyer recycled_pool *recycled_pools;
8836fa284a241af325aa6f41234b5130b26ec4f9Thiemo Wiedemeyer};
331603b37dec12e37e2e1df9634ef0f2c5c73ddfThiemo Wiedemeyer
7ae38566aaf40710cd83ffa3ba25655c4ad22741Thiemo Wiedemeyerstatic apr_status_t queue_info_cleanup(void *data_)
1a389234e68da7c3d087b038307ed8c66fc6dc32Thiemo Wiedemeyer{
38122cbf09ad3dcc31a826cc4093f630515a5cfcChristian Maeder fd_queue_info_t *qi = data_;
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer apr_thread_cond_destroy(qi->wait_for_idler);
02a84229da51532505a93fc2abfca1ccf81b4446Razvan Pascanu apr_thread_mutex_destroy(qi->idlers_mutex);
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer /* Clean up any pools in the recycled list */
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer for (;;) {
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer struct recycled_pool *first_pool = qi->recycled_pools;
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer if (first_pool == NULL) {
1842453990fed8a1bd7a5ac792d7982c1d2bfcd5Christian Maeder break;
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer }
b6a59f004903ac7bc96323ee3ef09c01fd221157Christian Maeder if (apr_atomic_casptr
8a1077f446e5a0e127e0805e2c1efe6bf5eeb0d8Christian Maeder ((volatile void **) &(qi->recycled_pools), first_pool->next,
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer first_pool) == first_pool) {
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer apr_pool_destroy(first_pool->pool);
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer }
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer }
36f69d35e01d2d6b6bdc165b49661f2a80af8687Mihai Codescu
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer return APR_SUCCESS;
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer}
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyerapr_status_t ap_queue_info_create(fd_queue_info_t ** queue_info,
d1066b8fb69179973dcab47154858d77e72760a7Thiemo Wiedemeyer apr_pool_t * pool, int max_idlers)
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer{
4e9e95ba35a68f3c767bc0b23ebf9e904e442517Christian Maeder apr_status_t rv;
4e9e95ba35a68f3c767bc0b23ebf9e904e442517Christian Maeder fd_queue_info_t *qi;
4e9e95ba35a68f3c767bc0b23ebf9e904e442517Christian Maeder
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer qi = apr_palloc(pool, sizeof(*qi));
79d103748927615310322af6f7806c7cef11a802Christian Maeder memset(qi, 0, sizeof(*qi));
ecd98975b8a8ab5a7bc075562bdab51cf47d2a90Christian Maeder
f9e0b18852b238ddb649d341194e05d7200d1bbeChristian Maeder rv = apr_thread_mutex_create(&qi->idlers_mutex, APR_THREAD_MUTEX_DEFAULT,
697e63e30aa3c309a1ef1f9357745111f8dfc5a9Christian Maeder pool);
1e3aca4178372af672efb237d16087c603fe5564Christian Maeder if (rv != APR_SUCCESS) {
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer return rv;
4b136ad539bd9f4e115dff4eee4d552a42d4437eChristian Maeder }
f456529a89bfb620d39e5fd5b0a53b24643db96dDominik Luecke rv = apr_thread_cond_create(&qi->wait_for_idler, pool);
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer if (rv != APR_SUCCESS) {
4c8d3c5a9e938633f6147b5a595b9b93bfca99e6Christian Maeder return rv;
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer }
c745add71930134bc085a544783213179bd3e734Thiemo Wiedemeyer qi->recycled_pools = NULL;
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer qi->max_idlers = max_idlers;
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer apr_pool_cleanup_register(pool, qi, queue_info_cleanup,
93eeaffa1087fc6eae3f19b8ca5affb7802799fdThiemo Wiedemeyer apr_pool_cleanup_null);
02a84229da51532505a93fc2abfca1ccf81b4446Razvan Pascanu
1ac36418f204bbe56f4cd951a979180721758999Christian Maeder *queue_info = qi;
2028dc2c091bb60343e15985948a59b955276cbfChristian Maeder
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer return APR_SUCCESS;
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer}
16e45483b5ce48f0b92d01c817242a8c9b8bae02Christian Maeder
40b73e7d13a858afeac95321fcdb9ac216bfbf01Thiemo Wiedemeyerapr_status_t ap_queue_info_set_idle(fd_queue_info_t * queue_info,
ddc662fdf0207eae2034d7b68ae5e2225c575207Thiemo Wiedemeyer apr_pool_t * pool_to_recycle)
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer{
28ca54b0d63d1d26a991711c8c7e85c474994715Christian Maeder apr_status_t rv;
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu int prev_idlers;
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu
02a84229da51532505a93fc2abfca1ccf81b4446Razvan Pascanu ap_push_pool(queue_info, pool_to_recycle);
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer /* Atomically increment the count of idle workers */
331603b37dec12e37e2e1df9634ef0f2c5c73ddfThiemo Wiedemeyer prev_idlers = apr_atomic_inc32(&(queue_info->idlers));
331603b37dec12e37e2e1df9634ef0f2c5c73ddfThiemo Wiedemeyer
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer /* If other threads are waiting on a worker, wake one up */
331603b37dec12e37e2e1df9634ef0f2c5c73ddfThiemo Wiedemeyer if (prev_idlers < 0) {
331603b37dec12e37e2e1df9634ef0f2c5c73ddfThiemo Wiedemeyer rv = apr_thread_mutex_lock(queue_info->idlers_mutex);
331603b37dec12e37e2e1df9634ef0f2c5c73ddfThiemo Wiedemeyer if (rv != APR_SUCCESS) {
331603b37dec12e37e2e1df9634ef0f2c5c73ddfThiemo Wiedemeyer AP_DEBUG_ASSERT(0);
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer return rv;
331603b37dec12e37e2e1df9634ef0f2c5c73ddfThiemo Wiedemeyer }
03bbcb1fefdbd8bc4e8329ca2688809d84aff0a9Christian Maeder rv = apr_thread_cond_signal(queue_info->wait_for_idler);
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer if (rv != APR_SUCCESS) {
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer apr_thread_mutex_unlock(queue_info->idlers_mutex);
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer return rv;
03bbcb1fefdbd8bc4e8329ca2688809d84aff0a9Christian Maeder }
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer rv = apr_thread_mutex_unlock(queue_info->idlers_mutex);
1ac36418f204bbe56f4cd951a979180721758999Christian Maeder if (rv != APR_SUCCESS) {
331603b37dec12e37e2e1df9634ef0f2c5c73ddfThiemo Wiedemeyer return rv;
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer }
c40b7badd217089d8a256dabdf8f7d4e219ca215Thiemo Wiedemeyer }
d71a37fb09bce02af6c98e7a5ab0aa5639058e4fThiemo Wiedemeyer
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu return APR_SUCCESS;
0b8b26a22f136a9b2a8e99d655f6fe6b0b96008cThiemo Wiedemeyer}
0b8b26a22f136a9b2a8e99d655f6fe6b0b96008cThiemo Wiedemeyer
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanuapr_status_t ap_queue_info_wait_for_idler(fd_queue_info_t * queue_info)
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer{
d71a37fb09bce02af6c98e7a5ab0aa5639058e4fThiemo Wiedemeyer apr_status_t rv;
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer int prev_idlers;
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer
0b8b26a22f136a9b2a8e99d655f6fe6b0b96008cThiemo Wiedemeyer /* Atomically decrement the idle worker count, saving the old value */
0b8b26a22f136a9b2a8e99d655f6fe6b0b96008cThiemo Wiedemeyer prev_idlers = apr_atomic_add32(&(queue_info->idlers), -1);
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer /* Block if there weren't any idle workers */
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer if (prev_idlers <= 0) {
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer rv = apr_thread_mutex_lock(queue_info->idlers_mutex);
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer if (rv != APR_SUCCESS) {
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer AP_DEBUG_ASSERT(0);
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer apr_atomic_inc32(&(queue_info->idlers)); /* back out dec */
d71a37fb09bce02af6c98e7a5ab0aa5639058e4fThiemo Wiedemeyer return rv;
0b8b26a22f136a9b2a8e99d655f6fe6b0b96008cThiemo Wiedemeyer }
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer /* Re-check the idle worker count to guard against a
aa07f9c4585a94514dcff2979d853d6e04c12fb9Thiemo Wiedemeyer * race condition. Now that we're in the mutex-protected
5044e8de9e6fde7a139a5e34324c92a4d08a6e73Thiemo Wiedemeyer * region, one of two things may have happened:
aa07f9c4585a94514dcff2979d853d6e04c12fb9Thiemo Wiedemeyer * - If the idle worker count is still negative, the
8836fa284a241af325aa6f41234b5130b26ec4f9Thiemo Wiedemeyer * workers are all still busy, so it's safe to
aa07f9c4585a94514dcff2979d853d6e04c12fb9Thiemo Wiedemeyer * block on a condition variable.
8836fa284a241af325aa6f41234b5130b26ec4f9Thiemo Wiedemeyer * - If the idle worker count is non-negative, then a
8836fa284a241af325aa6f41234b5130b26ec4f9Thiemo Wiedemeyer * worker has become idle since the first check
8836fa284a241af325aa6f41234b5130b26ec4f9Thiemo Wiedemeyer * of queue_info->idlers above. It's possible
86b2d79be961f0247a2eed10ed4f86d8d6a7639dChristian Maeder * that the worker has also signaled the condition
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer * variable--and if so, the listener missed it
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer * because it wasn't yet blocked on the condition
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer * variable. But if the idle worker count is
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer * now non-negative, it's safe for this function to
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer * return immediately.
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer *
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer * A negative value in queue_info->idlers tells how many
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer * threads are waiting on an idle worker.
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer */
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer if (queue_info->idlers < 0) {
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer rv = apr_thread_cond_wait(queue_info->wait_for_idler,
d71a37fb09bce02af6c98e7a5ab0aa5639058e4fThiemo Wiedemeyer queue_info->idlers_mutex);
d71a37fb09bce02af6c98e7a5ab0aa5639058e4fThiemo Wiedemeyer if (rv != APR_SUCCESS) {
d71a37fb09bce02af6c98e7a5ab0aa5639058e4fThiemo Wiedemeyer apr_status_t rv2;
d71a37fb09bce02af6c98e7a5ab0aa5639058e4fThiemo Wiedemeyer AP_DEBUG_ASSERT(0);
d71a37fb09bce02af6c98e7a5ab0aa5639058e4fThiemo Wiedemeyer rv2 = apr_thread_mutex_unlock(queue_info->idlers_mutex);
d71a37fb09bce02af6c98e7a5ab0aa5639058e4fThiemo Wiedemeyer if (rv2 != APR_SUCCESS) {
d71a37fb09bce02af6c98e7a5ab0aa5639058e4fThiemo Wiedemeyer return rv2;
d71a37fb09bce02af6c98e7a5ab0aa5639058e4fThiemo Wiedemeyer }
d71a37fb09bce02af6c98e7a5ab0aa5639058e4fThiemo Wiedemeyer return rv;
d71a37fb09bce02af6c98e7a5ab0aa5639058e4fThiemo Wiedemeyer }
d71a37fb09bce02af6c98e7a5ab0aa5639058e4fThiemo Wiedemeyer }
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer rv = apr_thread_mutex_unlock(queue_info->idlers_mutex);
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer if (rv != APR_SUCCESS) {
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer return rv;
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer }
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer }
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer if (queue_info->terminated) {
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer return APR_EOF;
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer }
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer else {
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer return APR_SUCCESS;
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer }
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer}
d9f20cf968e246ec283f0c09f60af4b47b174398Thiemo Wiedemeyer
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyervoid ap_push_pool(fd_queue_info_t * queue_info,
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer apr_pool_t * pool_to_recycle)
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer{
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer /* If we have been given a pool to recycle, atomically link
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer * it into the queue_info's list of recycled pools
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer */
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer if (pool_to_recycle) {
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer struct recycled_pool *new_recycle;
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer new_recycle = (struct recycled_pool *) apr_palloc(pool_to_recycle,
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer sizeof
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer (*new_recycle));
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer new_recycle->pool = pool_to_recycle;
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer for (;;) {
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer new_recycle->next = queue_info->recycled_pools;
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer if (apr_atomic_casptr
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer ((volatile void **) &(queue_info->recycled_pools),
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer new_recycle, new_recycle->next) == new_recycle->next) {
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer break;
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer }
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer }
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer }
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer}
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyervoid ap_pop_pool(apr_pool_t ** recycled_pool, fd_queue_info_t * queue_info)
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer{
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer /* Atomically pop a pool from the recycled list */
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer
aa21e7aa42fef563dea0cc77edbde76f66cdbe88Thiemo Wiedemeyer /* This function is safe only as long as it is single threaded because
d9f20cf968e246ec283f0c09f60af4b47b174398Thiemo Wiedemeyer * it reaches into the queue and accesses "next" which can change.
d9f20cf968e246ec283f0c09f60af4b47b174398Thiemo Wiedemeyer * We are OK today because it is only called from the listener thread.
d9f20cf968e246ec283f0c09f60af4b47b174398Thiemo Wiedemeyer * cas-based pushes do not have the same limitation - any number can
d9f20cf968e246ec283f0c09f60af4b47b174398Thiemo Wiedemeyer * happen concurrently with a single cas-based pop.
d9f20cf968e246ec283f0c09f60af4b47b174398Thiemo Wiedemeyer */
d9f20cf968e246ec283f0c09f60af4b47b174398Thiemo Wiedemeyer
d9f20cf968e246ec283f0c09f60af4b47b174398Thiemo Wiedemeyer *recycled_pool = NULL;
d9f20cf968e246ec283f0c09f60af4b47b174398Thiemo Wiedemeyer
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer
84ba39232a012abf2085c8a421ebce6abc52d56eThiemo Wiedemeyer /* Atomically pop a pool from the recycled list */
d71a37fb09bce02af6c98e7a5ab0aa5639058e4fThiemo Wiedemeyer for (;;) {
d71a37fb09bce02af6c98e7a5ab0aa5639058e4fThiemo Wiedemeyer struct recycled_pool *first_pool = queue_info->recycled_pools;
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer if (first_pool == NULL) {
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer break;
3e3efd4ce838940032e875e6d08712a177c9c1d0Thiemo Wiedemeyer }
3e3efd4ce838940032e875e6d08712a177c9c1d0Thiemo Wiedemeyer if (apr_atomic_casptr
3e3efd4ce838940032e875e6d08712a177c9c1d0Thiemo Wiedemeyer ((volatile void **) &(queue_info->recycled_pools),
3e3efd4ce838940032e875e6d08712a177c9c1d0Thiemo Wiedemeyer first_pool->next, first_pool) == first_pool) {
3e3efd4ce838940032e875e6d08712a177c9c1d0Thiemo Wiedemeyer *recycled_pool = first_pool->pool;
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer break;
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer }
370e81d7af7821f0ac6ee0643613e87a727841e7Thiemo Wiedemeyer }
1ac36418f204bbe56f4cd951a979180721758999Christian Maeder}
1ac36418f204bbe56f4cd951a979180721758999Christian Maeder
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyerapr_status_t ap_queue_info_term(fd_queue_info_t * queue_info)
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer{
1ac36418f204bbe56f4cd951a979180721758999Christian Maeder apr_status_t rv;
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer rv = apr_thread_mutex_lock(queue_info->idlers_mutex);
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer if (rv != APR_SUCCESS) {
1ac36418f204bbe56f4cd951a979180721758999Christian Maeder return rv;
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer }
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer queue_info->terminated = 1;
370e81d7af7821f0ac6ee0643613e87a727841e7Thiemo Wiedemeyer apr_thread_cond_broadcast(queue_info->wait_for_idler);
370e81d7af7821f0ac6ee0643613e87a727841e7Thiemo Wiedemeyer return apr_thread_mutex_unlock(queue_info->idlers_mutex);
84ba39232a012abf2085c8a421ebce6abc52d56eThiemo Wiedemeyer}
370e81d7af7821f0ac6ee0643613e87a727841e7Thiemo Wiedemeyer
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer/**
370e81d7af7821f0ac6ee0643613e87a727841e7Thiemo Wiedemeyer * Detects when the fd_queue_t is full. This utility function is expected
370e81d7af7821f0ac6ee0643613e87a727841e7Thiemo Wiedemeyer * to be called from within critical sections, and is not threadsafe.
370e81d7af7821f0ac6ee0643613e87a727841e7Thiemo Wiedemeyer */
370e81d7af7821f0ac6ee0643613e87a727841e7Thiemo Wiedemeyer#define ap_queue_full(queue) ((queue)->nelts == (queue)->bounds)
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer/**
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer * Detects when the fd_queue_t is empty. This utility function is expected
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer * to be called from within critical sections, and is not threadsafe.
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer */
1ac36418f204bbe56f4cd951a979180721758999Christian Maeder#define ap_queue_empty(queue) ((queue)->nelts == 0)
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer/**
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer * Callback routine that is called to destroy this
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer * fd_queue_t when its pool is destroyed.
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer */
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyerstatic apr_status_t ap_queue_destroy(void *data)
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer{
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer fd_queue_t *queue = data;
84ba39232a012abf2085c8a421ebce6abc52d56eThiemo Wiedemeyer
370e81d7af7821f0ac6ee0643613e87a727841e7Thiemo Wiedemeyer /* Ignore errors here, we can't do anything about them anyway.
84ba39232a012abf2085c8a421ebce6abc52d56eThiemo Wiedemeyer * XXX: We should at least try to signal an error here, it is
1ac36418f204bbe56f4cd951a979180721758999Christian Maeder * indicative of a programmer error. -aaron */
370e81d7af7821f0ac6ee0643613e87a727841e7Thiemo Wiedemeyer apr_thread_cond_destroy(queue->not_empty);
84ba39232a012abf2085c8a421ebce6abc52d56eThiemo Wiedemeyer apr_thread_mutex_destroy(queue->one_big_mutex);
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer return APR_SUCCESS;
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer}
370e81d7af7821f0ac6ee0643613e87a727841e7Thiemo Wiedemeyer
545d0cd78159cade346b579d06052638b19b0f72Thiemo Wiedemeyer/**
1a389234e68da7c3d087b038307ed8c66fc6dc32Thiemo Wiedemeyer * Initialize the fd_queue_t.
1a389234e68da7c3d087b038307ed8c66fc6dc32Thiemo Wiedemeyer */
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyerapr_status_t ap_queue_init(fd_queue_t * queue, int queue_capacity,
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer apr_pool_t * a)
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu{
a4e6fb26100f53e3b1e9f5b97c2e0a0c129294e5Christian Maeder int i;
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu apr_status_t rv;
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu if ((rv = apr_thread_mutex_create(&queue->one_big_mutex,
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer APR_THREAD_MUTEX_DEFAULT,
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer a)) != APR_SUCCESS) {
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu return rv;
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu }
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu if ((rv = apr_thread_cond_create(&queue->not_empty, a)) != APR_SUCCESS) {
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer return rv;
1a389234e68da7c3d087b038307ed8c66fc6dc32Thiemo Wiedemeyer }
1a389234e68da7c3d087b038307ed8c66fc6dc32Thiemo Wiedemeyer
8836fa284a241af325aa6f41234b5130b26ec4f9Thiemo Wiedemeyer queue->data = apr_palloc(a, queue_capacity * sizeof(fd_queue_elem_t));
8836fa284a241af325aa6f41234b5130b26ec4f9Thiemo Wiedemeyer queue->bounds = queue_capacity;
8836fa284a241af325aa6f41234b5130b26ec4f9Thiemo Wiedemeyer queue->nelts = 0;
8836fa284a241af325aa6f41234b5130b26ec4f9Thiemo Wiedemeyer
8836fa284a241af325aa6f41234b5130b26ec4f9Thiemo Wiedemeyer /* Set all the sockets in the queue to NULL */
37e30366abd83c00a5d5447b45694627fd783de8Cui Jian for (i = 0; i < queue_capacity; ++i)
da955132262baab309a50fdffe228c9efe68251dCui Jian queue->data[i].sd = NULL;
37e30366abd83c00a5d5447b45694627fd783de8Cui Jian
37e30366abd83c00a5d5447b45694627fd783de8Cui Jian apr_pool_cleanup_register(a, queue, ap_queue_destroy,
37e30366abd83c00a5d5447b45694627fd783de8Cui Jian apr_pool_cleanup_null);
37e30366abd83c00a5d5447b45694627fd783de8Cui Jian
8836fa284a241af325aa6f41234b5130b26ec4f9Thiemo Wiedemeyer return APR_SUCCESS;
370e81d7af7821f0ac6ee0643613e87a727841e7Thiemo Wiedemeyer}
370e81d7af7821f0ac6ee0643613e87a727841e7Thiemo Wiedemeyer
370e81d7af7821f0ac6ee0643613e87a727841e7Thiemo Wiedemeyer/**
370e81d7af7821f0ac6ee0643613e87a727841e7Thiemo Wiedemeyer * Push a new socket onto the queue.
1842453990fed8a1bd7a5ac792d7982c1d2bfcd5Christian Maeder *
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer * precondition: ap_queue_info_wait_for_idler has already been called
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer * to reserve an idle worker thread
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer */
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyerapr_status_t ap_queue_push(fd_queue_t * queue, apr_socket_t * sd,
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu conn_state_t * cs, apr_pool_t * p)
a4e6fb26100f53e3b1e9f5b97c2e0a0c129294e5Christian Maeder{
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu fd_queue_elem_t *elem;
a4e6fb26100f53e3b1e9f5b97c2e0a0c129294e5Christian Maeder apr_status_t rv;
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer if ((rv = apr_thread_mutex_lock(queue->one_big_mutex)) != APR_SUCCESS) {
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer return rv;
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer }
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer
109b67ffce2bad83667e2f4a319d2d7f380f91afThiemo Wiedemeyer AP_DEBUG_ASSERT(!queue->terminated);
66fd8f017efdb8a6c862c3f1856dfaef90865dd5Thiemo Wiedemeyer AP_DEBUG_ASSERT(!ap_queue_full(queue));
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer elem = &queue->data[queue->nelts];
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu elem->sd = sd;
a4e6fb26100f53e3b1e9f5b97c2e0a0c129294e5Christian Maeder elem->cs = cs;
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu elem->p = p;
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu queue->nelts++;
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer apr_thread_cond_signal(queue->not_empty);
d1066b8fb69179973dcab47154858d77e72760a7Thiemo Wiedemeyer
d1066b8fb69179973dcab47154858d77e72760a7Thiemo Wiedemeyer if ((rv = apr_thread_mutex_unlock(queue->one_big_mutex)) != APR_SUCCESS) {
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer return rv;
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer }
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer return APR_SUCCESS;
d1066b8fb69179973dcab47154858d77e72760a7Thiemo Wiedemeyer}
d1066b8fb69179973dcab47154858d77e72760a7Thiemo Wiedemeyer
d1066b8fb69179973dcab47154858d77e72760a7Thiemo Wiedemeyer/**
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer * Retrieves the next available socket from the queue. If there are no
d1066b8fb69179973dcab47154858d77e72760a7Thiemo Wiedemeyer * sockets available, it will block until one becomes available.
d1066b8fb69179973dcab47154858d77e72760a7Thiemo Wiedemeyer * Once retrieved, the socket is placed into the address specified by
5107ba7da675778f2fded68493512b60eff8a455Christian Maeder * 'sd'.
966a6c024c828387023fccb0cd0049f78687e5dcThiemo Wiedemeyer */
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanuapr_status_t ap_queue_pop(fd_queue_t * queue, apr_socket_t ** sd,
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu conn_state_t ** cs, apr_pool_t ** p)
5107ba7da675778f2fded68493512b60eff8a455Christian Maeder{
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu fd_queue_elem_t *elem;
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu apr_status_t rv;
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu
966a6c024c828387023fccb0cd0049f78687e5dcThiemo Wiedemeyer if ((rv = apr_thread_mutex_lock(queue->one_big_mutex)) != APR_SUCCESS) {
0dba5bbaaef2f620f3b83a16ab6b229c3dd50c98Christian Maeder return rv;
0dba5bbaaef2f620f3b83a16ab6b229c3dd50c98Christian Maeder }
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer /* Keep waiting until we wake up and find that the queue is not empty. */
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer if (ap_queue_empty(queue)) {
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer if (!queue->terminated) {
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer apr_thread_cond_wait(queue->not_empty, queue->one_big_mutex);
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer }
a4e6fb26100f53e3b1e9f5b97c2e0a0c129294e5Christian Maeder /* If we wake up and it's still empty, then we were interrupted */
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer if (ap_queue_empty(queue)) {
28ca54b0d63d1d26a991711c8c7e85c474994715Christian Maeder rv = apr_thread_mutex_unlock(queue->one_big_mutex);
1e3aca4178372af672efb237d16087c603fe5564Christian Maeder if (rv != APR_SUCCESS) {
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer return rv;
370e81d7af7821f0ac6ee0643613e87a727841e7Thiemo Wiedemeyer }
ddc662fdf0207eae2034d7b68ae5e2225c575207Thiemo Wiedemeyer if (queue->terminated) {
44c1fff98bd6c54db237bef5030657d3f47058a5Thiemo Wiedemeyer return APR_EOF; /* no more elements ever again */
28ca54b0d63d1d26a991711c8c7e85c474994715Christian Maeder }
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu else {
a4e6fb26100f53e3b1e9f5b97c2e0a0c129294e5Christian Maeder return APR_EINTR;
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu }
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu }
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu }
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu
c40b7badd217089d8a256dabdf8f7d4e219ca215Thiemo Wiedemeyer elem = &queue->data[--queue->nelts];
1ac36418f204bbe56f4cd951a979180721758999Christian Maeder *sd = elem->sd;
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer *cs = elem->cs;
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer *p = elem->p;
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer#ifdef AP_DEBUG
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer elem->sd = NULL;
1ac36418f204bbe56f4cd951a979180721758999Christian Maeder elem->p = NULL;
c40b7badd217089d8a256dabdf8f7d4e219ca215Thiemo Wiedemeyer#endif /* AP_DEBUG */
966a6c024c828387023fccb0cd0049f78687e5dcThiemo Wiedemeyer
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu rv = apr_thread_mutex_unlock(queue->one_big_mutex);
83263d411f611d9902ef4d98c93be6ad9361c833Christian Maeder return rv;
1e3aca4178372af672efb237d16087c603fe5564Christian Maeder}
c40b7badd217089d8a256dabdf8f7d4e219ca215Thiemo Wiedemeyer
c40b7badd217089d8a256dabdf8f7d4e219ca215Thiemo Wiedemeyerapr_status_t ap_queue_interrupt_all(fd_queue_t * queue)
966a6c024c828387023fccb0cd0049f78687e5dcThiemo Wiedemeyer{
966a6c024c828387023fccb0cd0049f78687e5dcThiemo Wiedemeyer apr_status_t rv;
79d103748927615310322af6f7806c7cef11a802Christian Maeder
c40b7badd217089d8a256dabdf8f7d4e219ca215Thiemo Wiedemeyer if ((rv = apr_thread_mutex_lock(queue->one_big_mutex)) != APR_SUCCESS) {
c40b7badd217089d8a256dabdf8f7d4e219ca215Thiemo Wiedemeyer return rv;
4b136ad539bd9f4e115dff4eee4d552a42d4437eChristian Maeder }
83263d411f611d9902ef4d98c93be6ad9361c833Christian Maeder apr_thread_cond_broadcast(queue->not_empty);
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu return apr_thread_mutex_unlock(queue->one_big_mutex);
28ca54b0d63d1d26a991711c8c7e85c474994715Christian Maeder}
83263d411f611d9902ef4d98c93be6ad9361c833Christian Maeder
83263d411f611d9902ef4d98c93be6ad9361c833Christian Maederapr_status_t ap_queue_term(fd_queue_t * queue)
83263d411f611d9902ef4d98c93be6ad9361c833Christian Maeder{
83263d411f611d9902ef4d98c93be6ad9361c833Christian Maeder apr_status_t rv;
71654489020a03cf6ce9f2947f3da26a996f9c32Razvan Pascanu
d71a37fb09bce02af6c98e7a5ab0aa5639058e4fThiemo Wiedemeyer if ((rv = apr_thread_mutex_lock(queue->one_big_mutex)) != APR_SUCCESS) {
966a6c024c828387023fccb0cd0049f78687e5dcThiemo Wiedemeyer return rv;
c40b7badd217089d8a256dabdf8f7d4e219ca215Thiemo Wiedemeyer }
1ac36418f204bbe56f4cd951a979180721758999Christian Maeder /* we must hold one_big_mutex when setting this... otherwise,
c40b7badd217089d8a256dabdf8f7d4e219ca215Thiemo Wiedemeyer * we could end up setting it and waking everybody up just after a
c40b7badd217089d8a256dabdf8f7d4e219ca215Thiemo Wiedemeyer * would-be popper checks it but right before they block
c40b7badd217089d8a256dabdf8f7d4e219ca215Thiemo Wiedemeyer */
c40b7badd217089d8a256dabdf8f7d4e219ca215Thiemo Wiedemeyer queue->terminated = 1;
c40b7badd217089d8a256dabdf8f7d4e219ca215Thiemo Wiedemeyer if ((rv = apr_thread_mutex_unlock(queue->one_big_mutex)) != APR_SUCCESS) {
1ac36418f204bbe56f4cd951a979180721758999Christian Maeder return rv;
4b136ad539bd9f4e115dff4eee4d552a42d4437eChristian Maeder }
c40b7badd217089d8a256dabdf8f7d4e219ca215Thiemo Wiedemeyer return ap_queue_interrupt_all(queue);
53e76316f409f6b1b57ed3d2e5cb9cfe1cb511e5Thiemo Wiedemeyer}
38122cbf09ad3dcc31a826cc4093f630515a5cfcChristian Maeder