ClockWork DB CoreAPI 1.0.48
Abstract Time Series and Storage/Management Library
Loading...
Searching...
No Matches
shared_list.hpp
1#ifndef HAVE_TOM__SHARED_LIST_HPP
2#define HAVE_TOM__SHARED_LIST_HPP
3
4#include <tom-util/defines.hpp>
5
6#include <boost/thread/barrier.hpp>
7#include <boost/thread/thread.hpp>
8#include <boost/thread/condition.hpp>
9#include <boost/thread/xtime.hpp>
10#include <list>
11
12/*
13 The idea:
14 Structure where data T's can be FIFO'd safely across threads.
15 Structure is in one of several states:
16 Read/Write - writable / readable - Reads block if no-data available
17 Read Only - readable ONLY - if empty() then done!
18*/
19//TOM_NAMESPACE_BEGIN;
20namespace tom {
21
22 template <typename T>
23 class TOM_UTIL_API shared_list
24 {
25 public:
26 typedef T value_type;
27
28 shared_list() : m_read_only( false ) { }
29 virtual ~shared_list() { }
30
31 bool
32 empty();
33
34 void
35 set_read_only();
36
37 bool
38 read_only();
39
40 void
41 pop_front();
42
43 // fast fetch/pop w/o the need to check empty()
44 bool
45 pop_front( T & );
46
47 void
48 push_back( const T & );
49
50 T &
51 front();
52
53 const T &
54 front() const;
55
56 private:
57 typedef boost::mutex::scoped_lock lock;
58
59 bool m_read_only;
60 mutable boost::condition m_buffer_empty;
61 mutable boost::condition m_buffer_ready;
62 mutable boost::mutex m_monitor;
63
64// mutable std::list<T> m_list;
65 mutable std::list<T> m_list;
66 };
67
68 template <typename T>
69 void
71 {
72 lock l( m_monitor );
73
74 // if we are not read-only and empty, block until new data arrives
75 if ( ( ! m_read_only ) && m_list.empty() )
76 m_buffer_ready.wait(l);
77
78 if ( ! m_list.empty() )
79 m_list.pop_front();
80
81 }
82 // fast fetch/pop w/o the need to check empty()
83 template <typename T>
84 bool
85 shared_list<T>::pop_front( T &v )
86 {
87 lock l( m_monitor );
88
89 // if we are not read-only and empty, block until new data arrives
90 if ( ( ! m_read_only ) && m_list.empty() )
91 {
92 m_buffer_empty.notify_one();
93 m_buffer_ready.wait(l); // and wait for him to produce
94 }
95 if ( ! m_list.empty() )
96 {
97 v = m_list.front();
98 m_list.pop_front();
99 return true;
100 }
101 else
102 return false;
103 }
104 template <typename T>
105 void
106 shared_list<T>::push_back( const T &v )
107 {
108 // important thing if starvation happens!
109 boost::thread::thread::yield();
110
111 lock l( m_monitor );
112
113 // no pushing if we are read-only
114 if ( m_read_only )
115 return;
116
117
118 // if buffer is full we should wait on a condition of emptiness
119 if ( m_list.size() > 1000 ) // lets put the size into the template
120 {
121 // wait for the buffer to empty
122 m_buffer_empty.wait(l); // this unlocks the mutex/monitor
123 }
124 // if we are empty, we need to notify any
125 // blocked threads waiting to read
126 bool notify = m_list.empty() ? true : false;
127
128 // push the data on list
129 m_list.push_back( v );
130
131 // if it was empty notify we are ready!
132 if ( notify )
133 m_buffer_ready.notify_one();
134 }
135
136 template <typename T>
137 T &
138 shared_list<T>::front()
139 {
140 lock l( m_monitor );
141
142 // if we are not read-only and empty, block until new data arrives
143 if ( (! m_read_only ) && m_list.empty() )
144 m_buffer_ready.wait(l);
145
146 return m_list.front();
147 }
148
149 template <typename T>
150 const T &
151 shared_list<T>::front() const
152 {
153 lock l( m_monitor );
154
155 // if we are not read-only and empty, block until new data arrives
156 if ( (! m_read_only) && m_list.empty() )
157 m_buffer_ready.wait(l);
158
159 return m_list.front();
160 }
161 template <typename T>
162 bool
163 shared_list<T>::empty()
164 {
165 lock l( m_monitor );
166
167 // if we are not read-only and empty, block until new data arrives
168 if ( ( ! m_read_only ) && m_list.empty() )
169 m_buffer_ready.wait(l);
170
171 return m_list.empty();
172 }
173 template <typename T>
174 void
175 shared_list<T>::set_read_only()
176 {
177 lock l( m_monitor );
178 m_read_only = true;
179 m_buffer_ready.notify_one();
180 }
181
182//TOM_NAMESPACE_END;
183} // end tom namespace
184
185#endif
Definition shared_list.hpp:24