INTRODUCTION
Overview
Download and Install
Documentation
Publications

REPOSITORY
Libraries

DEVELOPER
Dev Guide
Dashboard

PEOPLE
Contributors
Users

SourceForge.net Logo
Project
Download
Mailing lists

 

         
store.h
1 /*
2  * GearBox Project: Peer-Reviewed Open-Source Libraries for Robotics
3  http://gearbox.sf.net/
4  * Copyright (c) 2004-2010 Alex Brooks, Alexei Makarenko, Tobias Kaupp
5  *
6  * This distribution is licensed to you under the terms described in
7  * the LICENSE file included in this distribution.
8  *
9  */
10 
11 #ifndef GBXICEUTILACFR_STORE_H
12 #define GBXICEUTILACFR_STORE_H
13 
14 #include <gbxutilacfr/exceptions.h>
15 
16 #include <IceUtil/Monitor.h>
17 #include <IceUtil/Mutex.h>
18 #include <IceUtil/Time.h>
19 
20 namespace gbxiceutilacfr {
21 
41 template<class Type>
42 class Store : public IceUtil::Monitor<IceUtil::Mutex>
43 {
44 public:
45 
46  Store();
47  virtual ~Store();
48 
52  bool isEmpty() const;
53 
55  bool isNewData() const;
56 
58  void set( const Type & obj );
59 
63  void get( Type & obj );
64 
68  void peek( Type & obj ) const;
69 
79  int getNext( Type & obj, int timeoutMs=-1 );
80 
83  void purge();
84 
85 protected:
86 
87  // local copy of the object
88  Type obj_;
89 
90  // Reimplement this function for non-standard types.
91  virtual void internalGet( Type & obj ) const ;
92 
93  // Reimplement this function for non-standard types.
94  virtual void internalSet( const Type & obj );
95 
96 private:
97 
98 
99  bool isEmpty_;
100 
101  // flag to keep track of new data.
102  bool isNewData_;
103 
104  // internal implementation of front( obj, -1 ); returns 0.
105  int getNextNoWait( Type & obj );
106 
107 };
108 
109 
111 
112 template<class Type>
114  : isEmpty_(true),
115  isNewData_(false)
116 {
117 }
118 
119 template<class Type>
121 {
122 }
123 
124 template<class Type>
126 {
127  IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
128  return isEmpty_;
129 }
130 
131 template<class Type>
133 {
134  IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
135  return isNewData_;
136 }
137 
138 template<class Type>
139 void Store<Type>::get( Type & obj )
140 {
141  IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
142  if ( !isEmpty_ )
143  {
144  internalGet( obj );
145  isNewData_ = false;
146  }
147  else
148  {
149  throw gbxutilacfr::Exception( ERROR_INFO, "trying to read from an empty Store." );
150  }
151 }
152 
153 template<class Type>
154 void Store<Type>::peek( Type & obj ) const
155 {
156  IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
157  if ( !isEmpty_ )
158  {
159  internalGet( obj );
160  // do NOT set isNewData_ to false
161  }
162  else
163  {
164  throw gbxutilacfr::Exception( ERROR_INFO, "trying to read from an empty Store." );
165  }
166 }
167 
168 template<class Type>
169 int Store<Type>::getNext( Type & obj, int timeoutMs )
170 {
171  // special case: infinite wait time
172  if ( timeoutMs == -1 ) {
173  return getNextNoWait( obj );
174  }
175 
176  // finite wait time
177  IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
178 
179  // if already have data in the buffer, return it and get out
180  if ( isNewData_ )
181  {
182  internalGet( obj );
183  isNewData_ = false;
184  return 0;
185  }
186 
187  // empty buffer: figure out when to wake up
188  // notice that we are still holding the lock, so it's ok to call timedWait()
189  if ( this->timedWait( IceUtil::Time::milliSeconds( timeoutMs ) ) )
190  {
191  // someone woke us up, we are holding the lock again
192  // check new data again (could be a spurious wakeup)
193  if ( isNewData_ )
194  {
195  internalGet( obj );
196  isNewData_ = false;
197  return 0;
198  }
199  else {
200  // spurious wakup, don't wait again, just return
201  return 1;
202  }
203  }
204  else {
205  // wait timedout, nobody woke us up
206  return -1;
207  }
208 }
209 
210 template<class Type>
211 int Store<Type>::getNextNoWait( Type & obj )
212 {
213  IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
214 
215  // check the condition before and after waiting to deal with spurious wakeups
216  // (see Ice manual sec. 28.9.2)
217  while ( !isNewData_ )
218  {
219  this->wait();
220  }
221 
222  internalGet( obj );
223  isNewData_ = false;
224  return 0;
225 }
226 
227 // NOTE: see notes on efficient notification in Ice sec. 28.9.3
228 template<class Type>
229 void Store<Type>::set( const Type &obj )
230 {
231  IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
232 
233  internalSet( obj );
234 
235  // mark as having new data (nobody has looked at it yet)
236  isNewData_ = true;
237 
238  // mark Store non-empty (only usefull the very first time)
239  isEmpty_ = false;
240 
241  // wakeup someone who's waiting for an update
242  this->notify();
243 }
244 
245 template<class Type>
247 {
248  IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
249  isEmpty_ = true;
250 }
251 
252 template<class Type>
253 void Store<Type>::internalGet( Type & obj ) const
254 {
255  obj = obj_;
256 }
257 
258 template<class Type>
259 void Store<Type>::internalSet( const Type & obj )
260 {
261  obj_ = obj;
262 }
263 
264 } // end namespace
265 
266 #endif
void set(const Type &obj)
Sets the contents of the Store.
Definition: store.h:229
Base class for all GbxUtilAcfr exceptions.
Definition: gbxutilacfr/exceptions.h:65
void purge()
Definition: store.h:246
void get(Type &obj)
Definition: store.h:139
bool isNewData() const
Returns TRUE if the data in the Store has not been accessed with get() yet.
Definition: store.h:132
void peek(Type &obj) const
Definition: store.h:154
Thread-safe storage for a single data objects.
Definition: store.h:42
bool isEmpty() const
Definition: store.h:125
Utility namespace (part of SICK-ACFR driver)
Definition: buffer.h:21
int getNext(Type &obj, int timeoutMs=-1)
Waits until the next update and returns the new value. If the Store is empty, getNext blocks until th...
Definition: store.h:169
 

Generated for GearBox by  doxygen 1.4.5