This is Unofficial EPICS BASE Doxygen Site
virtualCircuit.h
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2002 The University of Chicago, as Operator of Argonne
3 * National Laboratory.
4 * Copyright (c) 2002 The Regents of the University of California, as
5 * Operator of Los Alamos National Laboratory.
6 * EPICS BASE is distributed subject to a Software License Agreement found
7 * in file LICENSE that is included with this distribution.
8 \*************************************************************************/
9 
10 /*
11  *
12  *
13  * L O S A L A M O S
14  * Los Alamos National Laboratory
15  * Los Alamos, New Mexico 87545
16  *
17  * Copyright, 1986, The Regents of the University of California.
18  *
19  *
20  * Author Jeffrey O. Hill
21  * johill@lanl.gov
22  * 505 665 1831
23  */
24 
25 #ifndef INC_virtualCircuit_H
26 #define INC_virtualCircuit_H
27 
28 #include "tsDLList.h"
29 
30 #include "comBuf.h"
31 #include "caServerID.h"
32 #include "netiiu.h"
33 #include "comQueSend.h"
34 #include "comQueRecv.h"
35 #include "tcpRecvWatchdog.h"
36 #include "tcpSendWatchdog.h"
37 #include "hostNameCache.h"
38 #include "SearchDest.h"
39 #include "compilerDependencies.h"
40 
41 class callbackManager;
42 
43 // a modified ca header with capacity for large arrays
45  ca_uint32_t m_postsize; // size of message extension
46  ca_uint32_t m_count; // operation data count
47  ca_uint32_t m_cid; // channel identifier
48  ca_uint32_t m_available; // protocol stub dependent
49  ca_uint16_t m_dataType; // operation data type
50  ca_uint16_t m_cmmd; // operation to be performed
51 };
52 
54 
55 class tcpRecvThread : private epicsThreadRunable {
56 public:
58  class tcpiiu & iiuIn, epicsMutex & cbMutexIn, cacContextNotify &,
59  const char * pName, unsigned int stackSize, unsigned int priority );
60  virtual ~tcpRecvThread ();
61  void start ();
62  void exitWait ();
63  bool exitWait ( double delay );
64  void interruptSocketRecv ();
65  void show ( unsigned level ) const;
66 private:
67  epicsThread thread;
68  class tcpiiu & iiu;
70  cacContextNotify & ctxNotify;
71  void run ();
72  void connect (
73  epicsGuard < epicsMutex > & guard );
74  bool validFillStatus (
76  const statusWireIO & stat );
77 };
78 
79 class tcpSendThread : private epicsThreadRunable {
80 public:
82  class tcpiiu & iiuIn, const char * pName,
83  unsigned int stackSize, unsigned int priority );
84  virtual ~tcpSendThread ();
85  void start ();
86  void exitWait ();
87  void interruptSocketSend ();
88  void show ( unsigned level ) const;
89 private:
90  epicsThread thread;
91  class tcpiiu & iiu;
92  void run ();
93 };
94 
95 class SearchDestTCP : public SearchDest {
96 public:
97  SearchDestTCP ( cac &, const osiSockAddr & );
98  void searchRequest ( epicsGuard < epicsMutex > & guard,
99  const char * pbuf, size_t len );
100  void show ( epicsGuard < epicsMutex > & guard, unsigned level ) const;
101  void setCircuit ( tcpiiu * );
102  void disable ();
103  void enable ();
104 private:
105  tcpiiu * _ptcpiiu;
106  cac & _cac;
107  const osiSockAddr _addr;
108  bool _active;
109 };
110 
111 class tcpiiu :
112  public netiiu, public tsDLNode < tcpiiu >,
113  public tsSLNode < tcpiiu >, public caServerID,
114  private wireSendAdapter, private wireRecvAdapter {
116  const char * pbuf, size_t len );
117 public:
118  tcpiiu ( cac & cac, epicsMutex & mutualExclusion, epicsMutex & callbackControl,
119  cacContextNotify &, double connectionTimeout, epicsTimerQueue & timerQueue,
120  const osiSockAddr & addrIn, comBufMemoryManager &, unsigned minorVersion,
121  ipAddrToAsciiEngine & engineIn, const cacChannel::priLev & priorityIn,
122  SearchDestTCP * pSearchDestIn = NULL);
123  ~tcpiiu ();
124  void start (
126  void responsiveCircuitNotify (
127  epicsGuard < epicsMutex > & cbGuard,
128  epicsGuard < epicsMutex > & guard );
129  void sendTimeoutNotify (
130  callbackManager & cbMgr,
131  epicsGuard < epicsMutex > & guard );
132  void receiveTimeoutNotify(
133  callbackManager &,
135  void beaconAnomalyNotify (
137  void beaconArrivalNotify (
139  void probeResponseNotify (
141 
142  void flushRequest (
144  unsigned requestMessageBytesPending (
145  epicsGuard < epicsMutex > & mutualExclusionGuard );
146  void flush (
147  epicsGuard < epicsMutex > & mutualExclusionGuard );
148 
149  void show ( unsigned level ) const;
150  bool setEchoRequestPending (
152  void requestRecvProcessPostponedFlush (
154  void clearChannelRequest (
156  ca_uint32_t sid, ca_uint32_t cid );
157 
158  bool ca_v41_ok (
159  epicsGuard < epicsMutex > & ) const;
160  bool ca_v42_ok (
161  epicsGuard < epicsMutex > & ) const;
162  bool ca_v44_ok (
163  epicsGuard < epicsMutex > & ) const;
164  bool ca_v49_ok (
165  epicsGuard < epicsMutex > & ) const;
166 
167  unsigned getHostName (
169  char *pBuf, unsigned bufLength ) const throw ();
170  bool alive (
171  epicsGuard < epicsMutex > & ) const;
172  bool connecting (
173  epicsGuard < epicsMutex > & ) const;
174  bool receiveThreadIsBusy (
176  osiSockAddr getNetworkAddress (
177  epicsGuard < epicsMutex > & ) const;
178  int printFormated (
179  epicsGuard < epicsMutex > & cbGuard,
180  const char *pformat, ... );
181  unsigned channelCount (
183  void disconnectAllChannels (
184  epicsGuard < epicsMutex > & cbGuard,
185  epicsGuard < epicsMutex > & guard, class udpiiu & );
186  void unlinkAllChannels (
187  epicsGuard < epicsMutex > & cbGuard,
188  epicsGuard < epicsMutex > & guard );
189  void installChannel (
191  unsigned sidIn, ca_uint16_t typeIn, arrayElementCount countIn );
192  void uninstallChan (
193  epicsGuard < epicsMutex > & guard, nciu & chan );
194  bool connectNotify (
195  epicsGuard < epicsMutex > &, nciu & chan );
196 
197  void searchRespNotify (
198  const epicsTime &, const caHdrLargeArray & );
199  void versionRespNotify ( const caHdrLargeArray & );
200 
201  void * operator new ( size_t size,
203  epicsPlacementDeleteOperator (( void *,
205 
206 private:
207  hostNameCache hostNameCacheInstance;
208  tcpRecvThread recvThread;
209  tcpSendThread sendThread;
212  comQueSend sendQue;
213  comQueRecv recvQue;
214  // nciu state field tells us which list
215  // protected by the callback mutex
216  tsDLList < nciu > createReqPend;
217  tsDLList < nciu > createRespPend;
218  tsDLList < nciu > v42ConnCallbackPend;
219  tsDLList < nciu > subscripReqPend;
220  tsDLList < nciu > connectedList;
221  tsDLList < nciu > unrespCircuit;
222  tsDLList < nciu > subscripUpdateReqPend;
224  arrayElementCount curDataMax;
225  arrayElementCount curDataBytes;
226  comBufMemoryManager & comBufMemMgr;
227  cac & cacRef;
228  char * pCurData;
229  SearchDestTCP * pSearchDest;
230  epicsMutex & mutex;
231  epicsMutex & cbMutex;
232  unsigned minorProtocolVersion;
234  iiucs_connecting, // pending circuit connect
235  iiucs_connected, // live circuit
236  iiucs_clean_shutdown, // live circuit will shutdown when flush completes
237  iiucs_disconnected, // socket informed us of disconnect
238  iiucs_abort_shutdown // socket has been closed
239  } state;
247  unsigned channelCountTot;
249  bool busyStateDetected; // only modified by the recv thread
250  bool flowControlActive; // only modified by the send process thread
259 
260  bool processIncoming (
261  const epicsTime & currentTime, callbackManager & );
262  unsigned sendBytes ( const void *pBuf,
263  unsigned nBytesInBuf, const epicsTime & currentTime );
264  void recvBytes (
265  void * pBuf, unsigned nBytesInBuf, statusWireIO & );
266  const char * pHostName (
267  epicsGuard < epicsMutex > & ) const throw ();
268  double receiveWatchdogDelay (
269  epicsGuard < epicsMutex > & ) const;
270  void unresponsiveCircuitNotify (
271  epicsGuard < epicsMutex > & cbGuard,
272  epicsGuard < epicsMutex > & guard );
273  void initiateCleanShutdown (
274  epicsGuard < epicsMutex > & );
275  void initiateAbortShutdown (
276  epicsGuard < epicsMutex > & );
277  void disconnectNotify (
278  epicsGuard < epicsMutex > & );
279  bool bytesArePendingInOS () const;
280  void decrementBlockingForFlushCount (
281  epicsGuard < epicsMutex > & guard );
282  bool isNameService () const;
283 
284  // send protocol stubs
285  void echoRequest (
286  epicsGuard < epicsMutex > & );
287  void versionMessage (
288  epicsGuard < epicsMutex > &, const cacChannel::priLev & priority );
289  void disableFlowControlRequest (
290  epicsGuard < epicsMutex > & );
291  void enableFlowControlRequest (
292  epicsGuard < epicsMutex > & );
293  void hostNameSetRequest (
294  epicsGuard < epicsMutex > & );
295  void userNameSetRequest (
296  epicsGuard < epicsMutex > & );
297  void createChannelRequest (
298  nciu &, epicsGuard < epicsMutex > & );
299  void writeRequest (
300  epicsGuard < epicsMutex > &, nciu &,
301  unsigned type, arrayElementCount nElem, const void *pValue );
302  void writeNotifyRequest (
303  epicsGuard < epicsMutex > &, nciu &,
304  netWriteNotifyIO &, unsigned type,
305  arrayElementCount nElem, const void *pValue );
306  void readNotifyRequest (
307  epicsGuard < epicsMutex > &, nciu &,
308  netReadNotifyIO &, unsigned type,
309  arrayElementCount nElem );
310  void subscriptionRequest (
311  epicsGuard < epicsMutex > &,
312  nciu &, netSubscription & subscr );
313  void subscriptionUpdateRequest (
314  epicsGuard < epicsMutex > &,
315  nciu & chan, netSubscription & subscr );
316  void subscriptionCancelRequest (
317  epicsGuard < epicsMutex > &,
318  nciu & chan, netSubscription & subscr );
319  void flushIfRecvProcessRequested (
320  epicsGuard < epicsMutex > & );
321  bool sendThreadFlush (
322  epicsGuard < epicsMutex > & );
323 
324  // netiiu stubs
325  void uninstallChanDueToSuccessfulSearchResponse (
326  epicsGuard < epicsMutex > &, nciu &, const class epicsTime & );
327  bool searchMsg (
328  epicsGuard < epicsMutex > &, ca_uint32_t id,
329  const char * pName, unsigned nameLength );
330 
331  friend class tcpRecvThread;
332  friend class tcpSendThread;
333 
334  tcpiiu ( const tcpiiu & );
335  tcpiiu & operator = ( const tcpiiu & );
336  void operator delete ( void * );
337 };
338 
339 inline void * tcpiiu::operator new ( size_t size,
340  tsFreeList < class tcpiiu, 32, epicsMutexNOOP > & mgr )
341 {
342  return mgr.allocate ( size );
343 }
344 
345 #ifdef CXX_PLACEMENT_DELETE
346 inline void tcpiiu::operator delete ( void * pCadaver,
348 {
349  mgr.release ( pCadaver );
350 }
351 #endif
352 
353 inline bool tcpiiu::ca_v41_ok (
354  epicsGuard < epicsMutex > & ) const
355 {
356  return CA_V41 ( this->minorProtocolVersion );
357 }
358 
359 inline bool tcpiiu::ca_v44_ok (
360  epicsGuard < epicsMutex > & ) const
361 {
362  return CA_V44 ( this->minorProtocolVersion );
363 }
364 
365 inline bool tcpiiu::ca_v49_ok (
366  epicsGuard < epicsMutex > & ) const
367 {
368  return CA_V49 ( this->minorProtocolVersion );
369 }
370 
371 inline bool tcpiiu::alive (
372  epicsGuard < epicsMutex > & ) const
373 {
374  return ( this->state == iiucs_connecting ||
375  this->state == iiucs_connected );
376 }
377 
378 inline bool tcpiiu::connecting (
379  epicsGuard < epicsMutex > & ) const
380 {
381  return ( this->state == iiucs_connecting );
382 }
383 
385  epicsGuard < epicsMutex > & guard )
386 {
387  guard.assertIdenticalMutex ( this->mutex );
388  return this->_receiveThreadIsBusy;
389 }
390 
392  epicsGuard < epicsMutex > & guard )
393 {
394  //guard.assertIdenticalMutex ( this->cacRef.mutexRef () );
395  this->recvDog.beaconAnomalyNotify ( guard );
396 }
397 
399  epicsGuard < epicsMutex > & guard )
400 {
401  //guard.assertIdenticalMutex ( this->cacRef.mutexRef () );
402  this->recvDog.beaconArrivalNotify ( guard );
403 }
404 
406  epicsGuard < epicsMutex > & cbGuard )
407 {
408  this->recvDog.probeResponseNotify ( cbGuard );
409 }
410 
411 inline bool tcpiiu::isNameService () const
412 {
413  return ( this->pSearchDest != NULL );
414 }
415 
416 inline void SearchDestTCP::setCircuit ( tcpiiu * piiu )
417 {
418  _ptcpiiu = piiu;
419 }
420 
421 #endif // ifdef INC_virtualCircuit_H
void searchRequest(epicsGuard< epicsMutex > &guard, const char *pbuf, size_t len)
Definition: tcpiiu.cpp:2155
bool ca_v44_ok(epicsGuard< epicsMutex > &) const
Definition: cac.h:97
bool socketHasBeenClosed
LIBCA_API int epicsStdCall ca_v42_ok(chid chan)
epicsEvent flushBlockEvent
epicsMutex & cbMutex
ca_uint32_t m_postsize
bool unresponsiveCircuit
pvd::StructureConstPtr type
unsigned int ca_uint32_t
Definition: caProto.h:76
bool connecting(epicsGuard< epicsMutex > &) const
void assertIdenticalMutex(const T &) const
Definition: epicsGuard.h:80
unsigned blockingForFlush
#define NULL
Definition: catime.c:38
ca_uint16_t m_dataType
unsigned short ca_uint16_t
Definition: caProto.h:75
unsigned priLev
Definition: cacIO.h:165
#define CA_V44(MINOR)
Definition: caProto.h:35
#define CA_V49(MINOR)
Definition: caProto.h:40
bool earlyFlush
bool recvProcessPostponedFlush
bool isNameService() const
ca_uint32_t m_count
unsigned channelCountTot
epicsMutex mutex
Definition: pvAccess.cpp:71
unsigned unacknowledgedSendBytes
bool alive(epicsGuard< epicsMutex > &) const
int SOCKET
Definition: osdSock.h:31
unsigned socketLibrarySendBufferSize
bool ca_v41_ok(epicsGuard< epicsMutex > &) const
void beaconArrivalNotify(epicsGuard< epicsMutex > &)
epicsEvent sendThreadFlushEvent
ca_uint32_t m_cid
unsigned contigRecvMsgCount
unsigned long arrayElementCount
Definition: cacIO.h:57
bool busyStateDetected
void setCircuit(tcpiiu *)
bool flowControlActive
bool discardingPendingData
epicsEventId flush
Definition: errlog.c:70
ca_uint16_t m_cmmd
Definition: udpiiu.h:79
bool receiveThreadIsBusy(epicsGuard< epicsMutex > &)
void beaconAnomalyNotify(epicsGuard< epicsMutex > &)
ca_uint32_t m_available
bool ca_v49_ok(epicsGuard< epicsMutex > &) const
SOCKET sock
Compiler specific declarations.
bool oldMsgHeaderAvailable
Definition: netiiu.h:37
void probeResponseNotify(epicsGuard< epicsMutex > &)
bool _receiveThreadIsBusy
bool echoRequestPending
#define CA_V41(MINOR)
Definition: caProto.h:32
bool msgHeaderAvailable
Definition: nciu.h:127