FREEDM DGI
SynchronousTimeout.hpp
Go to the documentation of this file.
1 
28 #ifndef SYNCHRONOUS_TIMEOUT_HPP
29 #define SYNCHRONOUS_TIMEOUT_HPP
30 
31 #include "CLogger.hpp"
32 
33 #include <stdexcept>
34 
35 #include <boost/asio.hpp>
36 #include <boost/bind.hpp>
37 #include <boost/optional.hpp>
38 #include <boost/shared_ptr.hpp>
39 
40 namespace freedm {
41 namespace broker {
42 namespace device {
43 
44 namespace {
46 CLocalLogger SyncTimeoutLogger(__FILE__);
47 }
48 
50 typedef boost::optional<boost::system::error_code> OptionalError;
51 
53 void SetResult(boost::shared_ptr<OptionalError> status,
54  const boost::system::error_code & error);
55 
70 template <typename ReadStream, typename BufferSequence>
71 void TimedRead(ReadStream & stream, const BufferSequence & buffer,
72  unsigned int duration)
73 {
74  SyncTimeoutLogger.Trace << __PRETTY_FUNCTION__ << std::endl;
75 
76  boost::asio::io_service & ios = stream.get_io_service();
77  boost::shared_ptr<OptionalError> result(new OptionalError);
78  boost::shared_ptr<OptionalError> timeout(new OptionalError);
79  boost::asio::deadline_timer timer(ios);
80 
81  SyncTimeoutLogger.Info << "Blocking for synchronous read." << std::endl;
82 
83  boost::asio::async_read(stream, buffer,
84  boost::bind(SetResult, result, boost::asio::placeholders::error));
85  timer.expires_from_now(boost::posix_time::milliseconds(duration));
86  timer.async_wait(boost::bind(SetResult, timeout,
87  boost::asio::placeholders::error));
88 
89  while( !(*result) && !(*timeout) )
90  {
91  ios.poll();
92  }
93 
94  if( *result && (*result)->value() == boost::system::errc::success )
95  {
96  SyncTimeoutLogger.Info << "Synchronous read complete." << std::endl;
97  }
98  else if( *timeout && (*timeout)->value() == boost::system::errc::success )
99  {
100  throw std::runtime_error("Synchronous Read Timeout");
101  }
102  else
103  {
104  throw std::runtime_error("Synchronous Read Failed");
105  }
106 }
107 
123 template <typename ReadStream, typename Allocator>
124 void TimedReadUntil(ReadStream & stream,
125  boost::asio::basic_streambuf<Allocator> & buffer,
126  const std::string & delim,
127  unsigned int duration)
128 {
129  SyncTimeoutLogger.Trace << __PRETTY_FUNCTION__ << std::endl;
130 
131  boost::asio::io_service & ios = stream.get_io_service();
132  boost::shared_ptr<OptionalError> result(new OptionalError);
133  boost::shared_ptr<OptionalError> timeout(new OptionalError);
134  boost::asio::deadline_timer timer(ios);
135 
136  SyncTimeoutLogger.Info << "Blocking for synchronous read." << std::endl;
137 
138  boost::asio::async_read_until(stream, buffer, delim,
139  boost::bind(SetResult, result, boost::asio::placeholders::error));
140  timer.expires_from_now(boost::posix_time::milliseconds(duration));
141  timer.async_wait(boost::bind(SetResult, timeout,
142  boost::asio::placeholders::error));
143 
144  while( !(*result) && !(*timeout) )
145  {
146  ios.poll();
147  }
148 
149  if( *result && (*result)->value() == boost::system::errc::success )
150  {
151  SyncTimeoutLogger.Info << "Synchronous read complete." << std::endl;
152  }
153  else if( *timeout && (*timeout)->value() == boost::system::errc::success )
154  {
155  throw std::runtime_error("Synchronous Read Until Timeout");
156  }
157  else
158  {
159  throw std::runtime_error("Synchronous Read Until Failed");
160  }
161 }
162 
176 template <typename WriteStream, typename BufferSequence>
177 void TimedWrite(WriteStream & stream, const BufferSequence & buffer,
178  unsigned int duration)
179 {
180  SyncTimeoutLogger.Trace << __PRETTY_FUNCTION__ << std::endl;
181 
182  boost::asio::io_service & ios = stream.get_io_service();
183  boost::shared_ptr<OptionalError> result(new OptionalError);
184  boost::shared_ptr<OptionalError> timeout(new OptionalError);
185  boost::asio::deadline_timer timer(ios);
186 
187  SyncTimeoutLogger.Info << "Blocking for synchronous write." << std::endl;
188 
189  boost::asio::async_write(stream, buffer,
190  boost::bind(SetResult, result, boost::asio::placeholders::error));
191  timer.expires_from_now(boost::posix_time::milliseconds(duration));
192  timer.async_wait(boost::bind(SetResult, timeout,
193  boost::asio::placeholders::error));
194 
195  while( !(*result) && !(*timeout) )
196  {
197  ios.poll();
198  }
199 
200  if( *result && (*result)->value() == boost::system::errc::success )
201  {
202  SyncTimeoutLogger.Info << "Synchronous write complete." << std::endl;
203  }
204  else if( *timeout && (*timeout)->value() == boost::system::errc::success )
205  {
206  throw std::runtime_error("Synchronous Write Timeout");
207  }
208  else
209  {
210  throw std::runtime_error("Synchronous Write Failed");
211  }
212 }
213 
227 template <typename WriteStream, typename Allocator>
228 void TimedWrite(WriteStream & stream,
229  boost::asio::basic_streambuf<Allocator> & buffer,
230  unsigned int duration)
231 {
232  SyncTimeoutLogger.Trace << __PRETTY_FUNCTION__ << std::endl;
233 
234  boost::asio::io_service & ios = stream.get_io_service();
235  boost::shared_ptr<OptionalError> result(new OptionalError);
236  boost::shared_ptr<OptionalError> timeout(new OptionalError);
237  boost::asio::deadline_timer timer(ios);
238 
239  SyncTimeoutLogger.Info << "Blocking for synchronous write." << std::endl;
240 
241  boost::asio::async_write(stream, buffer,
242  boost::bind(SetResult, result, boost::asio::placeholders::error));
243  timer.expires_from_now(boost::posix_time::milliseconds(duration));
244  timer.async_wait(boost::bind(SetResult, timeout,
245  boost::asio::placeholders::error));
246 
247  while( !(*result) && !(*timeout) )
248  {
249  ios.poll();
250  }
251 
252  if( *result && (*result)->value() == boost::system::errc::success )
253  {
254  SyncTimeoutLogger.Info << "Synchronous write complete." << std::endl;
255  }
256  else if( *timeout && (*timeout)->value() == boost::system::errc::success )
257  {
258  throw std::runtime_error("Synchronous Write Timeout");
259  }
260  else
261  {
262  throw std::runtime_error("Synchronous Write Failed");
263  }
264 }
265 
266 } // namespace device
267 } // namespace broker
268 } // namespace freedm
269 
270 #endif // SYNCHRONOUS_TIMEOUT_HPP
271 
void TimedReadUntil(ReadStream &stream, boost::asio::basic_streambuf< Allocator > &buffer, const std::string &delim, unsigned int duration)
Definition: SynchronousTimeout.hpp:124
void SetResult(boost::shared_ptr< OptionalError > status, const boost::system::error_code &error)
Callback function for the timed synchronous operations.
Definition: SynchronousTimeout.cpp:53
boost::optional< boost::system::error_code > OptionalError
Convenience typedef for the SetResult function.
Definition: SynchronousTimeout.hpp:50
General FREEDM Namespace.
Definition: CBroker.cpp:53
#define __PRETTY_FUNCTION__
Definition: CLogger.hpp:44
void TimedWrite(WriteStream &stream, const BufferSequence &buffer, unsigned int duration)
Definition: SynchronousTimeout.hpp:177
void TimedRead(ReadStream &stream, const BufferSequence &buffer, unsigned int duration)
Definition: SynchronousTimeout.hpp:71