Annotation of embedaddon/strongswan/src/libstrongswan/collections/blocking_queue.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2012 Tobias Brunner
                      3:  * Copyright (C) 2012 Giuliano Grassi
                      4:  * Copyright (C) 2012 Ralf Sager
                      5:  * HSR Hochschule fuer Technik Rapperswil
                      6:  *
                      7:  * This program is free software; you can redistribute it and/or modify it
                      8:  * under the terms of the GNU General Public License as published by the
                      9:  * Free Software Foundation; either version 2 of the License, or (at your
                     10:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     11:  *
                     12:  * This program is distributed in the hope that it will be useful, but
                     13:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     14:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     15:  * for more details.
                     16:  */
                     17: 
                     18: #include "blocking_queue.h"
                     19: 
                     20: #include <threading/mutex.h>
                     21: #include <threading/thread.h>
                     22: #include <threading/condvar.h>
                     23: #include <collections/linked_list.h>
                     24: 
                     25: typedef struct private_blocking_queue_t private_blocking_queue_t;
                     26: 
                     27: /**
                     28:  * Private data of a blocking_queue_t object.
                     29:  */
                     30: struct private_blocking_queue_t {
                     31: 
                     32:        /**
                     33:         * Public part
                     34:         */
                     35:        blocking_queue_t public;
                     36: 
                     37:        /**
                     38:         * Linked list containing all items in the queue
                     39:         */
                     40:        linked_list_t *list;
                     41: 
                     42:        /**
                     43:         * Mutex used to synchronize access to the queue
                     44:         */
                     45:        mutex_t *mutex;
                     46: 
                     47:        /**
                     48:         * Condvar used to wait for items
                     49:         */
                     50:        condvar_t *condvar;
                     51: 
                     52: };
                     53: 
                     54: METHOD(blocking_queue_t, enqueue, void,
                     55:        private_blocking_queue_t *this, void *item)
                     56: {
                     57:        this->mutex->lock(this->mutex);
                     58:        this->list->insert_first(this->list, item);
                     59:        this->condvar->signal(this->condvar);
                     60:        this->mutex->unlock(this->mutex);
                     61: }
                     62: 
                     63: METHOD(blocking_queue_t, dequeue, void*,
                     64:        private_blocking_queue_t *this)
                     65: {
                     66:        bool oldstate;
                     67:        void *item;
                     68: 
                     69: 
                     70:        this->mutex->lock(this->mutex);
                     71:        thread_cleanup_push((thread_cleanup_t)this->mutex->unlock, this->mutex);
                     72:        /* ensure that a canceled thread does not dequeue any items */
                     73:        thread_cancellation_point();
                     74:        while (this->list->remove_last(this->list, &item) != SUCCESS)
                     75:        {
                     76:                oldstate = thread_cancelability(TRUE);
                     77:                this->condvar->wait(this->condvar, this->mutex);
                     78:                thread_cancelability(oldstate);
                     79:        }
                     80:        thread_cleanup_pop(TRUE);
                     81:        return item;
                     82: }
                     83: 
                     84: METHOD(blocking_queue_t, destroy, void,
                     85:        private_blocking_queue_t *this)
                     86: {
                     87:        this->list->destroy(this->list);
                     88:        this->condvar->destroy(this->condvar);
                     89:        this->mutex->destroy(this->mutex);
                     90:        free(this);
                     91: }
                     92: 
                     93: METHOD(blocking_queue_t, destroy_offset, void,
                     94:        private_blocking_queue_t *this, size_t offset)
                     95: {
                     96:        this->list->invoke_offset(this->list, offset);
                     97:        destroy(this);
                     98: }
                     99: 
                    100: METHOD(blocking_queue_t, destroy_function, void,
                    101:        private_blocking_queue_t *this, void (*fn)(void*))
                    102: {
                    103:        this->list->invoke_function(this->list, (linked_list_invoke_t)fn);
                    104:        destroy(this);
                    105: }
                    106: 
                    107: /*
                    108:  * Described in header.
                    109:  */
                    110: blocking_queue_t *blocking_queue_create()
                    111: {
                    112:        private_blocking_queue_t *this;
                    113: 
                    114:        INIT(this,
                    115:                .public = {
                    116:                        .enqueue = _enqueue,
                    117:                        .dequeue = _dequeue,
                    118:                        .destroy = _destroy,
                    119:                        .destroy_offset = _destroy_offset,
                    120:                        .destroy_function = _destroy_function,
                    121:                },
                    122:                .list = linked_list_create(),
                    123:                .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
                    124:                .condvar = condvar_create(CONDVAR_TYPE_DEFAULT),
                    125:        );
                    126: 
                    127:        return &this->public;
                    128: }
                    129: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>