This is Unofficial EPICS BASE Doxygen Site
cacIO.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  * L O S A L A M O S
13  * Los Alamos National Laboratory
14  * Los Alamos, New Mexico 87545
15  *
16  * Copyright, 1986, The Regents of the University of California.
17  *
18  *
19  * Author Jeffrey O. Hill
20  * johill@lanl.gov
21  * 505 665 1831
22  */
23 
24 #ifndef INC_cacIO_H
25 #define INC_cacIO_H
26 
27 //
28 // Open Issues
29 // -----------
30 //
31 // 1) A status code from the old client side interface is passed
32 // to the exception notify callback. Should we just pass a string?
33 // If so, then how do they detect the type of error and recover.
34 // Perhaps we should call a different vf for each type of exception.
35 //
36 // 2) Some exception types are present here but there is no common
37 // exception base class in use.
38 //
39 // 3) Should I be passing the channel reference in cacChannelNotify?
40 //
41 // 4) Should the code for caAccessRights not be inline so that this
42 // interface is version independent.
43 //
44 //
45 
46 #include <new>
47 #include <stdarg.h>
48 
49 #include "tsDLList.h"
50 #include "epicsMutex.h"
51 #include "epicsGuard.h"
52 #include "epicsThread.h"
53 
54 #include "libCaAPI.h"
55 
56 
57 class cacChannel;
58 
59 typedef unsigned long arrayElementCount;
60 
61 // 1) this should not be passing caerr.h status to the exception callback
62 // 2) needless-to-say the data should be passed here using the new data access API
63 class LIBCA_API cacWriteNotify {
64 public:
65  virtual ~cacWriteNotify () = 0;
66  virtual void completion ( epicsGuard < epicsMutex > & ) = 0;
67 // we should probably have a different vf for each type of exception ????
68  virtual void exception (
70  int status, const char * pContext,
71  unsigned type, arrayElementCount count ) = 0;
72 };
73 
74 // 1) this should not be passing caerr.h status to the exception callback
75 // 2) needless-to-say the data should be passed here using the new data access API
76 class LIBCA_API cacReadNotify {
77 public:
78  virtual ~cacReadNotify () = 0;
79  virtual void completion (
80  epicsGuard < epicsMutex > &, unsigned type,
81  arrayElementCount count, const void * pData ) = 0;
82 // we should probably have a different vf for each type of exception ????
83  virtual void exception (
85  const char * pContext, unsigned type,
86  arrayElementCount count ) = 0;
87 };
88 
89 // 1) this should not be passing caerr.h status to the exception callback
90 // 2) needless-to-say the data should be passed here using the new data access API
91 class LIBCA_API cacStateNotify {
92 public:
93  virtual ~cacStateNotify () = 0;
94  virtual void current (
95  epicsGuard < epicsMutex > &, unsigned type,
96  arrayElementCount count, const void * pData ) = 0;
97 // we should probably have a different vf for each type of exception ????
98  virtual void exception (
100  const char *pContext, unsigned type,
101  arrayElementCount count ) = 0;
102 };
103 
105 public:
107  bool readPermit = false,
108  bool writePermit = false,
109  bool operatorConfirmationRequest = false);
110  void setReadPermit ();
111  void setWritePermit ();
112  void setOperatorConfirmationRequest ();
113  void clrReadPermit ();
114  void clrWritePermit ();
115  void clrOperatorConfirmationRequest ();
116  bool readPermit () const;
117  bool writePermit () const;
118  bool operatorConfirmationRequest () const;
119 private:
120  bool f_readPermit:1;
121  bool f_writePermit:1;
122  bool f_operatorConfirmationRequest:1;
123 };
124 
125 class LIBCA_API cacChannelNotify {
126 public:
127  virtual ~cacChannelNotify () = 0;
128  virtual void connectNotify ( epicsGuard < epicsMutex > & ) = 0;
129  virtual void disconnectNotify ( epicsGuard < epicsMutex > & ) = 0;
130  virtual void serviceShutdownNotify (
131  epicsGuard < epicsMutex > & mutualExclusionGuard ) = 0;
132  virtual void accessRightsNotify (
133  epicsGuard < epicsMutex > &, const caAccessRights & ) = 0;
134  virtual void exception (
135  epicsGuard < epicsMutex > &, int status, const char *pContext ) = 0;
136 // we should probably have a different vf for each type of exception ????
137  virtual void readException (
138  epicsGuard < epicsMutex > &, int status, const char *pContext,
139  unsigned type, arrayElementCount count, void *pValue ) = 0;
140 // we should probably have a different vf for each type of exception ????
141  virtual void writeException (
142  epicsGuard < epicsMutex > &, int status, const char * pContext,
143  unsigned type, arrayElementCount count ) = 0;
144 };
145 
147  public epicsGuard < epicsMutex > {
148 public:
149  CallbackGuard ( epicsMutex & mutex ) :
150  epicsGuard < epicsMutex > ( mutex ) {}
151 private:
152  CallbackGuard ( const CallbackGuard & );
153  CallbackGuard & operator = ( const CallbackGuard & );
154 };
155 
156 //
157 // Notes
158 // 1) This interface assumes that when a channel is deleted then all
159 // attached IO is deleted. This is left over from the old interface,
160 // but perhaps is a bad practice that should be eliminated? If so,
161 // then the IO should not store or use a pointer to the channel.
162 //
163 class LIBCA_API cacChannel {
164 public:
165  typedef unsigned priLev;
166  static const priLev priorityMax;
167  static const priLev priorityMin;
168  static const priLev priorityDefault;
169  static const priLev priorityLinksDB;
170  static const priLev priorityArchive;
171  static const priLev priorityOPI;
172 
173  typedef unsigned ioid;
174  enum ioStatus { iosSynch, iosAsynch };
175 
177  virtual void destroy (
178  CallbackGuard & callbackGuard,
179  epicsGuard < epicsMutex > & mutualExclusionGuard ) = 0;
180  cacChannelNotify & notify () const; // required ?????
181  virtual unsigned getName (
183  char * pBuf, unsigned bufLen ) const throw () = 0;
184  // !! deprecated, avoid use !!
185  virtual const char * pName (
186  epicsGuard < epicsMutex > & guard ) const throw () = 0;
187  virtual void show (
189  unsigned level ) const = 0;
190  virtual void initiateConnect (
192  virtual unsigned requestMessageBytesPending (
193  epicsGuard < epicsMutex > & mutualExclusionGuard ) = 0;
194  virtual void flush (
195  epicsGuard < epicsMutex > & mutualExclusionGuard ) = 0;
196  virtual ioStatus read (
198  unsigned type, arrayElementCount count,
199  cacReadNotify &, ioid * = 0 ) = 0;
200  virtual void write (
202  unsigned type, arrayElementCount count,
203  const void *pValue ) = 0;
204  virtual ioStatus write (
206  unsigned type, arrayElementCount count,
207  const void *pValue, cacWriteNotify &, ioid * = 0 ) = 0;
208  virtual void subscribe (
209  epicsGuard < epicsMutex > &, unsigned type,
210  arrayElementCount count, unsigned mask, cacStateNotify &,
211  ioid * = 0 ) = 0;
212  // The primary mutex must be released when calling the user's
213  // callback, and therefore a finite interval exists when we are
214  // moving forward with the intent to call the users callback
215  // but the users IO could be deleted during this interval.
216  // To prevent the user's callback from being called after
217  // destroying his IO we must past a guard for the callback
218  // mutex here.
219  virtual void ioCancel (
220  CallbackGuard & callbackGuard,
221  epicsGuard < epicsMutex > & mutualExclusionGuard,
222  const ioid & ) = 0;
223  virtual void ioShow (
225  const ioid &, unsigned level ) const = 0;
226  virtual short nativeType (
227  epicsGuard < epicsMutex > & ) const = 0;
228  virtual arrayElementCount nativeElementCount (
229  epicsGuard < epicsMutex > & ) const = 0;
230  virtual caAccessRights accessRights (
231  epicsGuard < epicsMutex > & ) const;
232  virtual unsigned searchAttempts (
233  epicsGuard < epicsMutex > & ) const;
234  virtual double beaconPeriod (
235  epicsGuard < epicsMutex > & ) const; // negative DBL_MAX if UKN
236  virtual double receiveWatchdogDelay (
237  epicsGuard < epicsMutex > & ) const; // negative DBL_MAX if UKN
238  virtual bool ca_v42_ok (
239  epicsGuard < epicsMutex > & ) const;
240  virtual bool connected (
241  epicsGuard < epicsMutex > & ) const;
242  virtual unsigned getHostName (
244  char * pBuf, unsigned bufLength ) const throw ();
245  // !! deprecated, avoid use !!
246  virtual const char * pHostName (
247  epicsGuard < epicsMutex > & guard ) const throw ();
248 
249  // exceptions
250  class badString {};
251  class badType {};
252  class badPriority {};
253  class outOfBounds {};
255  class noWriteAccess {};
256  class noReadAccess {};
257  class notConnected {};
259  class msgBodyCacheTooSmall {}; // hopefully this one goes away in the future
260  class requestTimedOut {};
261 
262 protected:
263  virtual ~cacChannel () = 0;
264 
265 private:
267  cacChannel ( const cacChannel & );
268  cacChannel & operator = ( const cacChannel & );
269 };
270 
271 class LIBCA_API cacContext {
272 public:
273  virtual ~cacContext ();
274  virtual cacChannel & createChannel (
276  const char * pChannelName, cacChannelNotify &,
278  virtual void flush (
280  virtual unsigned circuitCount (
281  epicsGuard < epicsMutex > & ) const = 0;
282  virtual void selfTest (
283  epicsGuard < epicsMutex > & ) const = 0;
284  virtual unsigned beaconAnomaliesSinceProgramStart (
285  epicsGuard < epicsMutex > & ) const = 0;
286  virtual void show (
287  epicsGuard < epicsMutex > &, unsigned level ) const = 0;
288 };
289 
290 class LIBCA_API cacContextNotify {
291 public:
292  virtual ~cacContextNotify () = 0;
293  virtual cacContext & createNetworkContext (
294  epicsMutex & mutualExclusion, epicsMutex & callbackControl ) = 0;
295 // we should probably have a different vf for each type of exception ????
296  virtual void exception (
297  epicsGuard < epicsMutex > &, int status, const char * pContext,
298  const char * pFileName, unsigned lineNo ) = 0;
299 // perhaps this should be phased out in deference to the exception mechanism
300  virtual int varArgsPrintFormated ( const char * pformat, va_list args ) const = 0;
301 // backwards compatibility (from here down)
302  virtual void attachToClientCtx () = 0;
303  virtual void callbackProcessingInitiateNotify () = 0;
304  virtual void callbackProcessingCompleteNotify () = 0;
305 };
306 
307 // **** Lock Hierarchy ****
308 // callbackControl must be taken before mutualExclusion if both are held at
309 // the same time
310 class LIBCA_API cacService {
311 public:
312  virtual ~cacService () = 0;
313  virtual cacContext & contextCreate (
314  epicsMutex & mutualExclusion,
315  epicsMutex & callbackControl,
316  cacContextNotify & ) = 0;
317 };
318 
319 LIBCA_API void epicsStdCall caInstallDefaultService ( cacService & service );
320 
322 
324  callback ( notify )
325 {
326 }
327 
329 {
330  return this->callback;
331 }
332 
334  bool readPermit, bool writePermit, bool operatorConfirmationRequest) :
335  f_readPermit ( readPermit ), f_writePermit ( writePermit ),
336  f_operatorConfirmationRequest ( operatorConfirmationRequest ) {}
337 
339 {
340  this->f_readPermit = true;
341 }
342 
344 {
345  this->f_writePermit = true;
346 }
347 
349 {
350  this->f_operatorConfirmationRequest = true;
351 }
352 
354 {
355  this->f_readPermit = false;
356 }
357 
359 {
360  this->f_writePermit = false;
361 }
362 
364 {
365  this->f_operatorConfirmationRequest = false;
366 }
367 
368 inline bool caAccessRights::readPermit () const
369 {
370  return this->f_readPermit;
371 }
372 
373 inline bool caAccessRights::writePermit () const
374 {
375  return this->f_writePermit;
376 }
377 
379 {
380  return this->f_operatorConfirmationRequest;
381 }
382 
383 #endif // ifndef INC_cacIO_H
void setReadPermit()
Definition: cacIO.h:338
LIBCA_API int epicsStdCall ca_v42_ok(chid chan)
pvd::Status status
static const priLev priorityMin
Definition: cacIO.h:167
bool writePermit() const
Definition: cacIO.h:373
static const priLev priorityMax
Definition: cacIO.h:166
pvd::StructureConstPtr type
CallbackGuard(epicsMutex &mutex)
Definition: cacIO.h:149
cacChannel(cacChannelNotify &)
Definition: cacIO.h:323
static const priLev priorityOPI
Definition: cacIO.h:171
unsigned priLev
Definition: cacIO.h:165
LIBCA_API epicsThreadPrivateId caClientCallbackThreadId
void setOperatorConfirmationRequest()
Definition: cacIO.h:348
unsigned ioid
Definition: cacIO.h:173
static const priLev priorityLinksDB
Definition: cacIO.h:169
void setWritePermit()
Definition: cacIO.h:343
LIBCA_API void epicsStdCall caInstallDefaultService(cacService &service)
APIs for the epicsMutex mutual exclusion semaphore.
bool operatorConfirmationRequest() const
Definition: cacIO.h:378
Definition: caget.c:48
bool readPermit() const
Definition: cacIO.h:368
unsigned long arrayElementCount
Definition: cacIO.h:57
epicsEventId flush
Definition: errlog.c:70
void clrWritePermit()
Definition: cacIO.h:358
void clrOperatorConfirmationRequest()
Definition: cacIO.h:363
C++ and C descriptions for a thread.
void clrReadPermit()
Definition: cacIO.h:353
caAccessRights(bool readPermit=false, bool writePermit=false, bool operatorConfirmationRequest=false)
Definition: cacIO.h:333
static const priLev priorityArchive
Definition: cacIO.h:170
static const priLev priorityDefault
Definition: cacIO.h:168
cacChannelNotify & notify() const
Definition: cacIO.h:328