Files
epics-base/src/ca/netiiu.cpp
2001-03-08 21:29:04 +00:00

266 lines
5.7 KiB
C++

/* $Id$
*
* L O S A L A M O S
* Los Alamos National Laboratory
* Los Alamos, New Mexico 87545
*
* Copyright, 1986, The Regents of the University of California.
*
* Author: Jeff Hill
*/
#include <limits.h>
#include <float.h>
#include "iocinf.h"
#include "netiiu_IL.h"
#include "nciu_IL.h"
#include "baseNMIU_IL.h"
netiiu::netiiu ( cac *pClientCtxIn ) : pClientCtx ( pClientCtxIn )
{
}
netiiu::~netiiu ()
{
}
void netiiu::show ( unsigned level ) const
{
epicsAutoMutex autoMutex ( this->mutex );
printf ( "network IO base class\n" );
if ( level > 1 ) {
tsDLIterConstBD < nciu > pChan = this->channelList.firstIter ();
while ( pChan.valid () ) {
pChan->show ( level - 1u );
pChan++;
}
}
if ( level > 2u ) {
printf ( "\tcac pointer %p\n",
static_cast <void *> ( this->pClientCtx ) );
this->mutex.show ( level - 2u );
}
}
// cac lock must also be applied when
// calling this
void netiiu::attachChannel ( nciu &chan )
{
epicsAutoMutex autoMutex ( this->mutex );
this->channelList.add ( chan );
}
// cac lock must also be applied when
// calling this
void netiiu::detachChannel ( nciu &chan )
{
epicsAutoMutex autoMutex ( this->mutex );
this->channelList.remove ( chan );
if ( this->channelList.count () == 0u ) {
this->lastChannelDetachNotify ();
}
}
// cac lock must also be applied when
// calling this
void netiiu::disconnectAllChan ( netiiu & newiiu )
{
tsDLList < nciu > list;
{
epicsAutoMutex autoMutex ( this->mutex );
tsDLIterBD < nciu > chan = this->channelList.firstIter ();
while ( chan.valid () ) {
tsDLIterBD < nciu > next = chan;
next++;
this->clearChannelRequest ( *chan );
this->channelList.remove ( *chan );
chan->disconnect ( newiiu );
list.add ( *chan );
chan = next;
}
}
{
epicsAutoMutex autoMutex ( newiiu.mutex );
newiiu.channelList.add ( list );
}
}
//
// netiiu::destroyAllIO ()
//
// care is taken to not hold the lock while deleting the
// IO so that subscription delete request (sent by the
// IO's destructor) do not deadlock
//
bool netiiu::destroyAllIO ( nciu &chan )
{
tsDLList < baseNMIU > eventQ;
{
epicsAutoMutex autoMutex ( this->mutex );
if ( chan.verifyIIU ( *this ) ) {
eventQ.add ( chan.tcpiiuPrivateListOfIO::eventq );
}
else {
return false;
}
}
while ( baseNMIU *pIO = eventQ.get () ) {
delete pIO;
}
return true;
}
void netiiu::connectTimeoutNotify ()
{
epicsAutoMutex autoMutex ( this->mutex );
tsDLIterBD < nciu > chan = this->channelList.firstIter ();
while ( chan.valid () ) {
chan->connectTimeoutNotify ();
chan++;
}
}
void netiiu::resetChannelRetryCounts ()
{
epicsAutoMutex autoMutex ( this->mutex );
tsDLIterBD < nciu > chan = this->channelList.firstIter ();
while ( chan.valid () ) {
chan->resetRetryCount ();
chan++;
}
}
bool netiiu::searchMsg ( unsigned short retrySeqNumber, unsigned &retryNoForThisChannel )
{
bool success;
epicsAutoMutex autoMutex ( this->mutex );
if ( nciu *pChan = this->channelList.get () ) {
success = pChan->searchMsg ( retrySeqNumber, retryNoForThisChannel );
if ( success ) {
this->channelList.add ( *pChan );
}
else {
this->channelList.push ( *pChan );
}
}
else {
success = false;
}
return success;
}
bool netiiu::ca_v42_ok () const
{
return false;
}
bool netiiu::ca_v41_ok () const
{
return false;
}
bool netiiu::pushDatagramMsg ( const caHdr &, const void *, ca_uint16_t )
{
return false;
}
bool netiiu::isVirtaulCircuit ( const char *, const osiSockAddr & ) const
{
return false;
}
void netiiu::lastChannelDetachNotify ()
{
}
int netiiu::writeRequest ( nciu &, unsigned, unsigned, const void * )
{
return ECA_DISCONNCHID;
}
int netiiu::writeNotifyRequest ( nciu &, cacNotify &, unsigned, unsigned, const void * )
{
return ECA_DISCONNCHID;
}
int netiiu::readNotifyRequest ( nciu &, cacNotify &, unsigned, unsigned )
{
return ECA_DISCONNCHID;
}
int netiiu::createChannelRequest ( nciu & )
{
return ECA_DISCONNCHID;
}
int netiiu::clearChannelRequest ( nciu & )
{
return ECA_DISCONNCHID;
}
void netiiu::subscriptionRequest ( netSubscription &, bool )
{
}
void netiiu::subscriptionCancelRequest ( netSubscription &, bool )
{
}
void netiiu::installSubscription ( netSubscription &subscr )
{
bool connectedWhenInstalled;
{
epicsAutoMutex autoMutex ( this->mutex );
subscr.channel ().tcpiiuPrivateListOfIO::eventq.add ( subscr );
connectedWhenInstalled = subscr.channel ().connected ();
}
// iiu pointer briefly points at tcpiiu before the channel is connected
if ( connectedWhenInstalled ) {
this->subscriptionRequest ( subscr, true );
}
}
void netiiu::hostName ( char *pBuf, unsigned bufLength ) const
{
if ( bufLength ) {
strncpy ( pBuf, this->pHostName (), bufLength );
pBuf[bufLength - 1u] = '\0';
}
}
const char * netiiu::pHostName () const
{
return "<disconnected>";
}
void netiiu::disconnectAllIO ( nciu & )
{
}
void netiiu::connectAllIO ( nciu & )
{
}
bool netiiu::uninstallIO ( baseNMIU &io )
{
epicsAutoMutex autoMutex ( this->mutex );
if ( io.channel ().verifyIIU ( *this ) ) {
io.channel ().tcpiiuPrivateListOfIO::eventq.remove ( io );
return true;
}
return false;
}
double netiiu::beaconPeriod () const
{
return ( - DBL_MAX );
}