4 * @copyright © Copyright 2008 by Intra2net AG
10 #include "async_callout.hpp"
11 #include <asyncio_config.hpp>
13 #ifdef HAVE_LIBI2NCOMMON
14 #include <tracefunc.hpp>
15 #include <logfunc.hpp>
17 #define SCOPETRACKER(x) do{}while(false)
29 typedef boost::shared_ptr< Detail::Caller > CallerPtr;
31 typedef std::map< unsigned long, CallerPtr > CallMap;
34 unsigned long l_last_id=0;
40 * @brief creates a new id value for a call out.
43 * The id value is basically just a counter.
44 * It is implemented in a way that it can not be 0 and can deal with wrap arounds.
46 unsigned long create_call_out_id_value()
48 while ( l_call_map.find(++l_last_id) != l_call_map.end() and l_last_id != 0);
50 } // eo create_call_out_id_value
53 void add_call( CallerPtr caller )
57 l_call_map[ caller->getCallOutId().getValue() ] = caller;
62 bool remove_call( unsigned long id_value )
64 CallMap::iterator it= l_call_map.find(id_value);
65 if (it != l_call_map.end())
71 } // eo remove_call(unsigned long)
74 CallerPtr get_call(unsigned long id_value)
76 CallMap::iterator it= l_call_map.find(id_value);
77 if (it != l_call_map.end())
82 } // eo get_call(unsigned long)
85 bool has_call( unsigned long id_value )
87 CallMap::iterator it= l_call_map.find(id_value);
88 return (it != l_call_map.end() );
89 } // eo has_call(unsigned long)
93 } // eo namespace <anonymous>
98 ** implementation of class CallOutId
101 CallOutId::CallOutId()
104 } // eo CallOutId::CallOutId()
107 CallOutId::CallOutId(unsigned long value)
110 } // eo CallOutId::CallOutId(unsigned long)
113 bool CallOutId::thaw() const
115 if (m_caller_weak_ptr.expired())
119 CallerPtr call_ptr= get_call(m_value);
122 return call_ptr->thaw();
125 } // eo CallOutId::thaw() const
128 bool CallOutId::remove()
130 if (m_caller_weak_ptr.expired())
134 unsigned long value= m_value;
136 return remove_call(value);
137 } // eo CallOutId::remove()
140 bool CallOutId::active() const
142 return m_value!=0 and not m_caller_weak_ptr.expired() and has_call(m_value);
143 } // eo CallOutId::active() const
147 * @brief retruns if the call is frozen.
148 * @return @a true iff the call is frozen.
150 bool CallOutId::frozen() const
152 CallerPtr caller= m_caller_weak_ptr.lock();
157 return caller->frozen();
158 } // eo CallOutId::frozen() const
162 * @brief returns the remaining time until the call is done or thrown away (on frozen calls).
163 * @return the remaining time.
165 * The result only makes sense if the call is still active.
167 MilliTime CallOutId::remaining_time()
169 CallerPtr caller= m_caller_weak_ptr.lock();
170 if ( not active() or not caller )
175 get_current_monotonic_time(t);
176 MilliTime result= caller->getWhenTime();
179 return (result < t_null ? t_null : result);
180 } // eo CallOutId::remaining_time()
187 ** implementation of class Caller
190 Caller::Caller( boost::function< void() > f, long delta_sec, long delta_msec, bool frozen)
192 , m_call_out_id( create_call_out_id_value() )
197 setDeltaWhenTime( delta_sec, delta_msec);
198 } // eo Caller::Caller(boost::function< void() >,long)
204 } // eo Caller::~Caller()
207 void Caller::execute()
210 // NOTE: since the func may throw an exception, we first get a shared pointer
211 // (to prevent early deletion) and then we remove us from the call map.
212 CallerPtr ptr= shared_from_this();
213 m_call_out_id.remove();
215 if (m_func and not m_waiting)
217 m_func(); // may throw..., but at this point it doesn't harm.
218 //( it may harm at other places,...)
220 } // eo Caller::execute()
228 setDeltaWhenTime( 0, 0 );
232 } // eo Caller::thaw()
235 bool Caller::joinId()
237 if (m_call_out_id.m_caller_weak_ptr.expired())
239 m_call_out_id.m_caller_weak_ptr= shared_from_this();
244 } // eo Caller::joinId()
247 bool Caller::frozen() const
250 } // eo Caller::frozen() const
253 } // eo namespace Detail
258 * @brief remove a pending call by id.
260 * @param id the call id which should be removed.
261 * @return @a true iff the call was removed, @a false if no call with the given id was found.
263 bool removeCallOut( CallOutId& id )
266 } // eo removeCallOut(CallOutId&)
271 CallOutId callOut( boost::function< void() > f, long delta_sec)
273 CallerPtr caller( new Detail::Caller(f,delta_sec) );
275 return caller->getCallOutId();
276 } // eo callOut(boost::function< void() >,long)
279 CallOutId callOut( boost::function< void() > f, int delta_sec)
281 return callOut<long>(f,delta_sec);
282 } // eo callOut(boost::function< void() >,int)
286 CallOutId callOut( boost::function< void() > f, double delta_sec )
288 long delta_sec_i = (long)delta_sec;
289 long delta_sec_m = (long)((delta_sec - (double)delta_sec_i)*1000.0);
290 CallerPtr caller( new Detail::Caller(f,delta_sec_i, delta_sec_m) );
292 return caller->getCallOutId();
293 } // eo callOut(boost::function< void() >,double)
297 CallOutId callOut( boost::function< void() > f, float delta_sec )
299 return callOut<double>(f,delta_sec);
300 } // eo callOut(boost::function< void() >,float)
306 CallOutId frozenCall( boost::function< void() > f, long delta_sec)
308 CallerPtr caller( new Detail::Caller(f,delta_sec, 0, true) );
310 return caller->getCallOutId();
311 } // eo frozenCall(boost::function< void() >,long)
314 CallOutId frozenCall( boost::function< void() > f, int delta_sec)
316 return frozenCall<long>(f,delta_sec);
317 } // eo frozenCall(boost::function< void() >,int)
321 CallOutId frozenCall( boost::function< void() > f, double delta_sec )
323 long delta_sec_i = (long)delta_sec;
324 long delta_sec_m = (long)((delta_sec - (double)delta_sec_i)*1000.0);
325 CallerPtr caller( new Detail::Caller(f,delta_sec_i, delta_sec_m, true) );
327 return caller->getCallOutId();
328 } // eo frozenCall(boost::function< void() >,double)
332 CallOutId frozenCall( boost::function< void() > f, float delta_sec )
334 return frozenCall<double>(f,delta_sec);
335 } // eo frozenCall(boost::function< void() >,float)
338 } // eo namespace AsyncIo