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
20namespace gbxiceutilacfr {
21
41template<class Type>
42class Store : public IceUtil::Monitor<IceUtil::Mutex>
43{
44public:
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
85protected:
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
96private:
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
112template<class Type>
114 : isEmpty_(true),
115 isNewData_(false)
116{
117}
118
119template<class Type>
120Store<Type>::~Store()
121{
122}
123
124template<class Type>
126{
127 IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
128 return isEmpty_;
129}
130
131template<class Type>
133{
134 IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
135 return isNewData_;
136}
137
138template<class Type>
139void 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
153template<class Type>
154void 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
168template<class Type>
169int 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
210template<class Type>
211int 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
228template<class Type>
229void 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
245template<class Type>
247{
248 IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
249 isEmpty_ = true;
250}
251
252template<class Type>
253void Store<Type>::internalGet( Type & obj ) const
254{
255 obj = obj_;
256}
257
258template<class Type>
259void Store<Type>::internalSet( const Type & obj )
260{
261 obj_ = obj;
262}
263
264} // end namespace
265
266#endif
Thread-safe storage for a single data objects.
Definition store.h:43
void purge()
Definition store.h:246
bool isEmpty() const
Definition store.h:125
bool isNewData() const
Returns TRUE if the data in the Store has not been accessed with get() yet.
Definition store.h:132
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
void peek(Type &obj) const
Definition store.h:154
void set(const Type &obj)
Sets the contents of the Store.
Definition store.h:229
void get(Type &obj)
Definition store.h:139
Base class for all GbxUtilAcfr exceptions.
Definition gbxutilacfr/exceptions.h:66
Utility namespace (part of SICK-ACFR driver)
Definition buffer.h:21
 

Generated for GearBox by  doxygen 1.4.5