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>