μHAL (v2.6.5)
Part of the IPbus software repository
ProtocolTCP.hpp
Go to the documentation of this file.
1 /*
2 ---------------------------------------------------------------------------
3 
4  This file is part of uHAL.
5 
6  uHAL is a hardware access library and programming framework
7  originally developed for upgrades of the Level-1 trigger of the CMS
8  experiment at CERN.
9 
10  uHAL is free software: you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  uHAL is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with uHAL. If not, see <http://www.gnu.org/licenses/>.
22 
23 
24  Andrew Rose, Imperial College, London
25  email: awr01 <AT> imperial.ac.uk
26 
27  Marc Magrans de Abril, CERN
28  email: marc.magrans.de.abril <AT> cern.ch
29 
30 ---------------------------------------------------------------------------
31 */
32 
39 #ifndef _uhal_ProtocolTCP_hpp_
40 #define _uhal_ProtocolTCP_hpp_
41 
42 
43 #include <deque>
44 #include <iostream>
45 #include <stdint.h>
46 #include <string>
47 #include <vector>
48 
49 #include <boost/shared_ptr.hpp>
50 #include <boost/asio/io_service.hpp>
51 #include <boost/asio/ip/tcp.hpp>
52 #include <boost/asio/deadline_timer.hpp>
53 #include <boost/chrono/system_clocks.hpp>
54 
55 #include <boost/thread/thread.hpp>
56 #include <boost/thread/mutex.hpp>
57 #include <boost/thread/condition_variable.hpp>
58 
59 #include "uhal/ClientInterface.hpp"
60 #include "uhal/log/exception.hpp"
62 
63 namespace uhal
64 {
65  // Forward declarations
66  class Buffers;
67  struct URI;
68 
69 
70  namespace exception
71  {
73  UHAL_DEFINE_DERIVED_EXCEPTION_CLASS ( TcpTimeout , ClientTimeout , "Exception class to handle the case where the TCP connection timed out." )
75  UHAL_DEFINE_DERIVED_EXCEPTION_CLASS ( ErrorAtTcpSocketCreation , TransportLayerError , "Exception class to handle a failure to create a TCP socket." )
77  UHAL_DEFINE_DERIVED_EXCEPTION_CLASS ( TcpConnectionFailure , TransportLayerError , "Exception class to handle the case where the TCP connection was refused or aborted." )
79  UHAL_DEFINE_DERIVED_EXCEPTION_CLASS ( ASIOTcpError , TransportLayerError , "Exception class to handle the case where ASIO returned an error." )
80 
81  }
82 
84  template < typename InnerProtocol , std::size_t nr_buffers_per_send >
85  class TCP : public InnerProtocol
86  {
87 
88  private:
94  TCP ( const TCP& aTCP ); // non-copyable
95 
102  TCP& operator= ( const TCP& aTCP ); // non-assignable
103 
104  public:
110  TCP ( const std::string& aId, const URI& aUri );
111 
115  virtual ~TCP();
116 
117  private:
123  void implementDispatch ( boost::shared_ptr< Buffers > aBuffers );
124 
128  virtual void Flush( );
129 
133  virtual void dispatchExceptionHandler();
134 
139  uint32_t getMaxSendSize();
140 
145  uint32_t getMaxReplySize();
146 
150  void connect();
151 
157  void write ( );
158 
164  void write_callback ( const boost::system::error_code& aErrorCode , std::size_t aBytesTransferred );
165 
171  void read ( );
172 
178  void read_callback ( const boost::system::error_code& aErrorCode , std::size_t aBytesTransferred );
179 
183  void CheckDeadline();
184 
189  void NotifyConditionalVariable ( const bool& aValue );
193  void WaitOnConditionalVariable();
194 
195 
196  private:
197  typedef boost::chrono::steady_clock SteadyClock_t;
198 
200  boost::asio::io_service mIOservice;
201 
203  boost::asio::ip::tcp::socket mSocket;
204 
206  boost::asio::ip::tcp::resolver::iterator mEndpoint;
207 
209  boost::asio::deadline_timer mDeadlineTimer;
210 
212  boost::asio::io_service::work mIOserviceWork;
213 
215  boost::thread mDispatchThread;
216 
218  boost::mutex mTransportLayerMutex;
219 
221  std::deque < boost::shared_ptr< Buffers > > mDispatchQueue;
223  std::deque < std::pair<std::vector< boost::shared_ptr< Buffers > >, SteadyClock_t::time_point> > mReplyQueue;
224 
227 
230 
234  boost::condition_variable mConditionalVariable;
237 
245 
252 
257  std::vector< boost::shared_ptr< Buffers > > mDispatchBuffers;
258 
263  std::pair< std::vector< boost::shared_ptr< Buffers > >, SteadyClock_t::time_point > mReplyBuffers;
264 
270 
271 
272  SteadyClock_t::time_point mLastSendQueued;
273  SteadyClock_t::time_point mLastRecvQueued;
274 
279  };
280 
281 }
282 
283 
284 #endif
boost::condition_variable mConditionalVariable
A conditional variable for blocking the main thread until the variable with which it is associated is...
std::deque< std::pair< std::vector< boost::shared_ptr< Buffers > >, SteadyClock_t::time_point > > mReplyQueue
The list of buffers still awaiting a reply.
std::deque< boost::shared_ptr< Buffers > > mDispatchQueue
The list of buffers still waiting to be sent.
uint32_t mPacketsInFlight
Counter of how many writes have been sent, for which no reply has yet been received.
boost::asio::deadline_timer mDeadlineTimer
The mechanism for providing the time-out.
TimeIntervalStats mInterSendTimeStats
bool mFlushStarted
Boolean specifying whether or not the main thread is within TCP::Flush method. Its value checked by t...
uhal::exception::exception * mAsynchronousException
A pointer to an exception object for passing exceptions from the worker thread to the main thread...
SteadyClock_t::time_point mLastRecvQueued
SteadyClock_t::time_point mLastSendQueued
boost::asio::ip::tcp::resolver::iterator mEndpoint
A shared pointer to a boost::asio tcp endpoint - used by the delayed (open-on-first-use) connect...
#define UHAL_DEFINE_DERIVED_EXCEPTION_CLASS(ClassName, BaseClassName, ClassDescription)
Macro for simplifying the declaration and definition of derived exception types.
Definition: exception.hpp:54
An abstract base exception class providing an interface to a throw/ThrowAsDerivedType mechanism which...
Definition: exception.hpp:89
TimeIntervalStats mRTTStats
uint32_t mSendByteCounter
Variable storing "number of bytes to follow" field for the TCP chunk currently being sent...
boost::mutex mConditionalVariableMutex
A mutex for use by the conditional variable.
boost::mutex mTransportLayerMutex
A MutEx lock used to make sure the access functions are thread safe.
boost::chrono::steady_clock SteadyClock_t
boost::asio::io_service::work mIOserviceWork
Needed when multi-threading to stop the boost::asio::io_service thinking it has nothing to do and so ...
TimeIntervalStats mLSTStats
TimeIntervalStats mInterRecvTimeStats
std::pair< std::vector< boost::shared_ptr< Buffers > >, SteadyClock_t::time_point > mReplyBuffers
The buffers containing the payloads for the receive operation that&#39;s currently in progress...
boost::thread mDispatchThread
The Worker thread in Multi-threaded mode.
boost::asio::io_service mIOservice
The boost::asio::io_service used to create the connections.
Transport protocol to transfer an IPbus buffer via TCP.
Definition: ProtocolTCP.hpp:85
uint32_t mReplyByteCounter
Variable used to store "number of bytes to follow" field for the next/current TCP chunk being receive...
std::vector< boost::shared_ptr< Buffers > > mDispatchBuffers
The buffers containing the payload for the send operation that&#39;s currently in progress.
bool mFlushDone
A variable associated with the conditional variable which specifies whether all packets have been sen...
c write(addr, xx[0])
boost::asio::ip::tcp::socket mSocket
A shared pointer to a boost::asio tcp socket through which the operation will be performed.
Struct to store a URI when parsed by boost spirit.
Definition: URI.hpp:49