RCFProto
 All Classes Functions Typedefs
AsioServerTransport.hpp
1 
2 //******************************************************************************
3 // RCF - Remote Call Framework
4 //
5 // Copyright (c) 2005 - 2013, Delta V Software. All rights reserved.
6 // http://www.deltavsoft.com
7 //
8 // RCF is distributed under dual licenses - closed source or GPL.
9 // Consult your particular license for conditions of use.
10 //
11 // If you have not purchased a commercial license, you are using RCF
12 // under GPL terms.
13 //
14 // Version: 2.0
15 // Contact: support <at> deltavsoft.com
16 //
17 //******************************************************************************
18 
19 #ifndef INCLUDE_RCF_ASIOSERVERTRANSPORT_HPP
20 #define INCLUDE_RCF_ASIOSERVERTRANSPORT_HPP
21 
22 #include <set>
23 #include <vector>
24 
25 #include <boost/shared_ptr.hpp>
26 #include <boost/weak_ptr.hpp>
27 
28 #include <RCF/Asio.hpp>
29 #include <RCF/Enums.hpp>
30 #include <RCF/Export.hpp>
31 #include <RCF/IpAddress.hpp>
32 #include <RCF/IpServerTransport.hpp>
33 #include <RCF/ServerTransport.hpp>
34 #include <RCF/Service.hpp>
35 #include <RCF/ThreadLibrary.hpp>
36 
37 namespace RCF {
38 
39  class RcfServer;
40  class TcpClientTransport;
41  class AsioSessionState;
42  class AsioServerTransport;
43 
44  typedef boost::shared_ptr<AsioSessionState> AsioSessionStatePtr;
45  typedef boost::weak_ptr<AsioSessionState> AsioSessionStateWeakPtr;
46 
47  class AsioAcceptor
48  {
49  public:
50  virtual ~AsioAcceptor()
51  {}
52  };
53 
54  typedef boost::scoped_ptr<AsioAcceptor> AsioAcceptorPtr;
55 
56  class RCF_EXPORT AsioServerTransport :
57  public ServerTransport,
58  public ServerTransportEx,
59  public I_Service
60  {
61  private:
62 
63  // Needs to call open().
64  friend class TcpAsioTransportFactory;
65 
66  typedef boost::weak_ptr<I_Session> SessionWeakPtr;
67 
68  AsioSessionStatePtr createSessionState();
69 
70 
71 
72  // I_ServerTransportEx implementation
73  ClientTransportAutoPtr
74  createClientTransport(
75  const Endpoint &endpoint);
76 
77  SessionPtr createServerSession(
78  ClientTransportAutoPtr & clientTransportAutoPtr,
79  StubEntryPtr stubEntryPtr,
80  bool keepClientConnection);
81 
82  ClientTransportAutoPtr
83  createClientTransport(
84  SessionPtr sessionPtr);
85 
86  bool reflect(
87  const SessionPtr &sessionPtr1,
88  const SessionPtr &sessionPtr2);
89 
90  // I_Service implementation
91  void open();
92  void close();
93  void stop();
94 
95  void onServiceAdded( RcfServer & server);
96  void onServiceRemoved( RcfServer & server);
97 
98  protected:
99 
100  void onServerStart( RcfServer & server);
101  void onServerStop( RcfServer & server);
102  void setServer( RcfServer & server);
103 
104  void startAccepting();
105 
106  private:
107 
108  void startAcceptingThread(Exception & eRet);
109 
110  RcfServer & getServer();
111  RcfServer & getSessionManager();
112 
113  private:
114 
115  void registerSession(AsioSessionStateWeakPtr session);
116  void unregisterSession(AsioSessionStateWeakPtr session);
117  void cancelOutstandingIo();
118 
119  friend class AsioSessionState;
120  friend class FilterAdapter;
121  friend class ServerTcpFrame;
122  friend class ServerHttpFrame;
123 
124  protected:
125 
126  AsioServerTransport();
127  ~AsioServerTransport();
128 
129  AsioIoService * mpIoService;
130  AsioAcceptorPtr mAcceptorPtr;
131 
132  WireProtocol mWireProtocol;
133 
134  private:
135 
136  volatile bool mStopFlag;
137  RcfServer * mpServer;
138 
139  private:
140 
141  virtual AsioSessionStatePtr implCreateSessionState() = 0;
142  virtual void implOpen() = 0;
143 
144  virtual ClientTransportAutoPtr implCreateClientTransport(
145  const Endpoint &endpoint) = 0;
146 
147  public:
148 
149  AsioAcceptor & getAcceptor();
150 
151  AsioIoService & getIoService();
152  };
153 
154  class ReadHandler
155  {
156  public:
157  ReadHandler(AsioSessionStatePtr sessionStatePtr);
158  void operator()(AsioErrorCode err, std::size_t bytes);
159  void * allocate(std::size_t size);
160  AsioSessionStatePtr mSessionStatePtr;
161  };
162 
163  class WriteHandler
164  {
165  public:
166  WriteHandler(AsioSessionStatePtr sessionStatePtr);
167  void operator()(AsioErrorCode err, std::size_t bytes);
168  void * allocate(std::size_t size);
169  AsioSessionStatePtr mSessionStatePtr;
170  };
171 
172  void * asio_handler_allocate(std::size_t size, ReadHandler * pHandler);
173  void asio_handler_deallocate(void * pointer, std::size_t size, ReadHandler * pHandler);
174  void * asio_handler_allocate(std::size_t size, WriteHandler * pHandler);
175  void asio_handler_deallocate(void * pointer, std::size_t size, WriteHandler * pHandler);
176 
177  class RCF_EXPORT AsioSessionState :
178  public SessionState,
179  boost::noncopyable
180  {
181  public:
182 
183  friend class ReadHandler;
184  friend class WriteHandler;
185  friend class ServerTcpFrame;
186  friend class ServerHttpFrame;
187 
188 
189  typedef boost::weak_ptr<AsioSessionState> AsioSessionStateWeakPtr;
190  typedef boost::shared_ptr<AsioSessionState> AsioSessionStatePtr;
191 
192  AsioSessionState(
193  AsioServerTransport &transport,
194  AsioIoService & ioService);
195 
196  virtual ~AsioSessionState();
197 
198  AsioSessionStatePtr sharedFromThis();
199 
200  void close();
201 
202  AsioErrorCode getLastError();
203 
204  protected:
205  AsioIoService & mIoService;
206 
207  std::vector<char> mReadHandlerBuffer;
208  std::vector<char> mWriteHandlerBuffer;
209 
210  AsioErrorCode mLastError;
211 
212  private:
213 
214  // read()/write() are used to connect with the filter sequence.
215  void read(
216  const ByteBuffer &byteBuffer,
217  std::size_t bytesRequested);
218 
219  void write(
220  const std::vector<ByteBuffer> &byteBuffers);
221 
222  void setTransportFilters(
223  const std::vector<FilterPtr> &filters);
224 
225  void getTransportFilters(
226  std::vector<FilterPtr> &filters);
227 
228  void beginAccept();
229  void beginRead();
230  void beginWrite();
231 
232  void onAcceptCompleted(const AsioErrorCode & error);
233 
234  void onNetworkReadCompleted(
235  AsioErrorCode error,
236  size_t bytesTransferred);
237 
238  void onNetworkWriteCompleted(
239  AsioErrorCode error,
240  size_t bytesTransferred);
241 
242  void onAppReadWriteCompleted(
243  size_t bytesTransferred);
244 
245  void onReflectedReadWriteCompleted(
246  const AsioErrorCode & error,
247  size_t bytesTransferred);
248 
249  void sendServerError(int error);
250 
251  void doCustomFraming(size_t bytesTransferred);
252  void doRegularFraming(size_t bytesTransferred);
253 
254  // TODO: too many friends
255  friend class AsioServerTransport;
256  friend class TcpAsioSessionState;
257  friend class UnixLocalSessionState;
258  friend class Win32NamedPipeSessionState;
259  friend class FilterAdapter;
260 
261  enum State
262  {
263  Ready,
264  Accepting,
265  ReadingData,
266  ReadingDataCount,
267  WritingData
268  };
269 
270  State mState;
271  bool mIssueZeroByteRead;
272  std::size_t mReadBufferRemaining;
273  std::size_t mWriteBufferRemaining;
274 
275  std::vector<FilterPtr> mTransportFilters;
276  std::vector<FilterPtr> mWireFilters;
277 
278  AsioServerTransport & mTransport;
279 
280  std::vector<ByteBuffer> mWriteByteBuffers;
281  std::vector<ByteBuffer> mSlicedWriteByteBuffers;
282 
283  ReallocBufferPtr mAppReadBufferPtr;
284  ByteBuffer mAppReadByteBuffer;
285 
286  ReallocBufferPtr mNetworkReadBufferPtr;
287  ByteBuffer mNetworkReadByteBuffer;
288 
289  // So we can connect our read()/write() functions to the filter sequence.
290  FilterPtr mFilterAdapterPtr;
291 
292  bool mCloseAfterWrite;
293  AsioSessionStateWeakPtr mReflecteeWeakPtr;
294  AsioSessionStatePtr mReflecteePtr;
295  bool mReflecting;
296 
297  AsioSessionStateWeakPtr mWeakThisPtr;
298 
299  AsioBuffers mBufs;
300 
301  boost::shared_ptr<Mutex> mSocketOpsMutexPtr;
302 
303  // I_SessionState
304 
305  private:
306 
307  void postRead();
308  ByteBuffer getReadByteBuffer();
309  void postWrite(std::vector<ByteBuffer> &byteBuffers);
310  void postClose();
311  ServerTransport & getServerTransport();
312  const RemoteAddress & getRemoteAddress();
313  bool isConnected();
314 
315  private:
316 
317  virtual const RemoteAddress & implGetRemoteAddress() = 0;
318  virtual void implRead(char * buffer, std::size_t bufferLen) = 0;
319  virtual void implWrite(const std::vector<ByteBuffer> & buffers) = 0;
320  virtual void implWrite(AsioSessionState &toBeNotified, const char * buffer, std::size_t bufferLen) = 0;
321  virtual void implAccept() = 0;
322  virtual bool implOnAccept() = 0;
323  virtual bool implIsConnected() = 0;
324  virtual void implClose() = 0;
325  virtual void implCloseAfterWrite() {}
326  virtual void implTransferNativeFrom(ClientTransport & clientTransport) = 0;
327  virtual ClientTransportAutoPtr implCreateClientTransport() = 0;
328  };
329 
330 } // namespace RCF
331 
332 
333 #endif // ! INCLUDE_RCF_ASIOSERVERTRANSPORT_HPP