Orocos Real-Time Toolkit  2.8.3
ListLocked.hpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: Peter Soetens Thu Oct 22 11:59:08 CEST 2009 ListLocked.hpp
3 
4  ListLocked.hpp - description
5  -------------------
6  begin : Thu October 22 2009
7  copyright : (C) 2009 Peter Soetens
8  email : peter@thesourcworks.com
9 
10  ***************************************************************************
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU General Public *
13  * License as published by the Free Software Foundation; *
14  * version 2 of the License. *
15  * *
16  * As a special exception, you may use this file as part of a free *
17  * software library without restriction. Specifically, if other files *
18  * instantiate templates or use macros or inline functions from this *
19  * file, or you compile this file and link it with other files to *
20  * produce an executable, this file does not by itself cause the *
21  * resulting executable to be covered by the GNU General Public *
22  * License. This exception does not however invalidate any other *
23  * reasons why the executable file might be covered by the GNU General *
24  * Public License. *
25  * *
26  * This library is distributed in the hope that it will be useful, *
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
29  * Lesser General Public License for more details. *
30  * *
31  * You should have received a copy of the GNU General Public *
32  * License along with this library; if not, write to the Free Software *
33  * Foundation, Inc., 59 Temple Place, *
34  * Suite 330, Boston, MA 02111-1307 USA *
35  * *
36  ***************************************************************************/
37 
38 
39 
40 #ifndef ORO_LIST_LOCKED_HPP
41 #define ORO_LIST_LOCKED_HPP
42 
43 #include <boost/intrusive/list.hpp>
44 #include <boost/bind.hpp>
45 #include <boost/bind/protect.hpp>
46 #include <stack>
47 #include <vector>
48 #include <algorithm>
49 #include "../os/Mutex.hpp"
50 #include "../os/MutexLock.hpp"
51 
52 #ifdef ORO_PRAGMA_INTERFACE
53 #pragma interface
54 #endif
55 
56 namespace RTT
57 { namespace internal {
58 
71  template< class T>
72  class ListLocked
73  {
74  public:
75 
76  typedef T value_t;
77  private:
78  struct Cont : public boost::intrusive::list_base_hook<> {
79  T data;
80  };
81  typedef boost::intrusive::list<Cont> BufferType;
82  typedef std::stack<Cont*> StackType;
83  typedef typename BufferType::iterator Iterator;
84  typedef typename BufferType::const_iterator CIterator;
85 
86  BufferType mlist;
87  StackType mreserved;
88  unsigned int required;
89 
90  mutable os::MutexRecursive m;
91  public:
96  ListLocked(unsigned int lsize, unsigned int unused = 0 )
97  :required(lsize)
98  {
99  for(unsigned int i=0; i <lsize; ++i)
100  mreserved.push(new Cont());
101  }
102 
104  this->clear();
105  while( !mreserved.empty() ) {
106  delete mreserved.top();
107  mreserved.pop();
108  }
109  }
110 
111  size_t capacity() const
112  {
113  os::MutexLock lock(m);
114  return mreserved.size() + mlist.size();
115  }
116 
117  size_t size() const
118  {
119  os::MutexLock lock(m);
120  return mlist.size();
121  }
122 
123  bool empty() const
124  {
125  os::MutexLock lock(m);
126  return mlist.empty();
127  }
128 
136  void grow(size_t items = 1) {
137  os::MutexLock lock(m);
138  required += items;
139  if (required > mreserved.size() + mlist.size() ) {
140  while ( mreserved.size() + mlist.size() < required * 2) {
141  mreserved.push( new Cont() );
142  }
143  }
144  }
152  void shrink(size_t items = 1) {
153  os::MutexLock lock(m);
154  required -= items;
155  }
156 
163  void reserve(size_t lsize)
164  {
165  os::MutexLock lock(m);
166  while ( mreserved.size() + mlist.size() < lsize) {
167  mreserved.push( new Cont() );
168  }
169  }
170 
171  void clear()
172  {
173  os::MutexLock lock(m);
174  mlist.clear_and_dispose( boost::bind(&ListLocked::give_back, this, _1) );
175  }
176 
182  bool append( value_t item )
183  {
184  os::MutexLock lock(m);
185  if ( mreserved.empty() )
186  return false;
187  mlist.push_back( this->get_item(item) );
188  return true;
189  }
190 
194  value_t front() const
195  {
196  os::MutexLock lock(m);
197  return mlist.front().data;
198  }
199 
203  value_t back() const
204  {
205  os::MutexLock lock(m);
206  return mlist.back().data;
207  }
208 
214  size_t append(const std::vector<T>& items)
215  {
216  os::MutexLock lock(m);
217  unsigned int max = mreserved.size();
218  typename std::vector<T>::const_iterator it = items.begin();
219  for(; it != items.end() && max != 0; ++it, --max )
220  mlist.push_back( this->get_item(*it) );
221  return it - items.begin();
222  }
223 
224 
230  bool erase( value_t item )
231  {
232  os::MutexLock lock(m);
233  mlist.remove_and_dispose_if( boost::bind(&ListLocked::is_item, this, item, _1), boost::bind(&ListLocked::give_back, this, _1) );
234  return true;
235  }
236 
244  template<typename Pred>
245  bool delete_if(Pred pred)
246  {
247  os::MutexLock lock(m);
248  bool deleted = false;
249 
250  typename BufferType::iterator cur(mlist.begin());
251  typename BufferType::iterator last(mlist.end());
252 
253  while(cur != last)
254  {
255  if(pred(cur->data))
256  {
257  cur = mlist.erase_and_dispose(cur, boost::bind(&ListLocked::give_back, this, _1) );
258  deleted = true;
259  }
260  else
261  ++cur;
262  }
263 
264  return deleted;
265  }
266 
273  template<class Function>
274  void apply(Function func )
275  {
276  os::MutexLock lock(m);
277  // A free beer for the one that can express this with a for_each construct.
278  for (Iterator it = mlist.begin(); it != mlist.end(); ++it)
279  func( it->data );
280  }
281 
287  template<class Function>
288  value_t find_if( Function func, value_t blank = value_t() )
289  {
290  os::MutexLock lock(m);
291  Iterator it = std::find_if(mlist.begin(), mlist.end(), boost::bind(func, boost::bind(&ListLocked::get_data, this,_1)));
292  if (it != mlist.end() )
293  return it->data;
294  return blank;
295  }
296  private:
302  void give_back(Cont* cont)
303  {
304  mreserved.push( cont );
305  }
306 
307  Cont& get_item(value_t item)
308  {
309  Cont* c = mreserved.top();
310  mreserved.pop();
311  c->data = item;
312  return *c;
313  }
314 
315  value_t& get_data(Cont& c)
316  {
317  return c.data;
318  }
319 
327  bool is_item(value_t item, const Cont& cont)
328  {
329  return item == cont.data;
330  }
331  };
332 
333 }}
334 
335 #endif
value_t back() const
Returns the last element of the list.
Definition: ListLocked.hpp:203
bool erase(value_t item)
Erase a value from the list.
Definition: ListLocked.hpp:230
void reserve(size_t lsize)
Reserve a capacity for this list.
Definition: ListLocked.hpp:163
value_t front() const
Returns the first element of the list.
Definition: ListLocked.hpp:194
ListLocked(unsigned int lsize, unsigned int unused=0)
Create a lock-based list wich can store lsize elements.
Definition: ListLocked.hpp:96
void apply(Function func)
Apply a function to the elements of the whole list.
Definition: ListLocked.hpp:274
size_t append(const std::vector< T > &items)
Append a sequence of values to the list.
Definition: ListLocked.hpp:214
A simple lock-based list implementation to append or erase data of type T.
Definition: ListLocked.hpp:72
void grow(size_t items=1)
Grow the capacity to contain at least n additional items.
Definition: ListLocked.hpp:136
value_t find_if(Function func, value_t blank=value_t())
Find an item in the list such that func( item ) == true.
Definition: ListLocked.hpp:288
bool delete_if(Pred pred)
Erase a value from the list.
Definition: ListLocked.hpp:245
size_t capacity() const
Definition: ListLocked.hpp:111
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:51
bool append(value_t item)
Append a single value to the list.
Definition: ListLocked.hpp:182
An object oriented wrapper around a recursive mutex.
Definition: Mutex.hpp:208
void shrink(size_t items=1)
Shrink the capacity with at most n items.
Definition: ListLocked.hpp:152
MutexLock is a scope based Monitor, protecting critical sections with a Mutex object through locking ...
Definition: MutexLock.hpp:51