diff --git a/src/ca/access.cpp b/src/ca/access.cpp index 14f741a9e..9586b4a01 100644 --- a/src/ca/access.cpp +++ b/src/ca/access.cpp @@ -375,7 +375,7 @@ int epicsShareAPI ca_add_masked_array_event ( chtype type, unsigned long count, return ECA_TOLARGE; } - pSubsr = new oldSubscription (*pChan, pCallBack, pCallBackArg ); + pSubsr = new oldSubscription ( *pChan, pCallBack, pCallBackArg ); if ( ! pSubsr ) { return ECA_ALLOCMEM; } @@ -786,41 +786,6 @@ unsigned epicsShareAPI ca_get_ioc_connection_count () return pcac->connectionCount (); } -void netiiu::show ( unsigned /* level */ ) const -{ - this->pcas->lock (); - - tsDLIterConstBD pChan ( this->chidList.first () ); - while ( pChan.valid () ) { - char hostName [256]; - printf( "%s native type=%d ", - pChan->pName (), pChan->nativeType () ); - pChan->hostName ( hostName, sizeof (hostName) ); - printf( "N elements=%lu server=%s state=", - pChan->nativeElementCount (), hostName ); - switch ( pChan->state () ) { - case cs_never_conn: - printf ("never connected to an IOC"); - break; - case cs_prev_conn: - printf ("disconnected from IOC"); - break; - case cs_conn: - printf ("connected to an IOC"); - break; - case cs_closed: - printf ("invalid channel"); - break; - default: - break; - } - printf("\n"); - } - - this->pcas->unlock (); - -} - epicsShareFunc int epicsShareAPI ca_channel_status (threadId /* tid */) { cac *pcac; @@ -893,7 +858,7 @@ extern epicsShareDef const int epicsTypeToDBR_XXXX [lastEpicsType+1] = { DBR_STRING }; -extern epicsShareDef READONLY epicsType DBR_XXXXToEpicsType [LAST_BUFFER_TYPE+1] = { +extern epicsShareDef const epicsType DBR_XXXXToEpicsType [LAST_BUFFER_TYPE+1] = { epicsOldStringT, epicsInt16T, epicsFloat32T, diff --git a/src/ca/bhe_IL.h b/src/ca/bhe_IL.h index 96805a473..510fe4a10 100644 --- a/src/ca/bhe_IL.h +++ b/src/ca/bhe_IL.h @@ -57,10 +57,10 @@ inline tcpiiu *bhe::getIIU ()const return this->piiu; } -inline void bhe::bindToIIU (tcpiiu *piiuIn) +inline void bhe::bindToIIU ( tcpiiu &iiuIn ) { assert ( this->piiu == 0 ); - this->piiu = piiuIn; + this->piiu = &iiuIn; } inline void bhe::destroy () diff --git a/src/ca/cac.cpp b/src/ca/cac.cpp index da77d3e99..94c050f38 100644 --- a/src/ca/cac.cpp +++ b/src/ca/cac.cpp @@ -13,8 +13,11 @@ #include "osiProcess.h" #include "osiSigPipeIgnore.h" #include "iocinf.h" + #include "inetAddrID_IL.h" #include "bhe_IL.h" +#include "tcpiiu_IL.h" +#include "nciu_IL.h" extern "C" void cacRecursionLockExitHandler () { @@ -53,7 +56,7 @@ cac::cac ( bool enablePreemptiveCallbackIn ) : static threadOnceId once = OSITHREAD_ONCE_INIT; unsigned abovePriority; - threadOnce ( &once, cacInitRecursionLock, 0); + threadOnce ( &once, cacInitRecursionLock, 0 ); if ( cacInitRecursionLock == 0 ) { throwWithLocation ( caErrorCode (ECA_ALLOCMEM) ); @@ -78,24 +81,14 @@ cac::cac ( bool enablePreemptiveCallbackIn ) : throwWithLocation ( caErrorCode (ECA_ALLOCMEM) ); } - ellInit (&this->ca_taskVarList); ellInit (&this->putCvrtBuf); - ellInit (&this->fdInfoFreeList); - ellInit (&this->fdInfoList); this->ca_printf_func = errlogVprintf; this->ca_exception_func = ca_default_exception_handler; this->ca_exception_arg = NULL; - this->ca_number_iiu_in_fc = 0u; this->readSeq = 0u; - this->ca_io_done_sem = semBinaryCreate(semEmpty); - if (!this->ca_io_done_sem) { - throwWithLocation ( caErrorCode (ECA_ALLOCMEM) ); - } - this->ca_blockSem = semBinaryCreate(semEmpty); if (!this->ca_blockSem) { - semBinaryDestroy (this->ca_io_done_sem); throwWithLocation ( caErrorCode (ECA_ALLOCMEM) ); } @@ -113,7 +106,6 @@ cac::cac ( bool enablePreemptiveCallbackIn ) : len = strlen (tmp) + 1; this->ca_pUserName = (char *) malloc ( len ); if ( ! this->ca_pUserName ) { - semBinaryDestroy (this->ca_io_done_sem); semBinaryDestroy (this->ca_blockSem); throwWithLocation ( caErrorCode (ECA_ALLOCMEM) ); } @@ -221,10 +213,6 @@ cac::~cac () /* reclaim sync group resources */ this->sgTable.destroyAllEntries (); - /* free select context lists */ - ellFree ( &this->fdInfoFreeList ); - ellFree ( &this->fdInfoList ); - /* * free user name string */ @@ -234,7 +222,6 @@ cac::~cac () this->beaconTable.destroyAllEntries (); - semBinaryDestroy ( this->ca_io_done_sem ); semBinaryDestroy ( this->ca_blockSem ); osiSockRelease (); @@ -428,6 +415,19 @@ void cac::signalRecvActivityIIU (tcpiiu &iiu) void cac::removeIIU (tcpiiu &iiu) { + this->defaultMutex.lock (); + osiSockAddr addr = iiu.address (); + if ( addr.sa.sa_family == AF_INET ) { + bhe *pBHE = this->lookupBeaconInetAddr ( addr.ia ); + if ( pBHE ) { + pBHE->destroy (); + } + } + else { + errlogPrintf ( "CA server didnt have inet type address?\n" ); + } + this->defaultMutex.unlock (); + this->iiuListMutex.lock (); if ( iiu.recvPending ) { @@ -449,7 +449,6 @@ void cac::removeIIU (tcpiiu &iiu) /* * cac::lookupBeaconInetAddr() - * */ bhe * cac::lookupBeaconInetAddr (const inetAddrID &ina) { @@ -607,7 +606,7 @@ void cac::decrementOutstandingIO (unsigned seqNumber) } this->defaultMutex.unlock (); if ( this->pndrecvcnt == 0u ) { - semBinaryGive (this->ca_io_done_sem); + this->ioDone.signal (); } } @@ -619,7 +618,7 @@ void cac::decrementOutstandingIO () } this->defaultMutex.unlock (); if ( this->pndrecvcnt == 0u ) { - semBinaryGive (this->ca_io_done_sem); + this->ioDone.signal (); } } @@ -711,7 +710,7 @@ int cac::pendPrivate (double timeout, int early) } } - semBinaryTakeTimeout ( this->ca_io_done_sem, remaining ); + this->ioDone.wait ( remaining ); if ( this->pndrecvcnt == 0 && early ) { return ECA_NORMAL; diff --git a/src/ca/iocinf.h b/src/ca/iocinf.h index e9ad2772b..00174bd88 100644 --- a/src/ca/iocinf.h +++ b/src/ca/iocinf.h @@ -426,7 +426,7 @@ public: void addToChanList ( nciu &chan ); void removeFromChanList ( nciu &chan ); void disconnect ( nciu &chan ); - int recvMsg (); + void recvMsg (); int post_msg (const struct sockaddr_in *pnet_addr, char *pInBuf, unsigned long blockSize); int pushStreamMsg ( const caHdr *pmsg, const void *pext, bool BlockingOk ); @@ -526,7 +526,7 @@ public: void recvMsg (); void flush (); virtual void show (unsigned level) const; - osiSockAddr ipAddress () const; + osiSockAddr address () const; SOCKET getSock () const; void noopRequestMsg (); @@ -589,7 +589,7 @@ class bhe : public tsSLNode , public inetAddrID { public: bhe (class cac &cacIn, const osiTime &initialTimeStamp, const inetAddrID &addr); tcpiiu *getIIU () const; - void bindToIIU (tcpiiu *); + void bindToIIU ( tcpiiu & ); void destroy (); bool updateBeaconPeriod (osiTime programBeginTime); @@ -765,8 +765,6 @@ public: osiTimerQueue *pTimerQueue; ELLLIST activeCASGOP; ELLLIST putCvrtBuf; - ELLLIST fdInfoFreeList; - ELLLIST fdInfoList; osiTime programBeginTime; ca_real ca_connectTMO; caExceptionHandler *ca_exception_func; @@ -776,20 +774,18 @@ public: resTable < bhe, inetAddrID > beaconTable; tsDLIterBD endOfBCastList; - semBinaryId ca_io_done_sem; osiEvent recvActivity; semBinaryId ca_blockSem; unsigned readSeq; unsigned ca_nextSlowBucketId; - unsigned ca_number_iiu_in_fc; unsigned short ca_server_port; char ca_new_err_code_msg_buf[128u]; - ELLLIST ca_taskVarList; private: cacServiceList services; osiMutex defaultMutex; osiMutex iiuListMutex; + osiEvent ioDone; tsDLList iiuListIdle; tsDLList iiuListRecvPending; tsDLList @@ -838,82 +834,6 @@ int fetchClientContext (cac **ppcac); extern "C" void caRepeaterThread (void *pDummy); extern "C" void ca_default_exception_handler (struct exception_handler_args args); -// -// nciu inline member functions -// - -inline void * nciu::operator new (size_t size) -{ - return nciu::freeList.allocate (size); -} - -inline void nciu::operator delete (void *pCadaver, size_t size) -{ - nciu::freeList.release (pCadaver,size); -} - -inline bool nciu::fullyConstructed () const -{ - return this->f_fullyConstructed; -} - -// -// netSubscription inline member functions -// -inline void * netSubscription::operator new (size_t size) -{ - return netSubscription::freeList.allocate (size); -} - -inline void netSubscription::operator delete (void *pCadaver, size_t size) -{ - netSubscription::freeList.release (pCadaver,size); -} - -// -// netReadNotifyIO inline member functions -// -inline void * netReadNotifyIO::operator new (size_t size) -{ - return netReadNotifyIO::freeList.allocate (size); -} - -inline void netReadNotifyIO::operator delete (void *pCadaver, size_t size) -{ - netReadNotifyIO::freeList.release (pCadaver,size); -} - -// -// netWriteNotifyIO inline member functions -// -inline void * netWriteNotifyIO::operator new (size_t size) -{ - return netWriteNotifyIO::freeList.allocate (size); -} - -inline void netWriteNotifyIO::operator delete (void *pCadaver, size_t size) -{ - netWriteNotifyIO::freeList.release (pCadaver,size); -} - -// -// tcpiiu inline functions -// -inline void * tcpiiu::operator new (size_t size) -{ - return tcpiiu::freeList.allocate (size); -} - -inline void tcpiiu::operator delete (void *pCadaver, size_t size) -{ - tcpiiu::freeList.release (pCadaver,size); -} - -inline bool tcpiiu::fullyConstructed () const -{ - return this->fc; -} - /* * !!KLUDGE!! * diff --git a/src/ca/nciu.cpp b/src/ca/nciu.cpp index 6ddb421cb..37bd413d0 100644 --- a/src/ca/nciu.cpp +++ b/src/ca/nciu.cpp @@ -12,6 +12,11 @@ #include "iocinf.h" +#include "nciu_IL.h" +#include "netReadNotifyIO_IL.h" +#include "netWriteNotifyIO_IL.h" +#include "netSubscription_IL.h" + tsFreeList < class nciu, 1024 > nciu::freeList; struct putCvrtBuf { diff --git a/src/ca/netReadNotifyIO.cpp b/src/ca/netReadNotifyIO.cpp index 079324287..d6635c1c3 100644 --- a/src/ca/netReadNotifyIO.cpp +++ b/src/ca/netReadNotifyIO.cpp @@ -11,6 +11,7 @@ */ #include "iocinf.h" +#include "netReadNotifyIO_IL.h" tsFreeList < class netReadNotifyIO, 1024 > netReadNotifyIO::freeList; diff --git a/src/ca/netSubscription.cpp b/src/ca/netSubscription.cpp index 38a4d8cf6..4b6295f38 100644 --- a/src/ca/netSubscription.cpp +++ b/src/ca/netSubscription.cpp @@ -11,6 +11,7 @@ */ #include "iocinf.h" +#include "netSubscription_IL.h" tsFreeList < class netSubscription, 1024 > netSubscription::freeList; diff --git a/src/ca/netWriteNotifyIO.cpp b/src/ca/netWriteNotifyIO.cpp index 463f65de6..1f2b80493 100644 --- a/src/ca/netWriteNotifyIO.cpp +++ b/src/ca/netWriteNotifyIO.cpp @@ -11,6 +11,7 @@ */ #include "iocinf.h" +#include "netWriteNotifyIO_IL.h" tsFreeList < class netWriteNotifyIO, 1024 > netWriteNotifyIO::freeList; diff --git a/src/ca/netiiu.cpp b/src/ca/netiiu.cpp index 38f2f666d..9fe4945a9 100644 --- a/src/ca/netiiu.cpp +++ b/src/ca/netiiu.cpp @@ -27,4 +27,39 @@ netiiu::~netiiu () { } +void netiiu::show ( unsigned /* level */ ) const +{ + this->pcas->lock (); + + tsDLIterConstBD pChan ( this->chidList.first () ); + while ( pChan.valid () ) { + char hostName [256]; + printf( "%s native type=%d ", + pChan->pName (), pChan->nativeType () ); + pChan->hostName ( hostName, sizeof (hostName) ); + printf( "N elements=%lu server=%s state=", + pChan->nativeElementCount (), hostName ); + switch ( pChan->state () ) { + case cs_never_conn: + printf ("never connected to an IOC"); + break; + case cs_prev_conn: + printf ("disconnected from IOC"); + break; + case cs_conn: + printf ("connected to an IOC"); + break; + case cs_closed: + printf ("invalid channel"); + break; + default: + break; + } + printf("\n"); + } + + this->pcas->unlock (); + +} + diff --git a/src/ca/tcpiiu.cpp b/src/ca/tcpiiu.cpp index 5e1890e7d..eb6425bd2 100644 --- a/src/ca/tcpiiu.cpp +++ b/src/ca/tcpiiu.cpp @@ -12,8 +12,10 @@ */ #include "iocinf.h" + #include "inetAddrID_IL.h" #include "bhe_IL.h" +#include "tcpiiu_IL.h" const caHdr cacnullmsg = { 0,0,0,0,0,0 @@ -508,8 +510,8 @@ tcpiiu::tcpiiu (cac *pcac, const struct sockaddr_in &ina, unsigned minorVersion, } } - bhe.bindToIIU (this); - pcac->installIIU (*this); + bhe.bindToIIU ( *this ); + pcac->installIIU ( *this ); this->fc = true; } @@ -575,8 +577,6 @@ tcpiiu::~tcpiiu () this->pcas->removeIIU ( *this ); - this->pcas->removeBeaconInetAddr ( this->dest.ia ); - socket_close (this->sock); cacRingBufferDestroy (&this->recv); @@ -610,13 +610,6 @@ bool tcpiiu::compareIfTCP ( nciu &chan, const sockaddr_in &addr ) const return true; } -void tcpiiu::flush () -{ - if ( cacRingBufferWriteFlush ( &this->send ) ) { - this->armSendWatchdog (); - } -} - void tcpiiu::show ( unsigned /* level */ ) const { } @@ -1317,30 +1310,6 @@ int tcpiiu::post_msg (char *pInBuf, unsigned long blockSize) return ECA_NORMAL; } -void tcpiiu::hostName ( char *pBuf, unsigned bufLength ) const -{ - if ( bufLength ) { - strncpy ( pBuf, this->host_name_str, bufLength ); - pBuf[bufLength - 1u] = '\0'; - } -} - -// deprecated - please dont use -const char * tcpiiu::pHostName () const -{ - return this->host_name_str; -} - -bool tcpiiu::ca_v42_ok () const -{ - return CA_V42 (CA_PROTOCOL_VERSION, this->minor_version_number); -} - -bool tcpiiu::ca_v41_ok () const -{ - return CA_V41 (CA_PROTOCOL_VERSION, this->minor_version_number); -} - /* * tcpiiu::pushStreamMsg () */ @@ -1470,11 +1439,6 @@ void tcpiiu::disconnect ( nciu &chan ) this->pcas->unlock (); } -SOCKET tcpiiu::getSock () const -{ - return this->sock; -} - /* * FLOW CONTROL * @@ -1497,8 +1461,6 @@ void tcpiiu::flowControlOn () if ( ! this->client_busy ) { status = this->busyRequestMsg (); if ( status == ECA_NORMAL ) { - assert ( this->pcas->ca_number_iiu_in_fc < UINT_MAX ); - this->pcas->ca_number_iiu_in_fc++; this->client_busy = TRUE; # if defined(DEBUG) printf("fc on\n"); @@ -1523,8 +1485,6 @@ void tcpiiu::flowControlOff () if ( this->client_busy ) { status = this->readyRequestMsg (); if ( status == ECA_NORMAL ) { - assert ( this->pcas->ca_number_iiu_in_fc > 0u ); - this->pcas->ca_number_iiu_in_fc--; this->client_busy = FALSE; # if defined (DEBUG) printf("fc off\n"); diff --git a/src/ca/udpiiu.cpp b/src/ca/udpiiu.cpp index 1b7e6693e..bd845b97b 100644 --- a/src/ca/udpiiu.cpp +++ b/src/ca/udpiiu.cpp @@ -21,7 +21,7 @@ typedef void (*pProtoStubUDP) (udpiiu *piiu, caHdr *pMsg, const struct sockaddr_ // // udpiiu::recvMsg () // -int udpiiu::recvMsg () +void udpiiu::recvMsg () { osiSockAddr src; int src_size = sizeof (src); @@ -29,25 +29,25 @@ int udpiiu::recvMsg () status = recvfrom ( this->sock, this->recvBuf, sizeof ( this->recvBuf ), 0, &src.sa, &src_size ); - if (status < 0) { + if ( status <= 0 ) { + + if ( status == 0 ) { + return; + } + int errnoCpy = SOCKERRNO; if ( errnoCpy == SOCK_SHUTDOWN ) { - return -1; + return; } if ( errnoCpy == SOCK_ENOTSOCK ) { - return -1; + return; } if ( errnoCpy == SOCK_EBADF ) { - return -1; + return; } if ( errnoCpy == SOCK_EINTR ) { - if ( this->shutdownCmd ) { - return -1; - } - else { - return 0; - } + return; } # ifdef linux /* @@ -55,11 +55,11 @@ int udpiiu::recvMsg () * in linux */ if ( errnoCpy == SOCK_ECONNREFUSED ) { - return 0; + return; } # endif - ca_printf ( - "Unexpected UDP recv error %s\n", SOCKERRSTR(errnoCpy)); + ca_printf ( "Unexpected UDP recv error was \"%s\"\n", + SOCKERRSTR (errnoCpy) ); } else if (status > 0) { status = this->post_msg ( &src.ia, @@ -72,12 +72,11 @@ int udpiiu::recvMsg () ca_printf ( "%s: bad UDP msg from %s because \"%s\"\n", __FILE__, buf, ca_message (status) ); - - return 0; + return; } } - return 0; + return; } /* @@ -86,13 +85,12 @@ int udpiiu::recvMsg () extern "C" void cacRecvThreadUDP (void *pParam) { udpiiu *piiu = (udpiiu *) pParam; - int status; do { - status = piiu->recvMsg (); - } while ( status == 0 ); + piiu->recvMsg (); + } while ( ! piiu->shutdownCmd ); - semBinaryGive (piiu->recvThreadExitSignal); + semBinaryGive ( piiu->recvThreadExitSignal ); } /* @@ -425,21 +423,11 @@ void udpiiu::shutdown () if ( ! this->shutdownCmd ) { int status; + // this knocks the UDP input thread out of recv () this->shutdownCmd = true; - // - // use of shutdown () for this purpose on UDP - // sockets does not work on certain OS (i.e. solaris) - // because the thread in recv() does not drop out of recv(). - // On other OS (i.e. linux) shutdown() is required? - // - status = ::shutdown ( this->sock, SD_BOTH ); - if ( status ) { - errlogPrintf ( "CAC UDP socket shutdown error was %s\n", - SOCKERRSTR (SOCKERRNO) ); - } status = socket_close ( this->sock ); if ( status ) { - errlogPrintf ( "CAC UDP socket close error was %s\n", + errlogPrintf ( "CAC UDP socket close error was \"%s\"\n", SOCKERRSTR (SOCKERRNO) ); } }