fdqueue.c revision db68a93b6f008d48ce1c50ab59e153969ea5dbcf
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek/* ====================================================================
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * The Apache Software License, Version 1.1
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek *
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * reserved.
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek *
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * Redistribution and use in source and binary forms, with or without
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * modification, are permitted provided that the following conditions
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * are met:
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek *
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * 1. Redistributions of source code must retain the above copyright
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * notice, this list of conditions and the following disclaimer.
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek *
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * 2. Redistributions in binary form must reproduce the above copyright
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * notice, this list of conditions and the following disclaimer in
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * the documentation and/or other materials provided with the
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * distribution.
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek *
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * 3. The end-user documentation included with the redistribution,
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * if any, must include the following acknowledgment:
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * "This product includes software developed by the
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * Apache Software Foundation (http://www.apache.org/)."
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * Alternately, this acknowledgment may appear in the software itself,
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek * if and wherever such third-party acknowledgments normally appear.
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek *
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * 4. The names "Apache" and "Apache Software Foundation" must
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * not be used to endorse or promote products derived from this
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * software without prior written permission. For written
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * permission, please contact apache@apache.org.
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek *
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * 5. Products derived from this software may not be called "Apache",
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * nor may "Apache" appear in their name, without prior written
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * permission of the Apache Software Foundation.
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek *
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * SUCH DAMAGE.
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * ====================================================================
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek *
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * This software consists of voluntary contributions made by many
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * individuals on behalf of the Apache Software Foundation. For more
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * information on the Apache Software Foundation, please see
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * <http://www.apache.org/>.
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek *
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * Portions of this software are based upon public domain software
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * originally written at the National Center for Supercomputing Applications,
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * University of Illinois, Urbana-Champaign.
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek */
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek#include "fdqueue.h"
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek#include "apr_pools.h"
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek/* Assumption: queue itself is allocated by the user */
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek/* Assumption: increment and decrement are atomic on int */
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmekint ap_queue_size(FDQueue *queue) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek return ((queue->tail - queue->head + queue->bounds) % queue->bounds);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek}
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmekint ap_queue_full(FDQueue *queue) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek return(queue->blanks <= 0);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek}
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmekint ap_block_on_queue(FDQueue *queue) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek#if 0
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek if (pthread_mutex_lock(&queue->one_big_mutex) != 0) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek return FD_QUEUE_FAILURE;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek }
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek#endif
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek if (ap_queue_full(queue)) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek pthread_cond_wait(&queue->not_full, &queue->one_big_mutex);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek }
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek#if 0
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek if (pthread_mutex_unlock(&queue->one_big_mutex) != 0) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek return FD_QUEUE_FAILURE;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek }
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek#endif
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek return FD_QUEUE_SUCCESS;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek}
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmekstatic int increase_blanks(FDQueue *queue) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek queue->blanks++;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek return FD_QUEUE_SUCCESS;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek}
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmekstatic apr_status_t ap_queue_destroy(void *data) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek FDQueue *queue = data;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek /* Ignore errors here, we can't do anything about them anyway */
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek pthread_cond_destroy(&queue->not_empty);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek pthread_cond_destroy(&queue->not_full);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek pthread_mutex_destroy(&queue->one_big_mutex);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek return FD_QUEUE_SUCCESS;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek}
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmekint ap_queue_init(FDQueue *queue, int queue_capacity, apr_pool_t *a) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek int i;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek int bounds = queue_capacity + 1;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek pthread_mutex_init(&queue->one_big_mutex, NULL);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek pthread_cond_init(&queue->not_empty, NULL);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek pthread_cond_init(&queue->not_full, NULL);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek queue->head = queue->tail = 0;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek queue->data = apr_palloc(a, bounds * sizeof(FDQueueElement));
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek queue->bounds = bounds;
66f756d437658cc464bfb5647c97efd0cf77f933Jan Engelhardt queue->blanks = queue_capacity;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek apr_pool_cleanup_register(a, queue, ap_queue_destroy, apr_pool_cleanup_null);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek for (i=0; i < bounds; ++i)
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek queue->data[i].sd = NULL;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek return FD_QUEUE_SUCCESS;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek}
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmekint ap_queue_push(FDQueue *queue, apr_socket_t *sd, apr_pool_t *p) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek queue->data[queue->tail].sd = sd;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek queue->data[queue->tail].p = p;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek queue->tail = (queue->tail + 1) % queue->bounds;
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek queue->blanks--;
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek pthread_cond_signal(&queue->not_empty);
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek#if 0
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek if (queue->head == (queue->tail + 1) % queue->bounds) {
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek#endif
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek if (ap_queue_full(queue)) {
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek pthread_cond_wait(&queue->not_full, &queue->one_big_mutex);
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek }
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek return FD_QUEUE_SUCCESS;
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek}
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmekapr_status_t ap_queue_pop(FDQueue *queue, apr_socket_t **sd, apr_pool_t **p, int block_if_empty) {
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering increase_blanks(queue);
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering /* We have just removed one from the queue. By definition, it is
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering * no longer full. We can ALWAYS signal the listener thread at
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering * this point. However, the original code didn't do it this way,
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering * so I am leaving the original code in, just commented out. BTW,
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering * originally, the increase_blanks wasn't in this function either.
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering *
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering if (queue->blanks > 0) {
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering */
1f70b0876a9388f38422c12fa0c73761559d9425Lennart Poettering pthread_cond_signal(&queue->not_full);
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering /* } */
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering if (queue->head == queue->tail) {
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering if (block_if_empty) {
86349ffe49092345269762e3274121133604c3d4Lennart Poettering pthread_cond_wait(&queue->not_empty, &queue->one_big_mutex);
d9130355ee0530117518ff24354bdd552d030238Lennart Poetteringfprintf(stderr, "Found a non-empty queue :-)\n");
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering }
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering }
d9130355ee0530117518ff24354bdd552d030238Lennart Poettering
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering *sd = queue->data[queue->head].sd;
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering *p = queue->data[queue->head].p;
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering queue->data[queue->head].sd = NULL;
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering if (*sd != NULL) {
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering queue->head = (queue->head + 1) % queue->bounds;
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering }
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering return APR_SUCCESS;
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering}
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering
1fc5560911a7e9e8cf2993e17e1f0a001e148809Lennart Poetteringvoid ap_queue_signal_all_wakeup(FDQueue *queue)
1fc5560911a7e9e8cf2993e17e1f0a001e148809Lennart Poettering{
1fc5560911a7e9e8cf2993e17e1f0a001e148809Lennart Poetteringfprintf(stderr, "trying to broadcast to all workers\n");
1fc5560911a7e9e8cf2993e17e1f0a001e148809Lennart Poettering pthread_cond_broadcast(&queue->not_empty);
1fc5560911a7e9e8cf2993e17e1f0a001e148809Lennart Poettering}
1fc5560911a7e9e8cf2993e17e1f0a001e148809Lennart Poettering