This is Unofficial EPICS BASE Doxygen Site
ca_client_context Struct Reference

#include "oldAccess.h"

+ Inheritance diagram for ca_client_context:
+ Collaboration diagram for ca_client_context:

Classes

class  noSocket
 

Public Member Functions

 ca_client_context (bool enablePreemptiveCallback=false)
 
virtual ~ca_client_context ()
 
void changeExceptionEvent (caExceptionHandler *pfunc, void *arg)
 
void registerForFileDescriptorCallBack (CAFDHANDLER *pFunc, void *pArg)
 
void replaceErrLogHandler (caPrintfFunc *ca_printf_func)
 
cacChannelcreateChannel (epicsGuard< epicsMutex > &, const char *pChannelName, cacChannelNotify &, cacChannel::priLev pri)
 
void flush (epicsGuard< epicsMutex > &)
 
void eliminateExcessiveSendBacklog (epicsGuard< epicsMutex > &, cacChannel &)
 
int pendIO (const double &timeout)
 
int pendEvent (const double &timeout)
 
bool ioComplete () const
 
void show (unsigned level) const
 
unsigned circuitCount () const
 
unsigned sequenceNumberOfOutstandingIO (epicsGuard< epicsMutex > &) const
 
unsigned beaconAnomaliesSinceProgramStart () const
 
void incrementOutstandingIO (epicsGuard< epicsMutex > &, unsigned ioSeqNo)
 
void decrementOutstandingIO (epicsGuard< epicsMutex > &, unsigned ioSeqNo)
 
void blockForEventAndEnableCallbacks (epicsEvent &event, const double &timeout)
 
CASGlookupCASG (epicsGuard< epicsMutex > &, unsigned id)
 
void installCASG (epicsGuard< epicsMutex > &, CASG &)
 
void uninstallCASG (epicsGuard< epicsMutex > &, CASG &)
 
void selfTest () const
 
int printFormated (const char *pformat,...) const
 
int varArgsPrintFormated (const char *pformat, va_list args) const
 
void signal (int ca_status, const char *pfilenm, int lineno, const char *pFormat,...)
 
void vSignal (int ca_status, const char *pfilenm, int lineno, const char *pFormat, va_list args)
 
bool preemptiveCallbakIsEnabled () const
 
void destroyGetCopy (epicsGuard< epicsMutex > &, getCopy &)
 
void destroyGetCallback (epicsGuard< epicsMutex > &, getCallback &)
 
void destroyPutCallback (epicsGuard< epicsMutex > &, putCallback &)
 
void destroySubscription (epicsGuard< epicsMutex > &, oldSubscription &)
 
epicsMutex & mutexRef () const
 
template<class T >
void whenThereIsAnExceptionDestroySyncGroupIO (epicsGuard< epicsMutex > &, T &)
 
- Public Member Functions inherited from cacContextNotify
virtual ~cacContextNotify ()=0
 

Static Public Member Functions

static void installDefaultService (cacService &)
 

Public Attributes

void exception epicsGuard< epicsMutex > int status
 
void exception epicsGuard< epicsMutex > int const char * pContext
 
void exception epicsGuard< epicsMutex > int const char const char * pFileName
 
void exception epicsGuard< epicsMutex > int const char const char unsigned lineNo
 
void exception epicsGuard< epicsMutex > int const char const char unsigned oldChannelNotifychan
 
void exception epicsGuard< epicsMutex > int const char const char unsigned oldChannelNotify unsigned type
 
void exception epicsGuard< epicsMutex > int const char const char unsigned oldChannelNotify unsigned arrayElementCount count
 
void exception epicsGuard< epicsMutex > int const char const char unsigned oldChannelNotify unsigned arrayElementCount unsigned op
 
- Public Attributes inherited from cacContextNotify
virtual void exception epicsGuard< epicsMutex > int status
 
virtual void exception epicsGuard< epicsMutex > int const char * pContext
 
virtual void exception epicsGuard< epicsMutex > int const char const char * pFileName
 
virtual void exception epicsGuard< epicsMutex > int const char const char unsigned lineNo = 0
 

Friends

int epicsStdCall ca_create_channel (const char *name_str, caCh *conn_func, void *puser, capri priority, chid *chanptr)
 
int epicsStdCall ca_clear_channel (chid pChan)
 
int epicsStdCall ca_array_get (chtype type, arrayElementCount count, chid pChan, void *pValue)
 
int epicsStdCall ca_array_get_callback (chtype type, arrayElementCount count, chid pChan, caEventCallBackFunc *pfunc, void *arg)
 
int epicsStdCall ca_array_put (chtype type, arrayElementCount count, chid pChan, const void *pValue)
 
int epicsStdCall ca_array_put_callback (chtype type, arrayElementCount count, chid pChan, const void *pValue, caEventCallBackFunc *pfunc, void *usrarg)
 
int epicsStdCall ca_create_subscription (chtype type, arrayElementCount count, chid pChan, long mask, caEventCallBackFunc *pCallBack, void *pCallBackArg, evid *monixptr)
 
int epicsStdCall ca_flush_io ()
 
int epicsStdCall ca_clear_subscription (evid pMon)
 
int epicsStdCall ca_sg_create (CA_SYNC_GID *pgid)
 
int epicsStdCall ca_sg_delete (const CA_SYNC_GID gid)
 
int epicsStdCall ca_sg_block (const CA_SYNC_GID gid, ca_real timeout)
 
int epicsStdCall ca_sg_reset (const CA_SYNC_GID gid)
 
int epicsStdCall ca_sg_test (const CA_SYNC_GID gid)
 
int epicsStdCall ca_sg_array_get (const CA_SYNC_GID gid, chtype type, arrayElementCount count, chid pChan, void *pValue)
 
int epicsStdCall ca_sg_array_put (const CA_SYNC_GID gid, chtype type, arrayElementCount count, chid pChan, const void *pValue)
 
int ca_sync_group_destroy (CallbackGuard &cbGuard, epicsGuard< epicsMutex > &guard, ca_client_context &cac, const CA_SYNC_GID gid)
 
void sync_group_reset (ca_client_context &client, CASG &sg)
 
void cacOnceFunc (void *)
 

Detailed Description

Definition at line 283 of file oldAccess.h.

Constructor & Destructor Documentation

ca_client_context::ca_client_context ( bool  enablePreemptiveCallback = false)

Definition at line 60 of file ca_client_context.cpp.

60  :
61  mutex(__FILE__, __LINE__),
62  cbMutex(__FILE__, __LINE__),
63  createdByThread ( epicsThreadGetIdSelf () ),
64  ca_exception_func ( 0 ), ca_exception_arg ( 0 ),
65  pVPrintfFunc ( errlogVprintf ), fdRegFunc ( 0 ), fdRegArg ( 0 ),
66  pndRecvCnt ( 0u ), ioSeqNo ( 0u ), callbackThreadsPending ( 0u ),
67  localPort ( 0 ), fdRegFuncNeedsToBeCalled ( false ),
68  noWakeupSincePend ( true )
69 {
70  static const unsigned short PORT_ANY = 0u;
71 
72  if ( ! osiSockAttach () ) {
73  throwWithLocation ( noSocket () );
74  }
75 
76  epicsThreadOnce ( & cacOnce, cacOnceFunc, 0 );
77  {
78  epicsGuard < epicsMutex > guard ( *ca_client_context::pDefaultServiceInstallMutex );
79  if ( ca_client_context::pDefaultService ) {
80  this->pServiceContext.reset (
81  & ca_client_context::pDefaultService->contextCreate (
82  this->mutex, this->cbMutex, *this ) );
83  }
84  else {
85  this->pServiceContext.reset ( new cac ( this->mutex, this->cbMutex, *this ) );
86  }
87  }
88 
89  this->sock = epicsSocketCreate ( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
90  if ( this->sock == INVALID_SOCKET ) {
91  char sockErrBuf[64];
92  epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) );
93  this->printFormated (
94  "ca_client_context: unable to create "
95  "datagram socket because = \"%s\"\n",
96  sockErrBuf );
97  throwWithLocation ( noSocket () );
98  }
99 
100  {
101  osiSockIoctl_t yes = true;
102  int status = socket_ioctl ( this->sock,
103  FIONBIO, & yes);
104  if ( status < 0 ) {
105  char sockErrBuf[64];
106  epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) );
107  epicsSocketDestroy ( this->sock );
108  this->printFormated (
109  "%s: non blocking IO set fail because \"%s\"\n",
110  __FILE__, sockErrBuf );
111  throwWithLocation ( noSocket () );
112  }
113  }
114 
115  // force a bind to an unconstrained address so we can obtain
116  // the local port number below
117  {
118  osiSockAddr addr;
119  memset ( (char *)&addr, 0 , sizeof ( addr ) );
120  addr.ia.sin_family = AF_INET;
121  addr.ia.sin_addr.s_addr = htonl ( INADDR_ANY );
122  addr.ia.sin_port = htons ( PORT_ANY );
123  int status = bind (this->sock, &addr.sa, sizeof (addr) );
124  if ( status < 0 ) {
125  char sockErrBuf[64];
126  epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) );
127  epicsSocketDestroy (this->sock);
128  this->printFormated (
129  "CAC: unable to bind to an unconstrained "
130  "address because = \"%s\"\n",
131  sockErrBuf );
132  throwWithLocation ( noSocket () );
133  }
134  }
135 
136  {
137  osiSockAddr tmpAddr;
138  osiSocklen_t saddr_length = sizeof ( tmpAddr );
139  int status = getsockname ( this->sock, & tmpAddr.sa, & saddr_length );
140  if ( status < 0 ) {
141  char sockErrBuf[64];
142  epicsSocketConvertErrnoToString ( sockErrBuf, sizeof ( sockErrBuf ) );
143  epicsSocketDestroy ( this->sock );
144  this->printFormated ( "CAC: getsockname () error was \"%s\"\n", sockErrBuf );
145  throwWithLocation ( noSocket () );
146  }
147  if ( tmpAddr.sa.sa_family != AF_INET) {
148  epicsSocketDestroy ( this->sock );
149  this->printFormated ( "CAC: UDP socket was not inet addr family\n" );
150  throwWithLocation ( noSocket () );
151  }
152  this->localPort = htons ( tmpAddr.ia.sin_port );
153  }
154 
155  std::auto_ptr < CallbackGuard > pCBGuard;
156  if ( ! enablePreemptiveCallback ) {
157  pCBGuard.reset ( new CallbackGuard ( this->cbMutex ) );
158  }
159 
160  // multiple steps ensure exception safety
161  this->pCallbackGuard = pCBGuard;
162 }
void exception epicsGuard< epicsMutex > int status
Definition: oldAccess.h:311
LIBCOM_API void epicsStdCall epicsSocketDestroy(SOCKET s)
Definition: osdSock.c:117
Definition: cac.h:97
#define INVALID_SOCKET
Definition: osdSock.h:32
int osiSocklen_t
Definition: osdSock.h:36
struct sockaddr sa
Definition: osiSock.h:158
int errlogVprintf(const char *pFormat, va_list pvar)
Definition: errlog.c:144
struct sockaddr_in ia
Definition: osiSock.h:157
int printFormated(const char *pformat,...) const
void epicsSocketConvertErrnoToString(char *pBuf, unsigned bufSize)
#define socket_ioctl(A, B, C)
Definition: osdSock.h:34
friend void cacOnceFunc(void *)
LIBCOM_API SOCKET epicsStdCall epicsSocketCreate(int domain, int type, int protocol)
Definition: osdSock.c:71
int osiSockIoctl_t
Definition: osdSock.h:35
LIBCOM_API void epicsStdCall epicsThreadOnce(epicsThreadOnceId *id, EPICSTHREADFUNC, void *arg)
int osiSockAttach()
Definition: osdSock.c:54
#define throwWithLocation(parm)
LIBCOM_API epicsThreadId epicsStdCall epicsThreadGetIdSelf(void)
Definition: osdThread.c:810
ca_client_context::~ca_client_context ( )
virtual

Definition at line 164 of file ca_client_context.cpp.

165 {
166  if ( this->fdRegFunc ) {
167  ( *this->fdRegFunc )
168  ( this->fdRegArg, this->sock, false );
169  }
170  epicsSocketDestroy ( this->sock );
171 
172  osiSockRelease ();
173 
174  // force a logical shutdown order
175  // so that the cac class does not hang its
176  // receive threads during their shutdown sequence
177  // and so that classes using this classes mutex
178  // are destroyed before the mutex is destroyed
179  if ( this->pCallbackGuard.get() ) {
180  epicsGuardRelease < epicsMutex > unguard ( *this->pCallbackGuard );
181  this->pServiceContext.reset ( 0 );
182  }
183  else {
184  this->pServiceContext.reset ( 0 );
185  }
186 }
LIBCOM_API void epicsStdCall epicsSocketDestroy(SOCKET s)
Definition: osdSock.c:117
void osiSockRelease()
Definition: osdSock.c:62

Member Function Documentation

unsigned ca_client_context::beaconAnomaliesSinceProgramStart ( ) const

Definition at line 675 of file ca_client_context.cpp.

676 {
677  epicsGuard < epicsMutex > guard ( this->mutex );
678  return this->pServiceContext->beaconAnomaliesSinceProgramStart ( guard );
679 }
void ca_client_context::blockForEventAndEnableCallbacks ( epicsEvent &  event,
const double &  timeout 
)

Definition at line 588 of file ca_client_context.cpp.

590 {
591  if ( this->pCallbackGuard.get() ) {
592  epicsGuardRelease < epicsMutex > unguard ( *this->pCallbackGuard );
593  event.wait ( timeout );
594  }
595  else {
596  event.wait ( timeout );
597  }
598 }
double timeout
Definition: pvutils.cpp:25
void ca_client_context::changeExceptionEvent ( caExceptionHandler pfunc,
void *  arg 
)

Definition at line 220 of file ca_client_context.cpp.

222 {
223  epicsGuard < epicsMutex > guard ( this->mutex );
224  this->ca_exception_func = pfunc;
225  this->ca_exception_arg = arg;
226 // should block here until releated callback in progress completes
227 }
unsigned ca_client_context::circuitCount ( ) const

Definition at line 669 of file ca_client_context.cpp.

670 {
671  epicsGuard < epicsMutex > guard ( this->mutex );
672  return this->pServiceContext->circuitCount ( guard );
673 }
cacChannel & ca_client_context::createChannel ( epicsGuard< epicsMutex > &  guard,
const char *  pChannelName,
cacChannelNotify chan,
cacChannel::priLev  pri 
)

Definition at line 655 of file ca_client_context.cpp.

658 {
659  guard.assertIdenticalMutex ( this->mutex );
660  return this->pServiceContext->createChannel (
661  guard, pChannelName, chan, pri );
662 }
void assertIdenticalMutex(const T &) const
Definition: epicsGuard.h:80
void ca_client_context::decrementOutstandingIO ( epicsGuard< epicsMutex > &  guard,
unsigned  ioSeqNo 
)

Definition at line 449 of file ca_client_context.cpp.

451 {
452  guard.assertIdenticalMutex ( this->mutex );
453  if ( this->ioSeqNo == ioSeqNoIn ) {
454  assert ( this->pndRecvCnt > 0u );
455  this->pndRecvCnt--;
456  if ( this->pndRecvCnt == 0u ) {
457  this->ioDone.signal ();
458  }
459  }
460 }
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
void assertIdenticalMutex(const T &) const
Definition: epicsGuard.h:80
void ca_client_context::destroyGetCallback ( epicsGuard< epicsMutex > &  guard,
getCallback gcb 
)

Definition at line 196 of file ca_client_context.cpp.

198 {
199  guard.assertIdenticalMutex ( this->mutex );
200  gcb.~getCallback ();
201  this->getCallbackFreeList.release ( & gcb );
202 }
void assertIdenticalMutex(const T &) const
Definition: epicsGuard.h:80
void release(void *p)
Definition: tsFreeList.h:176
void ca_client_context::destroyGetCopy ( epicsGuard< epicsMutex > &  guard,
getCopy gc 
)

Definition at line 188 of file ca_client_context.cpp.

190 {
191  guard.assertIdenticalMutex ( this->mutex );
192  gc.~getCopy ();
193  this->getCopyFreeList.release ( & gc );
194 }
void assertIdenticalMutex(const T &) const
Definition: epicsGuard.h:80
~getCopy()
Definition: getCopy.cpp:47
void release(void *p)
Definition: tsFreeList.h:176
void ca_client_context::destroyPutCallback ( epicsGuard< epicsMutex > &  guard,
putCallback pcb 
)

Definition at line 204 of file ca_client_context.cpp.

206 {
207  guard.assertIdenticalMutex ( this->mutex );
208  pcb.~putCallback ();
209  this->putCallbackFreeList.release ( & pcb );
210 }
void assertIdenticalMutex(const T &) const
Definition: epicsGuard.h:80
void release(void *p)
Definition: tsFreeList.h:176
void ca_client_context::destroySubscription ( epicsGuard< epicsMutex > &  guard,
oldSubscription os 
)

Definition at line 212 of file ca_client_context.cpp.

214 {
215  guard.assertIdenticalMutex ( this->mutex );
216  os.~oldSubscription ();
217  this->subscriptionFreeList.release ( & os );
218 }
void assertIdenticalMutex(const T &) const
Definition: epicsGuard.h:80
void release(void *p)
Definition: tsFreeList.h:176
void ca_client_context::eliminateExcessiveSendBacklog ( epicsGuard< epicsMutex > &  guard,
cacChannel chan 
)

Definition at line 781 of file ca_client_context.cpp.

783 {
784  if ( chan.requestMessageBytesPending ( guard ) >
785  ca_client_context :: flushBlockThreshold ) {
786  if ( this->pCallbackGuard.get() &&
787  this->createdByThread == epicsThreadGetIdSelf () ) {
788  // we need to be very careful about lock hierarchy
789  // inversion in this situation
790  epicsGuardRelease < epicsMutex > unguard ( guard );
791  {
793  * this->pCallbackGuard.get() );
794  {
795  epicsGuard < epicsMutex > nestedGuard ( this->mutex );
796  chan.flush ( nestedGuard );
797  }
798  }
799  }
800  else {
801  chan.flush ( guard );
802  }
803  }
804 }
virtual void flush(epicsGuard< epicsMutex > &mutualExclusionGuard)=0
virtual unsigned requestMessageBytesPending(epicsGuard< epicsMutex > &mutualExclusionGuard)=0
LIBCOM_API epicsThreadId epicsStdCall epicsThreadGetIdSelf(void)
Definition: osdThread.c:810
void ca_client_context::flush ( epicsGuard< epicsMutex > &  guard)

Definition at line 664 of file ca_client_context.cpp.

665 {
666  this->pServiceContext->flush ( guard );
667 }
void ca_client_context::incrementOutstandingIO ( epicsGuard< epicsMutex > &  guard,
unsigned  ioSeqNo 
)

Definition at line 439 of file ca_client_context.cpp.

441 {
442  guard.assertIdenticalMutex ( this->mutex );
443  if ( this->ioSeqNo == ioSeqNoIn ) {
444  assert ( this->pndRecvCnt < UINT_MAX );
445  this->pndRecvCnt++;
446  }
447 }
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
void assertIdenticalMutex(const T &) const
Definition: epicsGuard.h:80
void ca_client_context::installCASG ( epicsGuard< epicsMutex > &  guard,
CASG sg 
)

Definition at line 681 of file ca_client_context.cpp.

683 {
684  guard.assertIdenticalMutex ( this->mutex );
685  this->sgTable.idAssignAdd ( sg );
686 }
void assertIdenticalMutex(const T &) const
Definition: epicsGuard.h:80
void idAssignAdd(ITEM &item)
Definition: resourceLib.h:964
void ca_client_context::installDefaultService ( cacService service)
static

Definition at line 726 of file ca_client_context.cpp.

727 {
728  epicsThreadOnce ( & cacOnce, cacOnceFunc, 0 );
729 
730  epicsGuard < epicsMutex > guard ( *ca_client_context::pDefaultServiceInstallMutex );
731  if ( ca_client_context::pDefaultService ) {
732  throw std::logic_error
733  ( "CA in-memory service already installed and can't be replaced");
734  }
735  ca_client_context::pDefaultService = & service;
736 }
friend void cacOnceFunc(void *)
LIBCOM_API void epicsStdCall epicsThreadOnce(epicsThreadOnceId *id, EPICSTHREADFUNC, void *arg)
bool ca_client_context::ioComplete ( ) const
inline

Definition at line 561 of file oldAccess.h.

562 {
563  return ( this->pndRecvCnt == 0u );
564 }
CASG * ca_client_context::lookupCASG ( epicsGuard< epicsMutex > &  guard,
unsigned  id 
)

Definition at line 695 of file ca_client_context.cpp.

697 {
698  guard.assertIdenticalMutex ( this->mutex );
699  CASG * psg = this->sgTable.lookup ( idIn );
700  if ( psg ) {
701  if ( ! psg->verify ( guard ) ) {
702  psg = 0;
703  }
704  }
705  return psg;
706 }
void assertIdenticalMutex(const T &) const
Definition: epicsGuard.h:80
T * lookup(const ID &idIn) const
Definition: resourceLib.h:342
bool verify(epicsGuard< epicsMutex > &) const
Definition: CASG.cpp:54
epicsMutex & ca_client_context::mutexRef ( ) const

Definition at line 715 of file ca_client_context.cpp.

716 {
717  return this->mutex;
718 }
int ca_client_context::pendEvent ( const double &  timeout)

Definition at line 516 of file ca_client_context.cpp.

517 {
518  // prevent recursion nightmares by disabling calls to
519  // pendIO () from within a CA callback.
521  return ECA_EVDISALLOW;
522  }
523 
524  epicsTime current = epicsTime::getCurrent ();
525 
526  {
527  epicsGuard < epicsMutex > guard ( this->mutex );
528  this->flush ( guard );
529  }
530 
531  // process at least once if preemptive callback is disabled
532  if ( this->pCallbackGuard.get() ) {
533  epicsGuardRelease < epicsMutex > cbUnguard ( *this->pCallbackGuard );
534  epicsGuard < epicsMutex > guard ( this->mutex );
535 
536  //
537  // This is needed because in non-preemptive callback mode
538  // legacy applications that use file descriptor managers
539  // will register for ca receive thread activity and keep
540  // calling ca_pend_event until all of the socket data has
541  // been read. We must guarantee that other threads get a
542  // chance to run if there is data in any of the sockets.
543  //
544  if ( this->fdRegFunc ) {
545  epicsGuardRelease < epicsMutex > unguard ( guard );
546 
547  // remove short udp message sent to wake
548  // up a file descriptor manager
549  osiSockAddr tmpAddr;
550  osiSocklen_t addrSize = sizeof ( tmpAddr.sa );
551  char buf = 0;
552  int status = 0;
553  do {
554  status = recvfrom ( this->sock, & buf, sizeof ( buf ),
555  0, & tmpAddr.sa, & addrSize );
556  } while ( status > 0 );
557  }
558  while ( this->callbackThreadsPending > 0 ) {
559  epicsGuardRelease < epicsMutex > unguard ( guard );
560  this->callbackThreadActivityComplete.wait ( 30.0 );
561  }
562  this->noWakeupSincePend = true;
563  }
564 
565  double elapsed = epicsTime::getCurrent() - current;
566  double delay;
567 
568  if ( timeout > elapsed ) {
569  delay = timeout - elapsed;
570  }
571  else {
572  delay = 0.0;
573  }
574 
575  if ( delay >= CAC_SIGNIFICANT_DELAY ) {
576  if ( this->pCallbackGuard.get() ) {
577  epicsGuardRelease < epicsMutex > unguard ( *this->pCallbackGuard );
578  epicsThreadSleep ( delay );
579  }
580  else {
581  epicsThreadSleep ( delay );
582  }
583  }
584 
585  return ECA_TIMEOUT;
586 }
#define ECA_EVDISALLOW
Definition: caerr.h:103
void exception epicsGuard< epicsMutex > int status
Definition: oldAccess.h:311
double timeout
Definition: pvutils.cpp:25
int osiSocklen_t
Definition: osdSock.h:36
struct sockaddr sa
Definition: osiSock.h:158
LIBCOM_API void *epicsStdCall epicsThreadPrivateGet(epicsThreadPrivateId)
Definition: osdThread.c:973
epicsThreadPrivateId caClientCallbackThreadId
void flush(epicsGuard< epicsMutex > &)
LIBCOM_API void epicsStdCall epicsThreadSleep(double seconds)
Block the calling thread for at least the specified time.
Definition: osdThread.c:790
#define ECA_TIMEOUT
Definition: caerr.h:87
#define CAC_SIGNIFICANT_DELAY
Definition: iocinf.h:36
int ca_client_context::pendIO ( const double &  timeout)

Definition at line 468 of file ca_client_context.cpp.

469 {
470  // prevent recursion nightmares by disabling calls to
471  // pendIO () from within a CA callback.
473  return ECA_EVDISALLOW;
474  }
475 
476  int status = ECA_NORMAL;
477  epicsTime beg_time = epicsTime::getCurrent ();
478  double remaining = timeout;
479 
480  epicsGuard < epicsMutex > guard ( this->mutex );
481 
482  this->flush ( guard );
483 
484  while ( this->pndRecvCnt > 0 ) {
485  if ( remaining < CAC_SIGNIFICANT_DELAY ) {
486  status = ECA_TIMEOUT;
487  break;
488  }
489 
490  {
491  epicsGuardRelease < epicsMutex > unguard ( guard );
492  this->blockForEventAndEnableCallbacks ( this->ioDone, remaining );
493  }
494 
495  double delay = epicsTime::getCurrent () - beg_time;
496  if ( delay < timeout ) {
497  remaining = timeout - delay;
498  }
499  else {
500  remaining = 0.0;
501  }
502  }
503 
504  this->ioSeqNo++;
505  this->pndRecvCnt = 0u;
506 
507  return status;
508 }
#define ECA_EVDISALLOW
Definition: caerr.h:103
void exception epicsGuard< epicsMutex > int status
Definition: oldAccess.h:311
double timeout
Definition: pvutils.cpp:25
LIBCOM_API void *epicsStdCall epicsThreadPrivateGet(epicsThreadPrivateId)
Definition: osdThread.c:973
epicsThreadPrivateId caClientCallbackThreadId
#define ECA_NORMAL
Definition: caerr.h:77
void flush(epicsGuard< epicsMutex > &)
#define ECA_TIMEOUT
Definition: caerr.h:87
#define CAC_SIGNIFICANT_DELAY
Definition: iocinf.h:36
void blockForEventAndEnableCallbacks(epicsEvent &event, const double &timeout)
bool ca_client_context::preemptiveCallbakIsEnabled ( ) const
inline

Definition at line 556 of file oldAccess.h.

557 {
558  return this->pCallbackGuard.get () == 0;
559 }
int ca_client_context::printFormated ( const char *  pformat,
  ... 
) const

Definition at line 257 of file ca_client_context.cpp.

259 {
260  va_list theArgs;
261  int status;
262 
263  va_start ( theArgs, pformat );
264 
265  status = this->ca_client_context :: varArgsPrintFormated ( pformat, theArgs );
266 
267  va_end ( theArgs );
268 
269  return status;
270 }
void exception epicsGuard< epicsMutex > int status
Definition: oldAccess.h:311
int varArgsPrintFormated(const char *pformat, va_list args) const
void ca_client_context::registerForFileDescriptorCallBack ( CAFDHANDLER pFunc,
void *  pArg 
)

Definition at line 242 of file ca_client_context.cpp.

244 {
245  epicsGuard < epicsMutex > guard ( this->mutex );
246  this->fdRegFunc = pFunc;
247  this->fdRegArg = pArg;
248  this->fdRegFuncNeedsToBeCalled = true;
249  if ( pFunc ) {
250  // the receive thread might already be blocking
251  // w/o having sent the wakeup message
252  this->_sendWakeupMsg ();
253  }
254 // should block here until releated callback in progress completes
255 }
void ca_client_context::replaceErrLogHandler ( caPrintfFunc ca_printf_func)

Definition at line 229 of file ca_client_context.cpp.

231 {
232  epicsGuard < epicsMutex > guard ( this->mutex );
233  if ( ca_printf_func ) {
234  this->pVPrintfFunc = ca_printf_func;
235  }
236  else {
237  this->pVPrintfFunc = epicsVprintf;
238  }
239 // should block here until releated callback in progress completes
240 }
#define epicsVprintf
Definition: errlog.h:52
void ca_client_context::selfTest ( ) const

Definition at line 708 of file ca_client_context.cpp.

709 {
710  epicsGuard < epicsMutex > guard ( this->mutex );
711  this->sgTable.verify ();
712  this->pServiceContext->selfTest ( guard );
713 }
void verify() const
Definition: resourceLib.h:432
unsigned ca_client_context::sequenceNumberOfOutstandingIO ( epicsGuard< epicsMutex > &  ) const
inline

Definition at line 566 of file oldAccess.h.

568 {
569  // perhaps on SMP systems THERE should be lock/unlock around this
570  return this->ioSeqNo;
571 }
void ca_client_context::show ( unsigned  level) const

Definition at line 410 of file ca_client_context.cpp.

411 {
412  epicsGuard < epicsMutex > guard ( this->mutex );
413 
414  ::printf ( "ca_client_context at %p pndRecvCnt=%u ioSeqNo=%u\n",
415  static_cast <const void *> ( this ),
416  this->pndRecvCnt, this->ioSeqNo );
417 
418  if ( level > 0u ) {
419  this->pServiceContext->show ( guard, level - 1u );
420  ::printf ( "\tpreemptive callback is %s\n",
421  this->pCallbackGuard.get() ? "disabled" : "enabled" );
422  ::printf ( "\tthere are %u unsatisfied IO operations blocking ca_pend_io()\n",
423  this->pndRecvCnt );
424  ::printf ( "\tthe current io sequence number is %u\n",
425  this->ioSeqNo );
426  ::printf ( "IO done event:\n");
427  this->ioDone.show ( level - 1u );
428  ::printf ( "Synchronous group identifier hash table:\n" );
429  this->sgTable.show ( level - 1u );
430  }
431 }
#define printf
Definition: epicsStdio.h:41
void show(unsigned level) const
Definition: resourceLib.h:371
void ca_client_context::signal ( int  ca_status,
const char *  pfilenm,
int  lineno,
const char *  pFormat,
  ... 
)

Definition at line 351 of file ca_client_context.cpp.

353 {
354  va_list theArgs;
355  va_start ( theArgs, pFormat );
356  this->vSignal ( ca_status, pfilenm, lineno, pFormat, theArgs);
357  va_end ( theArgs );
358 }
int lineno
Definition: antelope.c:33
void vSignal(int ca_status, const char *pfilenm, int lineno, const char *pFormat, va_list args)
void ca_client_context::uninstallCASG ( epicsGuard< epicsMutex > &  guard,
CASG sg 
)

Definition at line 688 of file ca_client_context.cpp.

690 {
691  guard.assertIdenticalMutex ( this->mutex );
692  this->sgTable.remove ( sg );
693 }
void assertIdenticalMutex(const T &) const
Definition: epicsGuard.h:80
T * remove(const ID &idIn)
Definition: resourceLib.h:297
int ca_client_context::varArgsPrintFormated ( const char *  pformat,
va_list  args 
) const
virtual

Implements cacContextNotify.

Definition at line 272 of file ca_client_context.cpp.

274 {
275  caPrintfFunc * pFunc;
276  {
277  epicsGuard < epicsMutex > guard ( this->mutex );
278  pFunc = this->pVPrintfFunc;
279  }
280  if ( pFunc ) {
281  return ( *pFunc ) ( pformat, args );
282  }
283  else {
284  return :: vfprintf ( stderr, pformat, args );
285  }
286 }
int caPrintfFunc(const char *pformat, va_list args)
Definition: cadef.h:821
#define stderr
Definition: epicsStdio.h:32
void ca_client_context::vSignal ( int  ca_status,
const char *  pfilenm,
int  lineno,
const char *  pFormat,
va_list  args 
)

Definition at line 360 of file ca_client_context.cpp.

363 {
364  static const char *severity[] =
365  {
366  "Warning",
367  "Success",
368  "Error",
369  "Info",
370  "Fatal",
371  "Fatal",
372  "Fatal",
373  "Fatal"
374  };
375 
376  this->printFormated ( "CA.Client.Exception...............................................\n" );
377 
378  this->printFormated ( " %s: \"%s\"\n",
379  severity[ CA_EXTRACT_SEVERITY ( ca_status ) ],
380  ca_message ( ca_status ) );
381 
382  if ( pFormat ) {
383  this->printFormated ( " Context: \"" );
384  this->varArgsPrintFormated ( pFormat, args );
385  this->printFormated ( "\"\n" );
386  }
387 
388  if ( pfilenm ) {
389  this->printFormated ( " Source File: %s line %d\n",
390  pfilenm, lineno );
391  }
392 
393  epicsTime current = epicsTime::getCurrent ();
394  char date[64];
395  current.strftime ( date, sizeof ( date ), "%a %b %d %Y %H:%M:%S.%f");
396  this->printFormated ( " Current Time: %s\n", date );
397 
398  /*
399  * Terminate execution if unsuccessful
400  */
401  if( ! ( ca_status & CA_M_SUCCESS ) &&
402  CA_EXTRACT_SEVERITY ( ca_status ) != CA_K_WARNING ){
403  errlogFlush ();
404  abort ();
405  }
406 
407  this->printFormated ( "..................................................................\n" );
408 }
void errlogFlush(void)
Definition: errlog.c:529
#define CA_M_SUCCESS
Definition: caerr.h:41
int lineno
Definition: antelope.c:33
int printFormated(const char *pformat,...) const
#define CA_K_WARNING
Definition: caerr.h:34
int varArgsPrintFormated(const char *pformat, va_list args) const
void date(const char *format)
const char *epicsStdCall ca_message(long ca_status)
Definition: access.cpp:561
#define CA_EXTRACT_SEVERITY(code)
Definition: caerr.h:56
template<class T >
void ca_client_context::whenThereIsAnExceptionDestroySyncGroupIO ( epicsGuard< epicsMutex > &  guard,
T &  io 
)

Definition at line 574 of file oldAccess.h.

576 {
577  if ( this->pCallbackGuard.get() &&
578  this->createdByThread == epicsThreadGetIdSelf () ) {
579  io.destroy ( *this->pCallbackGuard.get(), guard );
580  }
581  else {
582  // dont reverse the lock hierarchy
583  epicsGuardRelease < epicsMutex > guardRelease ( guard );
584  {
585  //
586  // we will definately stall out here if all of the
587  // following are true
588  //
589  // o user creates non-preemtive mode client library context
590  // o user doesnt periodically call a ca function
591  // o user calls this function from an auxiillary thread
592  //
593  CallbackGuard cbGuard ( this->cbMutex );
594  epicsGuard < epicsMutex > guard ( this->mutex );
595  io.destroy ( cbGuard, guard );
596  }
597  }
598 }
LIBCOM_API epicsThreadId epicsStdCall epicsThreadGetIdSelf(void)
Definition: osdThread.c:810

Friends And Related Function Documentation

int epicsStdCall ca_array_get ( chtype  type,
arrayElementCount  count,
chid  pChan,
void *  pValue 
)
friend

Definition at line 267 of file oldChannelNotify.cpp.

269 {
270  int caStatus;
271  try {
272  if ( type < 0 ) {
273  return ECA_BADTYPE;
274  }
275  if ( count == 0 )
276  return ECA_BADCOUNT;
277 
278  unsigned tmpType = static_cast < unsigned > ( type );
279  epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );
280  pChan->eliminateExcessiveSendBacklog ( guard );
282  ( pChan->getClientCtx().getCopyFreeList,
283  new ( pChan->getClientCtx().getCopyFreeList )
284  getCopy ( guard, pChan->getClientCtx(), *pChan,
285  tmpType, count, pValue ) );
286  pChan->io.read ( guard, type, count, *pNotify, 0 );
287  pNotify.release ();
288  caStatus = ECA_NORMAL;
289  }
290  catch ( cacChannel::badString & )
291  {
292  caStatus = ECA_BADSTR;
293  }
294  catch ( cacChannel::badType & )
295  {
296  caStatus = ECA_BADTYPE;
297  }
298  catch ( cacChannel::outOfBounds & )
299  {
300  caStatus = ECA_BADCOUNT;
301  }
302  catch ( cacChannel::noReadAccess & )
303  {
304  caStatus = ECA_NORDACCESS;
305  }
306  catch ( cacChannel::notConnected & )
307  {
308  caStatus = ECA_DISCONN;
309  }
311  {
312  caStatus = ECA_UNAVAILINSERV;
313  }
314  catch ( cacChannel::requestTimedOut & )
315  {
316  caStatus = ECA_TIMEOUT;
317  }
318  catch ( std::bad_alloc & )
319  {
320  caStatus = ECA_ALLOCMEM;
321  }
323  caStatus = ECA_TOLARGE;
324  }
325  catch ( ... )
326  {
327  caStatus = ECA_GETFAIL;
328  }
329  return caStatus;
330 }
void exception epicsGuard< epicsMutex > int const char const char unsigned oldChannelNotify unsigned type
Definition: oldAccess.h:314
void exception epicsGuard< epicsMutex > int const char const char unsigned oldChannelNotify unsigned arrayElementCount count
Definition: oldAccess.h:314
#define ECA_GETFAIL
Definition: caerr.h:96
ca_client_context & getClientCtx()
Definition: oldAccess.h:428
#define ECA_BADCOUNT
Definition: caerr.h:99
epicsMutex & mutexRef() const
#define ECA_DISCONN
Definition: caerr.h:101
virtual ioStatus read(epicsGuard< epicsMutex > &, unsigned type, arrayElementCount count, cacReadNotify &, ioid *=0)=0
#define ECA_NORMAL
Definition: caerr.h:77
#define ECA_TOLARGE
Definition: caerr.h:86
#define ECA_NORDACCESS
Definition: caerr.h:123
#define ECA_BADSTR
Definition: caerr.h:100
#define ECA_TIMEOUT
Definition: caerr.h:87
#define ECA_BADTYPE
Definition: caerr.h:91
void eliminateExcessiveSendBacklog(epicsGuard< epicsMutex > &)
Definition: oldAccess.h:468
#define ECA_UNAVAILINSERV
Definition: caerr.h:131
#define ECA_ALLOCMEM
Definition: caerr.h:83
int epicsStdCall ca_array_get_callback ( chtype  type,
arrayElementCount  count,
chid  pChan,
caEventCallBackFunc pfunc,
void *  arg 
)
friend

Definition at line 335 of file oldChannelNotify.cpp.

338 {
339  int caStatus;
340  try {
341  if ( type < 0 ) {
342  return ECA_BADTYPE;
343  }
344  if ( pfunc == NULL ) {
345  return ECA_BADFUNCPTR;
346  }
347  unsigned tmpType = static_cast < unsigned > ( type );
348 
349  epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );
350  pChan->eliminateExcessiveSendBacklog ( guard );
352  ( pChan->getClientCtx().getCallbackFreeList,
353  new ( pChan->getClientCtx().getCallbackFreeList )
354  getCallback ( *pChan, pfunc, arg ) );
355  pChan->io.read ( guard, tmpType, count, *pNotify, 0 );
356  pNotify.release ();
357  caStatus = ECA_NORMAL;
358  }
359  catch ( cacChannel::badString & )
360  {
361  caStatus = ECA_BADSTR;
362  }
363  catch ( cacChannel::badType & )
364  {
365  caStatus = ECA_BADTYPE;
366  }
367  catch ( cacChannel::outOfBounds & )
368  {
369  caStatus = ECA_BADCOUNT;
370  }
371  catch ( cacChannel::noReadAccess & )
372  {
373  caStatus = ECA_NORDACCESS;
374  }
375  catch ( cacChannel::notConnected & )
376  {
377  caStatus = ECA_DISCONN;
378  }
380  {
381  caStatus = ECA_UNAVAILINSERV;
382  }
383  catch ( cacChannel::requestTimedOut & )
384  {
385  caStatus = ECA_TIMEOUT;
386  }
387  catch ( std::bad_alloc & )
388  {
389  caStatus = ECA_ALLOCMEM;
390  }
392  caStatus = ECA_TOLARGE;
393  }
394  catch ( ... )
395  {
396  caStatus = ECA_GETFAIL;
397  }
398  return caStatus;
399 }
void exception epicsGuard< epicsMutex > int const char const char unsigned oldChannelNotify unsigned type
Definition: oldAccess.h:314
#define ECA_BADFUNCPTR
Definition: caerr.h:129
void exception epicsGuard< epicsMutex > int const char const char unsigned oldChannelNotify unsigned arrayElementCount count
Definition: oldAccess.h:314
#define ECA_GETFAIL
Definition: caerr.h:96
ca_client_context & getClientCtx()
Definition: oldAccess.h:428
#define ECA_BADCOUNT
Definition: caerr.h:99
#define NULL
Definition: catime.c:38
epicsMutex & mutexRef() const
#define ECA_DISCONN
Definition: caerr.h:101
virtual ioStatus read(epicsGuard< epicsMutex > &, unsigned type, arrayElementCount count, cacReadNotify &, ioid *=0)=0
#define ECA_NORMAL
Definition: caerr.h:77
#define ECA_TOLARGE
Definition: caerr.h:86
#define ECA_NORDACCESS
Definition: caerr.h:123
#define ECA_BADSTR
Definition: caerr.h:100
#define ECA_TIMEOUT
Definition: caerr.h:87
#define ECA_BADTYPE
Definition: caerr.h:91
void eliminateExcessiveSendBacklog(epicsGuard< epicsMutex > &)
Definition: oldAccess.h:468
#define ECA_UNAVAILINSERV
Definition: caerr.h:131
#define ECA_ALLOCMEM
Definition: caerr.h:83
int epicsStdCall ca_array_put ( chtype  type,
arrayElementCount  count,
chid  pChan,
const void *  pValue 
)
friend

Definition at line 476 of file oldChannelNotify.cpp.

478 {
479  if ( type < 0 ) {
480  return ECA_BADTYPE;
481  }
482  unsigned tmpType = static_cast < unsigned > ( type );
483 
484  int caStatus;
485  try {
486  epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );
487  pChan->eliminateExcessiveSendBacklog ( guard );
488  pChan->io.write ( guard, tmpType, count, pValue );
489  caStatus = ECA_NORMAL;
490  }
491  catch ( cacChannel::badString & )
492  {
493  caStatus = ECA_BADSTR;
494  }
495  catch ( cacChannel::badType & )
496  {
497  caStatus = ECA_BADTYPE;
498  }
499  catch ( cacChannel::outOfBounds & )
500  {
501  caStatus = ECA_BADCOUNT;
502  }
503  catch ( cacChannel::noWriteAccess & )
504  {
505  caStatus = ECA_NOWTACCESS;
506  }
507  catch ( cacChannel::notConnected & )
508  {
509  caStatus = ECA_DISCONN;
510  }
512  {
513  caStatus = ECA_UNAVAILINSERV;
514  }
515  catch ( cacChannel::requestTimedOut & )
516  {
517  caStatus = ECA_TIMEOUT;
518  }
519  catch ( std::bad_alloc & )
520  {
521  caStatus = ECA_ALLOCMEM;
522  }
523  catch ( ... )
524  {
525  caStatus = ECA_PUTFAIL;
526  }
527  return caStatus;
528 }
void exception epicsGuard< epicsMutex > int const char const char unsigned oldChannelNotify unsigned type
Definition: oldAccess.h:314
void exception epicsGuard< epicsMutex > int const char const char unsigned oldChannelNotify unsigned arrayElementCount count
Definition: oldAccess.h:314
#define ECA_PUTFAIL
Definition: caerr.h:97
#define ECA_BADCOUNT
Definition: caerr.h:99
epicsMutex & mutexRef() const
#define ECA_DISCONN
Definition: caerr.h:101
#define ECA_NORMAL
Definition: caerr.h:77
virtual void write(epicsGuard< epicsMutex > &, unsigned type, arrayElementCount count, const void *pValue)=0
#define ECA_NOWTACCESS
Definition: caerr.h:124
#define ECA_BADSTR
Definition: caerr.h:100
#define ECA_TIMEOUT
Definition: caerr.h:87
#define ECA_BADTYPE
Definition: caerr.h:91
void eliminateExcessiveSendBacklog(epicsGuard< epicsMutex > &)
Definition: oldAccess.h:468
#define ECA_UNAVAILINSERV
Definition: caerr.h:131
#define ECA_ALLOCMEM
Definition: caerr.h:83
int epicsStdCall ca_array_put_callback ( chtype  type,
arrayElementCount  count,
chid  pChan,
const void *  pValue,
caEventCallBackFunc pfunc,
void *  usrarg 
)
friend

Definition at line 412 of file oldChannelNotify.cpp.

414 {
415  int caStatus;
416  try {
417  if ( type < 0 ) {
418  return ECA_BADTYPE;
419  }
420  if ( pfunc == NULL ) {
421  return ECA_BADFUNCPTR;
422  }
423  epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );
424  pChan->eliminateExcessiveSendBacklog ( guard );
425  unsigned tmpType = static_cast < unsigned > ( type );
427  ( pChan->getClientCtx().putCallbackFreeList,
428  new ( pChan->getClientCtx().putCallbackFreeList )
429  putCallback ( *pChan, pfunc, usrarg ) );
430  pChan->io.write ( guard, tmpType, count, pValue, *pNotify, 0 );
431  pNotify.release ();
432  caStatus = ECA_NORMAL;
433  }
434  catch ( cacChannel::badString & )
435  {
436  caStatus = ECA_BADSTR;
437  }
438  catch ( cacChannel::badType & )
439  {
440  caStatus = ECA_BADTYPE;
441  }
442  catch ( cacChannel::outOfBounds & )
443  {
444  caStatus = ECA_BADCOUNT;
445  }
446  catch ( cacChannel::noWriteAccess & )
447  {
448  caStatus = ECA_NOWTACCESS;
449  }
450  catch ( cacChannel::notConnected & )
451  {
452  caStatus = ECA_DISCONN;
453  }
455  {
456  caStatus = ECA_UNAVAILINSERV;
457  }
458  catch ( cacChannel::requestTimedOut & )
459  {
460  caStatus = ECA_TIMEOUT;
461  }
462  catch ( std::bad_alloc & )
463  {
464  caStatus = ECA_ALLOCMEM;
465  }
466  catch ( ... )
467  {
468  caStatus = ECA_PUTFAIL;
469  }
470  return caStatus;
471 }
void exception epicsGuard< epicsMutex > int const char const char unsigned oldChannelNotify unsigned type
Definition: oldAccess.h:314
#define ECA_BADFUNCPTR
Definition: caerr.h:129
void exception epicsGuard< epicsMutex > int const char const char unsigned oldChannelNotify unsigned arrayElementCount count
Definition: oldAccess.h:314
ca_client_context & getClientCtx()
Definition: oldAccess.h:428
#define ECA_PUTFAIL
Definition: caerr.h:97
#define ECA_BADCOUNT
Definition: caerr.h:99
#define NULL
Definition: catime.c:38
epicsMutex & mutexRef() const
#define ECA_DISCONN
Definition: caerr.h:101
#define ECA_NORMAL
Definition: caerr.h:77
virtual void write(epicsGuard< epicsMutex > &, unsigned type, arrayElementCount count, const void *pValue)=0
#define ECA_NOWTACCESS
Definition: caerr.h:124
#define ECA_BADSTR
Definition: caerr.h:100
#define ECA_TIMEOUT
Definition: caerr.h:87
#define ECA_BADTYPE
Definition: caerr.h:91
void eliminateExcessiveSendBacklog(epicsGuard< epicsMutex > &)
Definition: oldAccess.h:468
#define ECA_UNAVAILINSERV
Definition: caerr.h:131
#define ECA_ALLOCMEM
Definition: caerr.h:83
int epicsStdCall ca_clear_channel ( chid  pChan)
friend

Definition at line 363 of file access.cpp.

364 {
365  ca_client_context & cac = pChan->getClientCtx ();
366  {
367  epicsGuard < epicsMutex > guard ( cac.mutex );
368  try {
369  pChan->eliminateExcessiveSendBacklog ( guard );
370  }
371  catch ( cacChannel::notConnected & ) {
372  // intentionally ignored
373  }
374  }
375  if ( cac.pCallbackGuard.get() &&
376  cac.createdByThread == epicsThreadGetIdSelf () ) {
377  epicsGuard < epicsMutex > guard ( cac.mutex );
378  pChan->destructor ( *cac.pCallbackGuard.get(), guard );
379  cac.oldChannelNotifyFreeList.release ( pChan );
380  }
381  else {
382  //
383  // we will definately stall out here if all of the
384  // following are true
385  //
386  // o user creates non-preemtive mode client library context
387  // o user doesnt periodically call a ca function
388  // o user calls this function from an auxiillary thread
389  //
390  CallbackGuard cbGuard ( cac.cbMutex );
391  epicsGuard < epicsMutex > guard ( cac.mutex );
392  pChan->destructor ( *cac.pCallbackGuard.get(), guard );
393  cac.oldChannelNotifyFreeList.release ( pChan );
394  }
395  return ECA_NORMAL;
396 }
Definition: cac.h:97
ca_client_context & getClientCtx()
Definition: oldAccess.h:428
void destructor(CallbackGuard &cbGuard, epicsGuard< epicsMutex > &mutexGuard)
#define ECA_NORMAL
Definition: caerr.h:77
void release(void *p)
Definition: tsFreeList.h:176
void eliminateExcessiveSendBacklog(epicsGuard< epicsMutex > &)
Definition: oldAccess.h:468
LIBCOM_API epicsThreadId epicsStdCall epicsThreadGetIdSelf(void)
Definition: osdThread.c:810
int epicsStdCall ca_clear_subscription ( evid  pMon)
friend

Definition at line 743 of file ca_client_context.cpp.

744 {
745  oldChannelNotify & chan = pMon->channel ();
746  ca_client_context & cac = chan.getClientCtx ();
747  // !!!! the order in which we take the mutex here prevents deadlocks
748  {
749  epicsGuard < epicsMutex > guard ( cac.mutex );
750  try {
751  // if this stalls out on a live circuit then an exception
752  // can be forthcoming which we must ignore as the clear
753  // request must always be successful
754  chan.eliminateExcessiveSendBacklog ( guard );
755  }
756  catch ( cacChannel::notConnected & ) {
757  // intentionally ignored
758  }
759  }
760  if ( cac.pCallbackGuard.get() &&
761  cac.createdByThread == epicsThreadGetIdSelf () ) {
762  epicsGuard < epicsMutex > guard ( cac.mutex );
763  pMon->cancel ( *cac.pCallbackGuard.get(), guard );
764  }
765  else {
766  //
767  // we will definately stall out here if all of the
768  // following are true
769  //
770  // o user creates non-preemtive mode client library context
771  // o user doesnt periodically call a ca function
772  // o user calls this function from an auxiillary thread
773  //
774  CallbackGuard cbGuard ( cac.cbMutex );
775  epicsGuard < epicsMutex > guard ( cac.mutex );
776  pMon->cancel ( cbGuard, guard );
777  }
778  return ECA_NORMAL;
779 }
Definition: cac.h:97
ca_client_context & getClientCtx()
Definition: oldAccess.h:428
#define ECA_NORMAL
Definition: caerr.h:77
void cancel(CallbackGuard &callbackGuard, epicsGuard< epicsMutex > &mutualExclusionGuard)
Definition: oldAccess.h:502
oldChannelNotify & channel() const
Definition: oldAccess.h:509
void eliminateExcessiveSendBacklog(epicsGuard< epicsMutex > &)
Definition: oldAccess.h:468
void exception epicsGuard< epicsMutex > int const char const char unsigned oldChannelNotify & chan
Definition: oldAccess.h:314
LIBCOM_API epicsThreadId epicsStdCall epicsThreadGetIdSelf(void)
Definition: osdThread.c:810
int epicsStdCall ca_create_channel ( const char *  name_str,
caCh conn_func,
void *  puser,
capri  priority,
chid chanptr 
)
friend

Definition at line 288 of file access.cpp.

291 {
292  ca_client_context * pcac;
293  int caStatus = fetchClientContext ( & pcac );
294  if ( caStatus != ECA_NORMAL ) {
295  return caStatus;
296  }
297 
298  {
299  CAFDHANDLER * pFunc = 0;
300  void * pArg = 0;
301  {
303  guard ( pcac->mutex );
304  if ( pcac->fdRegFuncNeedsToBeCalled ) {
305  pFunc = pcac->fdRegFunc;
306  pArg = pcac->fdRegArg;
307  pcac->fdRegFuncNeedsToBeCalled = false;
308  }
309  }
310  if ( pFunc ) {
311  ( *pFunc ) ( pArg, pcac->sock, true );
312  }
313  }
314 
315  try {
316  epicsGuard < epicsMutex > guard ( pcac->mutex );
317  oldChannelNotify * pChanNotify =
318  new ( pcac->oldChannelNotifyFreeList )
319  oldChannelNotify ( guard, *pcac, name_str,
320  conn_func, puser, priority );
321  // make sure that their chan pointer is set prior to
322  // calling connection call backs
323  *chanptr = pChanNotify;
324  pChanNotify->initiateConnect ( guard );
325  // no need to worry about a connect preempting here because
326  // the connect sequence will not start untill initiateConnect()
327  // is called
328  }
329  catch ( cacChannel::badString & ) {
330  return ECA_BADSTR;
331  }
332  catch ( std::bad_alloc & ) {
333  return ECA_ALLOCMEM;
334  }
335  catch ( cacChannel::badPriority & ) {
336  return ECA_BADPRIORITY;
337  }
339  return ECA_UNAVAILINSERV;
340  }
341  catch ( std :: exception & except ) {
342  pcac->printFormated (
343  "ca_create_channel: "
344  "unexpected exception was \"%s\"",
345  except.what () );
346  return ECA_INTERNAL;
347  }
348  catch ( ... ) {
349  return ECA_INTERNAL;
350  }
351 
352  return ECA_NORMAL;
353 }
#define true
Definition: flexdef.h:84
#define ECA_INTERNAL
Definition: caerr.h:94
int printFormated(const char *pformat,...) const
void CAFDHANDLER(void *parg, int fd, int opened)
Definition: cadef.h:657
#define ECA_NORMAL
Definition: caerr.h:77
#define ECA_BADPRIORITY
Definition: caerr.h:133
void initiateConnect(epicsGuard< epicsMutex > &)
Definition: oldAccess.h:447
int fetchClientContext(ca_client_context **ppcac)
Definition: access.cpp:137
#define ECA_BADSTR
Definition: caerr.h:100
#define ECA_UNAVAILINSERV
Definition: caerr.h:131
#define ECA_ALLOCMEM
Definition: caerr.h:83
int epicsStdCall ca_create_subscription ( chtype  type,
arrayElementCount  count,
chid  pChan,
long  mask,
caEventCallBackFunc pCallBack,
void *  pCallBackArg,
evid monixptr 
)
friend

Definition at line 530 of file oldChannelNotify.cpp.

534 {
535  if ( type < 0 ) {
536  return ECA_BADTYPE;
537  }
538  unsigned tmpType = static_cast < unsigned > ( type );
539 
540  if ( INVALID_DB_REQ (type) ) {
541  return ECA_BADTYPE;
542  }
543 
544  if ( pCallBack == NULL ) {
545  return ECA_BADFUNCPTR;
546  }
547 
548  static const long maskMask = 0xffff;
549  if ( ( mask & maskMask ) == 0) {
550  return ECA_BADMASK;
551  }
552 
553  if ( mask & ~maskMask ) {
554  return ECA_BADMASK;
555  }
556 
557  try {
558  epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );
559  try {
560  // if this stalls out on a live circuit then an exception
561  // can be forthcoming which we must ignore (this is a
562  // special case preserving legacy ca_create_subscription
563  // behavior)
564  pChan->eliminateExcessiveSendBacklog ( guard );
565  }
566  catch ( cacChannel::notConnected & ) {
567  // intentionally ignored (its ok to subscribe when not connected)
568  }
569  new ( pChan->getClientCtx().subscriptionFreeList )
571  guard, *pChan, pChan->io, tmpType, count, mask,
572  pCallBack, pCallBackArg, monixptr );
573  // dont touch object created after above new because
574  // the first callback might have canceled, and therefore
575  // destroyed, it
576  return ECA_NORMAL;
577  }
578  catch ( cacChannel::badType & )
579  {
580  return ECA_BADTYPE;
581  }
582  catch ( cacChannel::outOfBounds & )
583  {
584  return ECA_BADCOUNT;
585  }
587  {
588  return ECA_BADMASK;
589  }
590  catch ( cacChannel::noReadAccess & )
591  {
592  return ECA_NORDACCESS;
593  }
595  {
596  return ECA_UNAVAILINSERV;
597  }
598  catch ( std::bad_alloc & )
599  {
600  return ECA_ALLOCMEM;
601  }
603  return ECA_TOLARGE;
604  }
605  catch ( ... )
606  {
607  return ECA_INTERNAL;
608  }
609 }
void exception epicsGuard< epicsMutex > int const char const char unsigned oldChannelNotify unsigned type
Definition: oldAccess.h:314
#define ECA_BADFUNCPTR
Definition: caerr.h:129
#define ECA_INTERNAL
Definition: caerr.h:94
void exception epicsGuard< epicsMutex > int const char const char unsigned oldChannelNotify unsigned arrayElementCount count
Definition: oldAccess.h:314
ca_client_context & getClientCtx()
Definition: oldAccess.h:428
#define ECA_BADCOUNT
Definition: caerr.h:99
#define INVALID_DB_REQ(x)
Definition: db_access.h:115
#define NULL
Definition: catime.c:38
epicsMutex & mutexRef() const
#define ECA_NORMAL
Definition: caerr.h:77
#define ECA_TOLARGE
Definition: caerr.h:86
#define ECA_NORDACCESS
Definition: caerr.h:123
#define ECA_BADMASK
Definition: caerr.h:118
#define ECA_BADTYPE
Definition: caerr.h:91
void eliminateExcessiveSendBacklog(epicsGuard< epicsMutex > &)
Definition: oldAccess.h:468
#define ECA_UNAVAILINSERV
Definition: caerr.h:131
#define ECA_ALLOCMEM
Definition: caerr.h:83
int epicsStdCall ca_flush_io ( )
friend

Definition at line 509 of file access.cpp.

510 {
511  ca_client_context * pcac;
512  int caStatus = fetchClientContext (&pcac);
513  if ( caStatus != ECA_NORMAL ) {
514  return caStatus;
515  }
516 
517  epicsGuard < epicsMutex > guard ( pcac->mutex );
518  pcac->flush ( guard );
519 
520  return ECA_NORMAL;
521 }
#define ECA_NORMAL
Definition: caerr.h:77
int fetchClientContext(ca_client_context **ppcac)
Definition: access.cpp:137
void flush(epicsGuard< epicsMutex > &)
int epicsStdCall ca_sg_array_get ( const CA_SYNC_GID  gid,
chtype  type,
arrayElementCount  count,
chid  pChan,
void *  pValue 
)
friend

Definition at line 308 of file syncgrp.cpp.

310 {
311  ca_client_context *pcac;
312 
313  int caStatus = fetchClientContext ( &pcac );
314  if ( caStatus != ECA_NORMAL ) {
315  return caStatus;
316  }
317 
318  epicsGuard < epicsMutex > guard ( pcac->mutexRef() );
319  CASG * const pcasg = pcac->lookupCASG ( guard, gid );
320  if ( ! pcasg ) {
321  return ECA_BADSYNCGRP;
322  }
323 
324  try {
325  pcasg->get ( guard, pChan, type,
326  static_cast < unsigned > ( count ), pValue );
327  return ECA_NORMAL;
328  }
329  catch ( cacChannel::badString & )
330  {
331  return ECA_BADSTR;
332  }
333  catch ( cacChannel::badType & )
334  {
335  return ECA_BADTYPE;
336  }
337  catch ( cacChannel::outOfBounds & )
338  {
339  return ECA_BADCOUNT;
340  }
341  catch ( cacChannel::noReadAccess & )
342  {
343  return ECA_NORDACCESS;
344  }
345  catch ( cacChannel::notConnected & )
346  {
347  return ECA_DISCONN;
348  }
350  {
351  return ECA_UNAVAILINSERV;
352  }
353  catch ( std::bad_alloc & )
354  {
355  return ECA_ALLOCMEM;
356  }
357  catch ( ... )
358  {
359  return ECA_INTERNAL;
360  }
361 }
void exception epicsGuard< epicsMutex > int const char const char unsigned oldChannelNotify unsigned type
Definition: oldAccess.h:314
#define ECA_INTERNAL
Definition: caerr.h:94
void exception epicsGuard< epicsMutex > int const char const char unsigned oldChannelNotify unsigned arrayElementCount count
Definition: oldAccess.h:314
#define ECA_BADCOUNT
Definition: caerr.h:99
epicsMutex & mutexRef() const
#define ECA_DISCONN
Definition: caerr.h:101
#define ECA_NORMAL
Definition: caerr.h:77
int fetchClientContext(ca_client_context **ppcac)
Definition: access.cpp:137
#define ECA_BADSYNCGRP
Definition: caerr.h:121
#define ECA_NORDACCESS
Definition: caerr.h:123
CASG * lookupCASG(epicsGuard< epicsMutex > &, unsigned id)
#define ECA_BADSTR
Definition: caerr.h:100
#define ECA_BADTYPE
Definition: caerr.h:91
#define ECA_UNAVAILINSERV
Definition: caerr.h:131
#define ECA_ALLOCMEM
Definition: caerr.h:83
int epicsStdCall ca_sg_array_put ( const CA_SYNC_GID  gid,
chtype  type,
arrayElementCount  count,
chid  pChan,
const void *  pValue 
)
friend

Definition at line 246 of file syncgrp.cpp.

248 {
249  ca_client_context *pcac;
250 
251  int caStatus = fetchClientContext ( &pcac );
252  if ( caStatus != ECA_NORMAL ) {
253  return caStatus;
254  }
255 
256  epicsGuard < epicsMutex > guard ( pcac->mutexRef() );
257  CASG * const pcasg = pcac->lookupCASG ( guard, gid );
258  if ( ! pcasg ) {
259  return ECA_BADSYNCGRP;
260  }
261 
262  try {
263  pcasg->put ( guard, pChan, type,
264  static_cast < unsigned > ( count ), pValue );
265  return ECA_NORMAL;
266  }
267  catch ( cacChannel::badString & )
268  {
269  return ECA_BADSTR;
270  }
271  catch ( cacChannel::badType & )
272  {
273  return ECA_BADTYPE;
274  }
275  catch ( cacChannel::outOfBounds & )
276  {
277  return ECA_BADCOUNT;
278  }
279  catch ( cacChannel::noWriteAccess & )
280  {
281  return ECA_NOWTACCESS;
282  }
283  catch ( cacChannel::notConnected & )
284  {
285  return ECA_DISCONN;
286  }
288  {
289  return ECA_UNAVAILINSERV;
290  }
291  catch ( cacChannel::requestTimedOut & )
292  {
293  return ECA_TIMEOUT;
294  }
295  catch ( std::bad_alloc & )
296  {
297  return ECA_ALLOCMEM;
298  }
299  catch ( ... )
300  {
301  return ECA_INTERNAL;
302  }
303 }
void exception epicsGuard< epicsMutex > int const char const char unsigned oldChannelNotify unsigned type
Definition: oldAccess.h:314
#define ECA_INTERNAL
Definition: caerr.h:94
void exception epicsGuard< epicsMutex > int const char const char unsigned oldChannelNotify unsigned arrayElementCount count
Definition: oldAccess.h:314
#define ECA_BADCOUNT
Definition: caerr.h:99
epicsMutex & mutexRef() const
#define ECA_DISCONN
Definition: caerr.h:101
#define ECA_NORMAL
Definition: caerr.h:77
int fetchClientContext(ca_client_context **ppcac)
Definition: access.cpp:137
#define ECA_BADSYNCGRP
Definition: caerr.h:121
#define ECA_NOWTACCESS
Definition: caerr.h:124
CASG * lookupCASG(epicsGuard< epicsMutex > &, unsigned id)
#define ECA_BADSTR
Definition: caerr.h:100
#define ECA_TIMEOUT
Definition: caerr.h:87
#define ECA_BADTYPE
Definition: caerr.h:91
#define ECA_UNAVAILINSERV
Definition: caerr.h:131
#define ECA_ALLOCMEM
Definition: caerr.h:83
int epicsStdCall ca_sg_block ( const CA_SYNC_GID  gid,
ca_real  timeout 
)
friend

Definition at line 127 of file syncgrp.cpp.

129 {
130  ca_client_context *pcac;
131  int status = fetchClientContext ( &pcac );
132  if ( status == ECA_NORMAL ) {
133  CASG * pcasg;
134  {
135  epicsGuard < epicsMutex > guard ( pcac->mutex );
136  pcasg = pcac->lookupCASG ( guard, gid );
137  if ( pcasg ) {
138  status = pcasg->block (
139  pcac->pCallbackGuard.get (), guard, timeout );
140  }
141  else {
142  status = ECA_BADSYNCGRP;
143  }
144  }
145  if ( pcasg ) {
146  sync_group_reset ( *pcac, *pcasg );
147  }
148  }
149  return status;
150 }
void exception epicsGuard< epicsMutex > int status
Definition: oldAccess.h:311
double timeout
Definition: pvutils.cpp:25
friend void sync_group_reset(ca_client_context &client, CASG &sg)
Definition: syncgrp.cpp:96
#define ECA_NORMAL
Definition: caerr.h:77
int block(epicsGuard< epicsMutex > *pcbGuard, epicsGuard< epicsMutex > &guard, double timeout)
Definition: CASG.cpp:62
int fetchClientContext(ca_client_context **ppcac)
Definition: access.cpp:137
#define ECA_BADSYNCGRP
Definition: caerr.h:121
CASG * lookupCASG(epicsGuard< epicsMutex > &, unsigned id)
int epicsStdCall ca_sg_create ( CA_SYNC_GID pgid)
friend

Definition at line 24 of file syncgrp.cpp.

25 {
26  ca_client_context * pcac;
27  int caStatus;
28  CASG * pcasg;
29 
30  caStatus = fetchClientContext ( &pcac );
31  if ( caStatus != ECA_NORMAL ) {
32  return caStatus;
33  }
34 
35  try {
36  epicsGuard < epicsMutex > guard ( pcac->mutexRef() );
37  pcasg = new ( pcac->casgFreeList ) CASG ( guard, *pcac );
38  *pgid = pcasg->getId ();
39  return ECA_NORMAL;
40  }
41  catch ( std::bad_alloc & ) {
42  return ECA_ALLOCMEM;
43  }
44  catch ( ... ) {
45  return ECA_INTERNAL;
46  }
47 }
#define ECA_INTERNAL
Definition: caerr.h:94
epicsMutex & mutexRef() const
#define ECA_NORMAL
Definition: caerr.h:77
int fetchClientContext(ca_client_context **ppcac)
Definition: access.cpp:137
#define ECA_ALLOCMEM
Definition: caerr.h:83
int epicsStdCall ca_sg_delete ( const CA_SYNC_GID  gid)
friend

Definition at line 68 of file syncgrp.cpp.

69 {
70  ca_client_context * pcac;
71  int caStatus = fetchClientContext ( & pcac );
72  if ( caStatus == ECA_NORMAL ) {
73  if ( pcac->pCallbackGuard.get() &&
74  pcac->createdByThread == epicsThreadGetIdSelf () ) {
75  epicsGuard < epicsMutex > guard ( pcac->mutex );
76  caStatus = ca_sync_group_destroy ( *pcac->pCallbackGuard.get(),
77  guard, *pcac, gid );
78  }
79  else {
80  //
81  // we will definately stall out here if all of the
82  // following are true
83  //
84  // o user creates non-preemtive mode client library context
85  // o user doesnt periodically call a ca function
86  // o user calls this function from an auxiillary thread
87  //
88  CallbackGuard cbGuard ( pcac->cbMutex );
89  epicsGuard < epicsMutex > guard ( pcac->mutex );
90  caStatus = ca_sync_group_destroy ( cbGuard, guard, *pcac, gid );
91  }
92  }
93  return caStatus;
94 }
#define ECA_NORMAL
Definition: caerr.h:77
int fetchClientContext(ca_client_context **ppcac)
Definition: access.cpp:137
friend int ca_sync_group_destroy(CallbackGuard &cbGuard, epicsGuard< epicsMutex > &guard, ca_client_context &cac, const CA_SYNC_GID gid)
Definition: syncgrp.cpp:49
LIBCOM_API epicsThreadId epicsStdCall epicsThreadGetIdSelf(void)
Definition: osdThread.c:810
int epicsStdCall ca_sg_reset ( const CA_SYNC_GID  gid)
friend

Definition at line 155 of file syncgrp.cpp.

156 {
157  ca_client_context *pcac;
158  int caStatus = fetchClientContext (&pcac);
159  if ( caStatus == ECA_NORMAL ) {
160  CASG * pcasg;
161  {
162  epicsGuard < epicsMutex > guard ( pcac->mutex );
163  pcasg = pcac->lookupCASG ( guard, gid );
164  }
165  if ( pcasg ) {
166  sync_group_reset ( *pcac, *pcasg );
167  caStatus = ECA_NORMAL;
168  }
169  else {
170  caStatus = ECA_BADSYNCGRP;
171  }
172  }
173  return caStatus;
174 }
friend void sync_group_reset(ca_client_context &client, CASG &sg)
Definition: syncgrp.cpp:96
#define ECA_NORMAL
Definition: caerr.h:77
int fetchClientContext(ca_client_context **ppcac)
Definition: access.cpp:137
#define ECA_BADSYNCGRP
Definition: caerr.h:121
CASG * lookupCASG(epicsGuard< epicsMutex > &, unsigned id)
int epicsStdCall ca_sg_test ( const CA_SYNC_GID  gid)
friend

Definition at line 202 of file syncgrp.cpp.

203 {
204  ca_client_context * pcac;
205  int caStatus = fetchClientContext ( &pcac );
206  if ( caStatus == ECA_NORMAL ) {
207  epicsGuard < epicsMutex > guard ( pcac->mutexRef() );
208  CASG * pcasg = pcac->lookupCASG ( guard, gid );
209  if ( pcasg ) {
210  bool isComplete;
211  if ( pcac->pCallbackGuard.get() &&
212  pcac->createdByThread == epicsThreadGetIdSelf () ) {
213  epicsGuard < epicsMutex > guard ( pcac->mutex );
214  isComplete = pcasg->ioComplete ( *pcac->pCallbackGuard.get(), guard );
215  }
216  else {
217  //
218  // we will definately stall out here if all of the
219  // following are true
220  //
221  // o user creates non-preemtive mode client library context
222  // o user doesnt periodically call a ca function
223  // o user calls this function from an auxiillary thread
224  //
225  CallbackGuard cbGuard ( pcac->cbMutex );
226  epicsGuard < epicsMutex > guard ( pcac->mutex );
227  isComplete = pcasg->ioComplete ( cbGuard, guard );
228  }
229  if ( isComplete ) {
230  caStatus = ECA_IODONE;
231  }
232  else{
233  caStatus = ECA_IOINPROGRESS;
234  }
235  }
236  else {
237  caStatus = ECA_BADSYNCGRP;
238  }
239  }
240  return caStatus;
241 }
#define ECA_IOINPROGRESS
Definition: caerr.h:120
#define ECA_IODONE
Definition: caerr.h:119
epicsMutex & mutexRef() const
#define ECA_NORMAL
Definition: caerr.h:77
int fetchClientContext(ca_client_context **ppcac)
Definition: access.cpp:137
#define ECA_BADSYNCGRP
Definition: caerr.h:121
CASG * lookupCASG(epicsGuard< epicsMutex > &, unsigned id)
LIBCOM_API epicsThreadId epicsStdCall epicsThreadGetIdSelf(void)
Definition: osdThread.c:810
int ca_sync_group_destroy ( CallbackGuard cbGuard,
epicsGuard< epicsMutex > &  guard,
ca_client_context cac,
const CA_SYNC_GID  gid 
)
friend

Definition at line 49 of file syncgrp.cpp.

51 {
52  int caStatus;
53  CASG * pcasg = cac.lookupCASG ( guard, gid );
54  if ( pcasg ) {
55  pcasg->destructor ( cbGuard, guard );
56  cac.casgFreeList.release ( pcasg );
57  caStatus = ECA_NORMAL;
58  }
59  else {
60  caStatus = ECA_BADSYNCGRP;
61  }
62  return caStatus;
63 }
void destructor(CallbackGuard &, epicsGuard< epicsMutex > &guard)
Definition: CASG.cpp:37
#define ECA_NORMAL
Definition: caerr.h:77
#define ECA_BADSYNCGRP
Definition: caerr.h:121
CASG * lookupCASG(epicsGuard< epicsMutex > &, unsigned id)
void release(void *p)
Definition: tsFreeList.h:176
void cacOnceFunc ( void *  )
friend

Definition at line 48 of file ca_client_context.cpp.

49 {
52  ca_client_context::pDefaultServiceInstallMutex = newEpicsMutex;
53 }
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
epicsThreadPrivateId caClientCallbackThreadId
LIBCOM_API epicsThreadPrivateId epicsStdCall epicsThreadPrivateCreate(void)
Definition: osdThread.c:934
void sync_group_reset ( ca_client_context client,
CASG sg 
)
friend

Definition at line 96 of file syncgrp.cpp.

97 {
98  if ( client.pCallbackGuard.get() &&
99  client.createdByThread == epicsThreadGetIdSelf () ) {
100  epicsGuard < epicsMutex > guard ( client.mutex );
101  sg.reset ( *client.pCallbackGuard.get(), guard );
102  }
103  else {
104  //
105  // we will definately stall out here if all of the
106  // following are true
107  //
108  // o user creates non-preemtive mode client library context
109  // o user doesnt periodically call a ca function
110  // o user calls this function from an auxiillary thread
111  //
112  CallbackGuard cbGuard ( client.cbMutex );
113  epicsGuard < epicsMutex > guard ( client.mutex );
114  sg.reset ( cbGuard, guard );
115  }
116 }
void reset(CallbackGuard &, epicsGuard< epicsMutex > &)
Definition: CASG.cpp:131
LIBCOM_API epicsThreadId epicsStdCall epicsThreadGetIdSelf(void)
Definition: osdThread.c:810

Member Data Documentation

void exception epicsGuard< epicsMutex > int const char const char unsigned oldChannelNotify& ca_client_context::chan

Definition at line 314 of file oldAccess.h.

void exception epicsGuard< epicsMutex > int const char const char unsigned oldChannelNotify unsigned arrayElementCount ca_client_context::count

Definition at line 314 of file oldAccess.h.

void exception epicsGuard< epicsMutex > int const char const char unsigned ca_client_context::lineNo

Definition at line 311 of file oldAccess.h.

void exception epicsGuard< epicsMutex > int const char const char unsigned oldChannelNotify unsigned arrayElementCount unsigned ca_client_context::op

Definition at line 314 of file oldAccess.h.

void exception epicsGuard< epicsMutex > int const char * ca_client_context::pContext

Definition at line 311 of file oldAccess.h.

void exception epicsGuard< epicsMutex > int const char const char * ca_client_context::pFileName

Definition at line 311 of file oldAccess.h.

void exception epicsGuard< epicsMutex > int ca_client_context::status

Definition at line 311 of file oldAccess.h.

void exception epicsGuard< epicsMutex > int const char const char unsigned oldChannelNotify unsigned ca_client_context::type

Definition at line 314 of file oldAccess.h.


The documentation for this struct was generated from the following files: