Line data Source code
1 : /*
2 : * (C) Copyright 2010 Cezary Bartoszuk, Michał Stachurski, Rafał Rawicki
3 : *
4 : * This file is part of CoherentDB.
5 : *
6 : * CoherentDB is free software: you can redistribute it and/or modify it
7 : * under the terms of the GNU General Public License as published by
8 : * the Free Software Foundation, either version 3 of the License, or
9 : * (at your option) any later version.
10 : *
11 : * CoherentDB is distributed in the hope that it will be useful, but
12 : * WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : * General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU General Public
17 : * License along with CoherentDB. If not, see
18 : * http://www.gnu.org/licenses/.
19 : */
20 :
21 : #ifndef __COHERENT_NETSERVER_QUEUE_H__
22 : #define __COHERENT_NETSERVER_QUEUE_H__
23 :
24 : #include <memory>
25 : #include <deque>
26 : #include <boost/function.hpp>
27 : #include <boost/thread.hpp>
28 :
29 : namespace coherent
30 : {
31 : namespace netserver
32 : {
33 :
34 : template<typename element_t>
35 : class simple_ptr_wrapper
36 : {
37 : public:
38 : typedef element_t * ptr_t;
39 : };
40 :
41 : template<typename element_t>
42 : class no_wrapper
43 : {
44 : public:
45 : typedef element_t ptr_t;
46 : };
47 :
48 : // Synchronized queue. Stores pointers to `element_t` type elements
49 : // with producer-consumer synchronization on `pop` and `push`.
50 : // Exception safe.
51 : template <
52 : typename element_t,
53 : template <typename, typename> class container_template = ::std::deque,
54 : template <typename> class ptr_wrapper_template = simple_ptr_wrapper,
55 : template <typename> class allocator_template = ::std::allocator
56 : >
57 : class queue
58 : {
59 : public:
60 : typedef typename ptr_wrapper_template<element_t>::ptr_t element_ptr_t;
61 : typedef allocator_template<element_ptr_t> element_ptr_allocator_t;
62 : typedef container_template<element_ptr_t, element_ptr_allocator_t> container_t;
63 : private:
64 : typedef ::boost::mutex mutex_t;
65 : typedef ::boost::condition_variable condition_t;
66 : typedef ::boost::unique_lock<mutex_t> unique_lock_t;
67 : typedef ::boost::lock_guard<mutex_t> lock_guard_t;
68 : private:
69 : condition_t condition;
70 : mutex_t mutex;
71 : container_t container;
72 : public:
73 : queue();
74 : ~queue();
75 : element_ptr_t pop();
76 : void push(element_ptr_t element_ptr);
77 : bool empty();
78 : };
79 :
80 : template <
81 : typename element_t,
82 : template <typename, typename> class container_template,
83 : template <typename> class ptr_wrapper_template,
84 : template <typename> class allocator_template
85 : >
86 : queue<element_t, container_template, ptr_wrapper_template, allocator_template>::queue()
87 : : condition(),
88 : mutex(),
89 : container()
90 : {
91 : }
92 1 :
93 : template <
94 : typename element_t,
95 1 : template <typename, typename> class container_template,
96 : template <typename> class ptr_wrapper_template,
97 1 : template <typename> class allocator_template
98 : >
99 : queue<element_t, container_template, ptr_wrapper_template, allocator_template>::~queue()
100 : {
101 : }
102 :
103 : template <
104 : typename element_t,
105 : template <typename, typename> class container_template,
106 1 : template <typename> class ptr_wrapper_template,
107 : template <typename> class allocator_template
108 1 : >
109 : typename queue<element_t, container_template, ptr_wrapper_template, allocator_template>::element_ptr_t queue<element_t, container_template, ptr_wrapper_template, allocator_template>::pop()
110 : {
111 : unique_lock_t lock(mutex);
112 : while(container.empty())
113 : {
114 : condition.wait(lock);
115 : }
116 : element_ptr_t element_ptr = container.front();
117 10000 : container.pop_front();
118 : return element_ptr;
119 20000 : }
120 10000 :
121 : template <
122 0 : typename element_t,
123 : template <typename, typename> class container_template,
124 10000 : template <typename> class ptr_wrapper_template,
125 10000 : template <typename> class allocator_template
126 10000 : >
127 : void queue<element_t, container_template, ptr_wrapper_template, allocator_template>::push(element_ptr_t element_ptr)
128 : {
129 : {
130 : lock_guard_t lock(mutex);
131 : container.push_back(element_ptr);
132 : }
133 : condition.notify_one();
134 : }
135 :
136 10000 : template <
137 : typename element_t,
138 : template <typename, typename> class container_template,
139 20000 : template <typename> class ptr_wrapper_template,
140 10000 : template <typename> class allocator_template
141 : >
142 10000 : bool queue<element_t, container_template, ptr_wrapper_template, allocator_template>::empty()
143 10000 : {
144 : unique_lock_t lock(mutex);
145 : return container.empty();
146 : }
147 :
148 : } // namespace netserver
149 : } // namespace coherent
150 :
151 : #endif
|