fdqueue.c revision db68a93b6f008d48ce1c50ab59e153969ea5dbcf
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek/* ====================================================================
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * The Apache Software License, Version 1.1
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
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 * 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 * 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 * 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.
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 * 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 * 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 * ====================================================================
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 * 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/* Assumption: queue itself is allocated by the user */
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek/* Assumption: increment and decrement are atomic on int */
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-Szmekint ap_queue_full(FDQueue *queue) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmekint ap_block_on_queue(FDQueue *queue) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek if (pthread_mutex_lock(&queue->one_big_mutex) != 0) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek pthread_cond_wait(&queue->not_full, &queue->one_big_mutex);
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmek if (pthread_mutex_unlock(&queue->one_big_mutex) != 0) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmekstatic int increase_blanks(FDQueue *queue) {
708c143c7cd2bbd748ac0fa993496ff44e72701cZbigniew Jędrzejewski-Szmekstatic apr_status_t ap_queue_destroy(void *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-Szmekint ap_queue_init(FDQueue *queue, int queue_capacity, apr_pool_t *a) {
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->data = apr_palloc(a, bounds * sizeof(FDQueueElement));
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-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->tail = (queue->tail + 1) % queue->bounds;
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek pthread_cond_signal(&queue->not_empty);
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek if (queue->head == (queue->tail + 1) % queue->bounds) {
dfdebb1b925332352966804303b2516a6506a429Zbigniew Jędrzejewski-Szmek pthread_cond_wait(&queue->not_full, &queue->one_big_mutex);
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 /* 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 if (queue->blanks > 0) {
86349ffe49092345269762e3274121133604c3d4Lennart Poettering pthread_cond_wait(&queue->not_empty, &queue->one_big_mutex);
d9130355ee0530117518ff24354bdd552d030238Lennart Poetteringfprintf(stderr, "Found a non-empty queue :-)\n");
781fa93815fafd02b5287ef5781b92ef7b99973bLennart Poettering queue->head = (queue->head + 1) % queue->bounds;
1fc5560911a7e9e8cf2993e17e1f0a001e148809Lennart Poetteringvoid ap_queue_signal_all_wakeup(FDQueue *queue)
1fc5560911a7e9e8cf2993e17e1f0a001e148809Lennart Poetteringfprintf(stderr, "trying to broadcast to all workers\n");