o changed UDP to non-blocking IO

o cleaned up (consolodated) UDP interface class structure
This commit is contained in:
Jeff Hill
1999-09-02 21:50:29 +00:00
parent 971e71c28d
commit 33d29a458d
66 changed files with 3771 additions and 4581 deletions
+9
View File
@@ -242,3 +242,12 @@ implemented ANSI STD C++ "bool" type.
o In class osiTimer type double, and not type osiTime, is returned from virtual member
function delay().
o The public const event mask member data in the caServer class were changed to member
functions in order to avoid problems on some compiler where const event masks cant be
created until the server is fully constructed. The constants have been replaced by the
following member functions.
casEventMask valueEventMask() const; // DBE_VALUE registerEvent("value")
casEventMask logEventMask() const; // DBE_LOG registerEvent("log")
casEventMask alarmEventMask() const; // DBE_ALARM registerEvent("alarm")
+4 -6
View File
@@ -27,13 +27,11 @@ LIBSRCS += casChannelI.cc
LIBSRCS += casPVListChan.cc
LIBSRCS += casClientMon.cc
LIBSRCS += casChanDelEv.cc
LIBSRCS += casAsyncIO.cc
LIBSRCS += casAsyncIOI.cc
LIBSRCS += casAsyncXXIO.cc
LIBSRCS += casAsyncRdIOI.cc
LIBSRCS += casAsyncWtIOI.cc
LIBSRCS += casAsyncExIOI.cc
LIBSRCS += casAsyncAtIOI.cc
LIBSRCS += casAsyncReadIO.cc
LIBSRCS += casAsyncWriteIO.cc
LIBSRCS += casAsyncPVExistIO.cc
LIBSRCS += casAsyncPVAttachIO.cc
LIBSRCS += casEventSys.cc
LIBSRCS += casMonitor.cc
LIBSRCS += casMonEvent.cc
+1 -1
View File
@@ -31,7 +31,7 @@ extern int main (int argc, const char **argv)
char pvPrefix[128] = "";
char fileName[128] = "pvDirectory.txt";
unsigned aliasCount = 0u;
aitBool forever = aitTrue;
bool forever = true;
int nPV;
int i;
+4 -4
View File
@@ -16,17 +16,17 @@ void exChannel::setOwner(const char * const /* pUserName */,
//
// exChannel::readAccess ()
//
aitBool exChannel::readAccess () const
bool exChannel::readAccess () const
{
return aitTrue;
return true;
}
//
// exChannel::writeAccess ()
//
aitBool exChannel::writeAccess () const
bool exChannel::writeAccess () const
{
return aitTrue;
return true;
}
+2 -2
View File
@@ -21,7 +21,7 @@ class exFixedStringDestructor: public gddDestructor {
//
// exPV::exPV()
//
exPV::exPV (pvInfo &setup, aitBool preCreateFlag, aitBool scanOnIn) :
exPV::exPV (pvInfo &setup, bool preCreateFlag, bool scanOnIn) :
info (setup),
interest (aitFalse),
preCreate (preCreateFlag),
@@ -95,7 +95,7 @@ caStatus exPV::update(gdd &valueIn)
// post a value change event
//
if (this->interest==aitTrue && pCAS!=NULL) {
casEventMask select(pCAS->valueEventMask|pCAS->logEventMask);
casEventMask select(pCAS->valueEventMask()|pCAS->logEventMask());
this->postEvent (select, *this->pValue);
}
+9 -7
View File
@@ -35,6 +35,9 @@ pvInfo exServer::pvList[] = {
pvInfo (2.0, "alan", 10.0f, -10.0f, excasIoSync, 100u),
pvInfo (20.0, "albert", 10.0f, -10.0f, excasIoSync, 1000u)
};
const unsigned exServer::pvListNElem = NELEMENTS (exServer::pvList);
//
// static on-the-fly PVs
//
@@ -44,17 +47,16 @@ pvInfo exServer::billy (2.0, "billy", 10.0f, -10.0f, excasIoAsync, 1u);
//
// exServer::exServer()
//
exServer::exServer(const char * const pvPrefix, unsigned aliasCount, aitBool scanOnIn) :
caServer (NELEMENTS(this->pvList)+2u),
stringResTbl (NELEMENTS(this->pvList)*(aliasCount+1u)+2u),
exServer::exServer(const char * const pvPrefix, unsigned aliasCount, bool scanOnIn) :
caServer (pvListNElem+2u),
stringResTbl (pvListNElem*(aliasCount+1u)+2u),
simultAsychIOCount (0u),
scanOn (scanOnIn)
{
unsigned i;
exPV *pPV;
pvInfo *pPVI;
pvInfo *pPVAfter =
&exServer::pvList[NELEMENTS(exServer::pvList)];
pvInfo *pPVAfter = &exServer::pvList[pvListNElem];
char pvAlias[256];
const char * const pNameFmtStr = "%.100s%.20s";
const char * const pAliasFmtStr = "%.100s%.20s%u";
@@ -240,13 +242,13 @@ pvAttachReturn exServer::pvAttach
//
// pvInfo::createPV()
//
exPV *pvInfo::createPV (exServer &, aitBool preCreateFlag, aitBool scanOn)
exPV *pvInfo::createPV (exServer &, bool preCreateFlag, bool scanOn)
{
if (this->pPV) {
return this->pPV;
}
exPV *pNewPV;
exPV *pNewPV;
//
// create an instance of the appropriate class
+19 -17
View File
@@ -87,7 +87,7 @@ public:
{ return this->elementCount; }
void unlinkPV() { this->pPV=NULL; }
exPV *createPV (exServer &exCAS, aitBool preCreateFlag, aitBool scanOn);
exPV *createPV (exServer &exCAS, bool preCreateFlag, bool scanOn);
void deletePV ();
private:
@@ -155,7 +155,7 @@ class exPV : public casPV, public tsSLNode<exPV> {
// allow the exScanTimer destructor to set dangling pScanTimer pointer to NULL
friend exScanTimer::~exScanTimer();
public:
exPV (pvInfo &setup, aitBool preCreateFlag, aitBool scanOn);
exPV (pvInfo &setup, bool preCreateFlag, bool scanOn);
virtual ~exPV();
void show(unsigned level) const;
@@ -241,12 +241,12 @@ public:
const char * const pUserName, const char * const pHostName);
protected:
smartGDDPointer pValue;
exScanTimer *pScanTimer;
pvInfo & info;
aitBool interest;
aitBool preCreate;
aitBool scanOn;
smartGDDPointer pValue;
exScanTimer *pScanTimer;
pvInfo & info;
bool interest;
bool preCreate;
bool scanOn;
static osiTime currentTime;
virtual caStatus updateValue (gdd &value) = 0;
@@ -274,7 +274,7 @@ private:
//
class exScalarPV : public exPV {
public:
exScalarPV (pvInfo &setup, aitBool preCreateFlag, aitBool scanOnIn) :
exScalarPV (pvInfo &setup, bool preCreateFlag, bool scanOnIn) :
exPV (setup, preCreateFlag, scanOnIn) {}
void scan();
private:
@@ -286,7 +286,7 @@ private:
//
class exVectorPV : public exPV {
public:
exVectorPV (pvInfo &setup, aitBool preCreateFlag, aitBool scanOnIn) :
exVectorPV (pvInfo &setup, bool preCreateFlag, bool scanOnIn) :
exPV (setup, preCreateFlag, scanOnIn) {}
void scan();
@@ -302,7 +302,7 @@ private:
//
class exServer : public caServer {
public:
exServer(const char * const pvPrefix, unsigned aliasCount, aitBool scanOn);
exServer(const char * const pvPrefix, unsigned aliasCount, bool scanOn);
~exServer();
void show (unsigned level) const;
@@ -328,12 +328,14 @@ public:
private:
resTable<pvEntry,stringId> stringResTbl;
unsigned simultAsychIOCount;
aitBool scanOn;
bool scanOn;
//
// list of pre-created PVs
//
static pvInfo pvList[];
static const unsigned pvListNElem;
//
// on-the-fly PVs
@@ -350,7 +352,7 @@ public:
//
// exAsyncPV()
//
exAsyncPV (pvInfo &setup, aitBool preCreateFlag, aitBool scanOnIn) :
exAsyncPV (pvInfo &setup, bool preCreateFlag, bool scanOnIn) :
exScalarPV (setup, preCreateFlag, scanOnIn),
simultAsychIOCount(0u) {}
@@ -390,8 +392,8 @@ public:
virtual void setOwner(const char * const pUserName,
const char * const pHostName);
virtual aitBool readAccess () const;
virtual aitBool writeAccess () const;
virtual bool readAccess () const;
virtual bool writeAccess () const;
private:
};
@@ -535,7 +537,7 @@ public:
// exAsyncCreateIO()
//
exAsyncCreateIO(pvInfo &pviIn, exServer &casIn,
const casCtx &ctxIn, aitBool scanOnIn) :
const casCtx &ctxIn, bool scanOnIn) :
casAsyncPVAttachIO(ctxIn), exOSITimer(0.00001),
pvi(pviIn), cas(casIn), scanOn(scanOnIn) {}
@@ -555,7 +557,7 @@ public:
private:
pvInfo &pvi;
exServer &cas;
aitBool scanOn;
bool scanOn;
};
//
+19 -11
View File
@@ -8,15 +8,16 @@
//
extern int main (int argc, const char **argv)
{
osiTime begin(osiTime::getCurrent());
exServer *pCAS;
unsigned debugLevel = 0u;
double executionTime;
char pvPrefix[128] = "";
unsigned aliasCount = 1u;
unsigned scanOn = 1u;
aitBool forever = aitTrue;
int i;
osiTime begin (osiTime::getCurrent());
exServer *pCAS;
unsigned debugLevel = 0u;
double executionTime;
char pvPrefix[128] = "";
unsigned aliasCount = 1u;
unsigned scanOnAsUnsignedInt = true;
bool scanOn;
bool forever = aitTrue;
int i;
for (i=1; i<argc; i++) {
if (sscanf(argv[i], "-d\t%u", &debugLevel)==1) {
@@ -32,7 +33,7 @@ extern int main (int argc, const char **argv)
if (sscanf(argv[i],"-c %u", &aliasCount)==1) {
continue;
}
if (sscanf(argv[i],"-s %u", &scanOn)==1) {
if (sscanf(argv[i],"-s %u", &scanOnAsUnsignedInt)==1) {
continue;
}
printf ("\"%s\"?\n", argv[i]);
@@ -43,7 +44,14 @@ extern int main (int argc, const char **argv)
return (1);
}
pCAS = new exServer(pvPrefix, aliasCount, (aitBool) scanOn);
if (scanOnAsUnsignedInt) {
scanOn = true;
}
else {
scanOn = false;
}
pCAS = new exServer (pvPrefix, aliasCount, scanOn);
if (!pCAS) {
return (-1);
}
+73 -26
View File
@@ -16,6 +16,7 @@
#ifdef caNetAddrSock
#include "osiSock.h"
#include "bsdSocketResource.h"
#endif
#include "epicsAssert.h"
@@ -26,10 +27,10 @@ public:
inline void checkSize();
};
enum caNetAddrType {casnaUDF, casnaSock}; // only IP addresses (and undefined) supported at this time
class epicsShareClass caNetAddr {
friend class verifyCANetAddr;
public:
enum caNetAddrType {casnaUDF, casnaInet};
//
// clear()
@@ -47,11 +48,37 @@ public:
this->clear();
}
inline int isSock () const
inline bool isInet () const
{
return this->type == casnaSock;
return this->type == casnaInet;
}
inline bool isValid () const
{
return this->type != casnaUDF;
}
inline bool operator == (const caNetAddr &rhs) const
{
if (this->type != rhs.type) {
return false;
}
# ifdef caNetAddrSock
if (this->type==casnaInet) {
return (this->addr.ip.sin_addr.s_addr == rhs.addr.ip.sin_addr.s_addr) &&
(this->addr.ip.sin_port == rhs.addr.ip.sin_port);
}
# endif
else {
return false;
}
}
inline bool operator != (const caNetAddr &rhs) const
{
return ! this->operator == (rhs);
}
//
// This is specified so that compilers will not use one of
// the following assignment operators after converting to a
@@ -67,6 +94,11 @@ public:
return *this;
}
//
// convert to the string equivalent of the address
//
void stringConvert (char *pString, unsigned stringLength) const;
//
// conditionally drag BSD socket headers into the server
// and server tool
@@ -74,60 +106,59 @@ public:
// to use this #define caNetAddrSock
//
# ifdef caNetAddrSock
inline void setSockIP(unsigned long inaIn, unsigned short portIn)
inline void setSockIP (unsigned long inaIn, unsigned short portIn)
{
this->type = casnaSock;
this->addr.sock.sin_family = AF_INET;
this->addr.sock.sin_addr.s_addr = inaIn;
this->addr.sock.sin_port = portIn;
this->type = casnaInet;
this->addr.ip.sin_family = AF_INET;
this->addr.ip.sin_addr.s_addr = inaIn;
this->addr.ip.sin_port = portIn;
}
inline void setSockIP(const struct sockaddr_in &sockIPIn)
inline void setSockIP (const struct sockaddr_in &sockIPIn)
{
this->type = casnaSock;
assert(sockIPIn.sin_family == AF_INET);
this->addr.sock = sockIPIn;
this->type = casnaInet;
assert (sockIPIn.sin_family == AF_INET);
this->addr.ip = sockIPIn;
}
inline void setSock(const struct sockaddr &sock)
inline void setSock (const struct sockaddr &sock)
{
this->type = casnaSock;
assert (sock.sa_family == AF_INET);
this->type = casnaInet;
const struct sockaddr_in *psip =
(const struct sockaddr_in *) &sock;
assert(sizeof(sock)==sizeof(this->addr.sock));
this->addr.sock = *psip;
this->addr.ip = *psip;
}
inline caNetAddr(const struct sockaddr_in &sockIPIn)
inline caNetAddr (const struct sockaddr_in &sockIPIn)
{
this->setSockIP(sockIPIn);
this->setSockIP (sockIPIn);
}
inline caNetAddr operator = (const struct sockaddr_in &sockIPIn)
{
this->setSockIP(sockIPIn);
this->setSockIP (sockIPIn);
return *this;
}
inline caNetAddr operator = (const struct sockaddr &sockIn)
{
this->setSock(sockIn);
this->setSock (sockIn);
return *this;
}
inline struct sockaddr_in getSockIP() const
{
assert (this->type==casnaSock);
return this->addr.sock;
assert (this->type==casnaInet);
return this->addr.ip;
}
inline struct sockaddr getSock() const
{
struct sockaddr sa;
assert (this->type==casnaSock);
assert (sizeof(sa)==sizeof(this->addr.sock));
assert (this->type==casnaInet);
struct sockaddr_in *psain = (struct sockaddr_in *) &sa;
*psain = this->addr.sock;
*psain = this->addr.ip;
return sa;
}
@@ -147,7 +178,7 @@ public:
private:
union {
# ifdef caNetAddrSock
struct sockaddr_in sock;
struct sockaddr_in ip;
# endif
//
// this must be as big or bigger
@@ -174,5 +205,21 @@ inline void verifyCANetAddr::checkSize()
assert (ds==as);
}
//
// caNetAddr::stringConvert ()
//
inline void caNetAddr::stringConvert (char *pString, unsigned stringLength) const
{
# ifdef caNetAddrSock
if (this->type==casnaInet) {
ipAddrToA (&this->addr.ip, pString, stringLength);
return;
}
# endif
if (stringLength) {
strncpy (pString, "<Undefined Address>", stringLength);
pString[stringLength-1] = '\n';
}
}
#endif // caNetAddrH
+62 -72
View File
@@ -26,49 +26,6 @@
* Advanced Photon Source
* Argonne National Laboratory
*
*
<<<<<<< caServer.cc
=======
* History
* $Log$
* Revision 1.12 1999/08/07 00:55:35 jhill
* solaris compiler issues
*
* Revision 1.11 1999/08/04 23:05:29 jhill
* applied chronIntId name change
*
* Revision 1.10 1999/01/28 20:18:14 jhill
* removed implicit int
*
* Revision 1.9 1998/12/19 00:04:49 jhill
* renamed createPV() to pvAttach()
*
* Revision 1.8 1997/08/05 00:46:56 jhill
* fixed warnings
*
* Revision 1.7 1997/06/25 05:09:00 jhill
* removed templInst.cc
*
* Revision 1.6 1997/06/13 09:15:50 jhill
* connect proto changes
*
* Revision 1.5 1997/04/10 19:33:52 jhill
* API changes
*
* Revision 1.4 1996/11/02 00:53:53 jhill
* many improvements
*
* Revision 1.3 1996/09/16 18:23:56 jhill
* vxWorks port changes
*
* Revision 1.2 1996/06/21 02:30:52 jhill
* solaris port
*
* Revision 1.1.1.1 1996/06/20 00:28:14 jhill
* ca server installation
*
*
>>>>>>> 1.8
*/
#include "dbMapper.h" // ait to dbr types
@@ -96,29 +53,20 @@
//
// caServer::caServer()
//
epicsShareFunc caServer::caServer(unsigned pvCountEstimateIn) :
pCAS (new caServerI(*this, pvCountEstimateIn)),
valueEventMask(this->registerEvent("value")),
logEventMask(this->registerEvent("log")),
alarmEventMask(this->registerEvent("alarm"))
epicsShareFunc caServer::caServer (unsigned pvCountEstimateIn)
{
static int init;
static bool init = false;
if (!init) {
gddMakeMapDBR(gddApplicationTypeTable::app_table);
init = true;
}
if (!init) {
gddMakeMapDBR(gddApplicationTypeTable::app_table);
init = TRUE;
}
if (!this->pCAS) {
errMessage(S_cas_noMemory, NULL);
return;
}
if (!this->pCAS->ready()) {
delete this->pCAS;
this->pCAS = NULL;
return;
}
this->pCAS = new caServerI(*this, pvCountEstimateIn);
if (this->pCAS==NULL) {
errMessage (S_cas_noMemory, " - unable to create caServer");
throw S_cas_noMemory;
}
}
//
@@ -202,15 +150,57 @@ epicsShareFunc void caServer::setDebugLevel (unsigned level)
//
// caServer::getDebugLevel()
//
epicsShareFunc unsigned caServer::getDebugLevel ()
epicsShareFunc unsigned caServer::getDebugLevel () const
{
if (pCAS) {
return this->pCAS->getDebugLevel();
}
else {
printf("caServer:: no server internals attached\n");
return 0u;
}
if (pCAS) {
return this->pCAS->getDebugLevel();
}
else {
printf("caServer:: no server internals attached\n");
return 0u;
}
}
//
// caServer::valueEventMask ()
//
epicsShareFunc casEventMask caServer::valueEventMask () const
{
if (pCAS) {
return this->pCAS->valueEventMask();
}
else {
printf("caServer:: no server internals attached\n");
return casEventMask();
}
}
//
// caServer::logEventMask ()
//
epicsShareFunc casEventMask caServer::logEventMask () const
{
if (pCAS) {
return this->pCAS->logEventMask();
}
else {
printf("caServer:: no server internals attached\n");
return casEventMask();
}
}
//
// caServer::alarmEventMask ()
//
epicsShareFunc casEventMask caServer::alarmEventMask () const
{
if (pCAS) {
return this->pCAS->alarmEventMask();
}
else {
printf("caServer:: no server internals attached\n");
return casEventMask();
}
}
//
+134 -157
View File
@@ -45,77 +45,11 @@ static const double CAServerMaxBeaconPeriod = 15.0; // seconds
//
static const double CAServerMinBeaconPeriod = 1.0e-3; // seconds
//
// caServerI::show()
//
void caServerI::show (unsigned level) const
{
int bytes_reserved;
printf( "Channel Access Server Status V%d.%d\n",
CA_PROTOCOL_VERSION, CA_MINOR_VERSION);
this->osiMutex::show(level);
this->osiLock();
tsDLIterBD<casStrmClient> iterCl(this->clientList.first());
while ( iterCl!=tsDLIterBD<casStrmClient>::eol() ) {
iterCl->show(level);
++iterCl;
}
this->dgClient.show(level);
tsDLIterBD<casIntfOS> iterIF(this->intfList.first());
while ( iterIF!=tsDLIterBD<casIntfOS>::eol() ) {
iterIF->show(level);
++iterIF;
}
this->osiUnlock();
bytes_reserved = 0u;
#if 0
bytes_reserved += sizeof(casClient) *
ellCount(&this->freeClientQ);
bytes_reserved += sizeof(casChannel) *
ellCount(&this->freeChanQ);
bytes_reserved += sizeof(casEventBlock) *
ellCount(&this->freeEventQ);
bytes_reserved += sizeof(casAsyncIIO) *
ellCount(&this->freePendingIO);
#endif
if (level>=1) {
printf(
"There are currently %d bytes on the server's free list\n",
bytes_reserved);
#if 0
printf(
"%d client(s), %d channel(s), %d event(s) (monitors), and %d IO blocks\n",
ellCount(&this->freeClientQ),
ellCount(&this->freeChanQ),
ellCount(&this->freeEventQ),
ellCount(&this->freePendingIO));
#endif
printf(
"The server's integer resource id conversion table:\n");
this->osiLock();
this->chronIntIdResTable<casRes>::show(level);
this->osiUnlock();
}
// @@@@@@ caPrintAddrList(&destAddr);
return;
}
//
// caServerI::caServerI()
//
caServerI::caServerI (caServer &tool, unsigned nPV) :
caServerOS (*this),
chronIntIdResTable<casRes>(nPV*2u),
casEventRegistry (* (osiMutex *) this),
dgClient (*this),
//
// Set up periodic beacon interval
// (exponential back off to a plateau
@@ -123,41 +57,19 @@ caServerI::caServerI (caServer &tool, unsigned nPV) :
//
beaconPeriod (CAServerMinBeaconPeriod),
adapter (tool),
debugLevel (0u),
haveBeenInitialized (FALSE)
debugLevel (0u)
{
caStatus status;
double maxPeriod;
assert (&adapter != NULL);
if (this->osiMutex::init ()) {
errMessage (S_cas_noMemory, "CA server mutex init");
return;
}
status = caServerIO::init (*this);
if (status) {
errMessage (status, "CA server IO internals init");
return;
}
if (this->intfList.count()==0u) {
errMessage (S_cas_noInterface, "CA server internals init");
return;
}
status = caServerOS::init();
if (status) {
errMessage (status, "CA server OS dependent init");
return;
}
status = this->dgClient.init();
if (status) {
errMessage (status, "CA server DG init");
return;
}
//
// create predefined event types
//
this->valueEvent = registerEvent ("value");
this->logEvent = registerEvent ("log");
this->alarmEvent = registerEvent ("alarm");
status = envGetDoubleConfigParam (&EPICS_CA_BEACON_PERIOD, &maxPeriod);
if (status || maxPeriod<=0.0) {
@@ -172,7 +84,13 @@ caServerI::caServerI (caServer &tool, unsigned nPV) :
this->maxBeaconInterval = maxPeriod;
}
this->haveBeenInitialized = TRUE;
this->locateInterfaces ();
if (this->intfList.count()==0u) {
errMessage (S_cas_noInterface, "CA server internals init");
return;
}
return;
}
@@ -182,7 +100,7 @@ caServerI::caServerI (caServer &tool, unsigned nPV) :
caServerI::~caServerI()
{
this->osiLock();
this->lock();
//
// delete all clients
@@ -204,7 +122,7 @@ caServerI::~caServerI()
delete pIF;
}
this->osiUnlock();
this->unlock();
}
//
@@ -212,40 +130,37 @@ caServerI::~caServerI()
//
void caServerI::installClient(casStrmClient *pClient)
{
this->osiLock();
this->lock();
this->clientList.add(*pClient);
this->osiUnlock();
this->unlock();
}
//
// caServerI::removeClient()
//
void caServerI::removeClient(casStrmClient *pClient)
void caServerI::removeClient (casStrmClient *pClient)
{
this->osiLock();
this->clientList.remove(*pClient);
this->osiUnlock();
this->lock();
this->clientList.remove (*pClient);
this->unlock();
}
//
// caServerI::connectCB()
//
void caServerI::connectCB(casIntfOS &intf)
void caServerI::connectCB (casIntfOS &intf)
{
casStreamOS *pNewClient;
caStatus status;
pNewClient = intf.newStreamClient(*this);
if (!pNewClient) {
errMessage(S_cas_noMemory, NULL);
return;
}
status = pNewClient->init();
if (status) {
errMessage(status, NULL);
delete pNewClient;
casStreamOS *pNewClient;
try {
pNewClient = intf.newStreamClient (*this);
if (!pNewClient) {
throw S_cas_noMemory;
}
}
catch (...) {
epicsPrintf ("Attempt to create entry for new client failed (C++ exception)\n");
}
}
//
@@ -272,54 +187,45 @@ void caServerI::advanceBeaconPeriod()
//
// casVerifyFunc()
//
void casVerifyFunc(const char *pFile, unsigned line, const char *pExp)
void casVerifyFunc (const char *pFile, unsigned line, const char *pExp)
{
fprintf(stderr, "the expression \"%s\" didnt evaluate to boolean true \n",
pExp);
fprintf(stderr,
"and therefore internal problems are suspected at line %u in \"%s\"\n",
line, pFile);
fprintf(stderr,
"Please forward above text to johill@lanl.gov - thanks\n");
fprintf(stderr, "the expression \"%s\" didnt evaluate to boolean true \n",
pExp);
fprintf(stderr,
"and therefore internal problems are suspected at line %u in \"%s\"\n",
line, pFile);
fprintf(stderr,
"Please forward above text to johill@lanl.gov - thanks\n");
}
//
// serverToolDebugFunc()
//
void serverToolDebugFunc(const char *pFile, unsigned line, const char *pComment)
void serverToolDebugFunc (const char *pFile, unsigned line, const char *pComment)
{
fprintf(stderr,
fprintf (stderr,
"Bad server tool response detected at line %u in \"%s\" because \"%s\"\n",
line, pFile, pComment);
}
//
// caServerI::addAddr()
// caServerI::attachInterface()
//
caStatus caServerI::addAddr(const caNetAddr &addr, int autoBeaconAddr,
int addConfigBeaconAddr)
caStatus caServerI::attachInterface (const caNetAddr &addr, bool autoBeaconAddr,
bool addConfigBeaconAddr)
{
caStatus stat;
casIntfOS *pIntf;
pIntf = new casIntfOS(*this);
if (pIntf) {
stat = pIntf->init(addr, this->dgClient,
autoBeaconAddr, addConfigBeaconAddr);
if (stat==S_cas_success) {
this->osiLock();
this->intfList.add(*pIntf);
this->osiUnlock();
}
else {
errMessage(stat, NULL);
delete pIntf;
}
}
else {
stat = S_cas_noMemory;
}
return stat;
casIntfOS *pIntf;
pIntf = new casIntfOS (*this, addr, autoBeaconAddr, addConfigBeaconAddr);
if (pIntf==NULL) {
return S_cas_noMemory;
}
this->lock ();
this->intfList.add (*pIntf);
this->unlock ();
return S_cas_success;
}
@@ -335,13 +241,13 @@ void caServerI::sendBeacon()
// otherwise. Also send a beacon to all configured
// addresses.
//
this->osiLock();
this->lock();
tsDLIterBD<casIntfOS> iter(this->intfList.first());
while ( iter ) {
iter->requestBeacon();
iter->sendBeacon();
iter++;
}
this->osiUnlock();
this->unlock();
//
// double the period between beacons (but dont exceed max)
@@ -349,6 +255,76 @@ void caServerI::sendBeacon()
this->advanceBeaconPeriod();
}
//
// caServerI::getBeaconPeriod()
//
double caServerI::getBeaconPeriod() const
{
return this->beaconPeriod;
}
//
// caServerI::show()
//
void caServerI::show (unsigned level) const
{
int bytes_reserved;
printf( "Channel Access Server Status V%d.%d\n",
CA_PROTOCOL_VERSION, CA_MINOR_VERSION);
this->osiMutex::show(level);
this->lock();
tsDLIterBD<casStrmClient> iterCl(this->clientList.first());
while ( iterCl!=tsDLIterBD<casStrmClient>::eol() ) {
iterCl->show(level);
++iterCl;
}
tsDLIterBD<casIntfOS> iterIF(this->intfList.first());
while ( iterIF!=tsDLIterBD<casIntfOS>::eol() ) {
iterIF->casIntfOS::show(level);
++iterIF;
}
this->unlock();
bytes_reserved = 0u;
#if 0
bytes_reserved += sizeof(casClient) *
ellCount(&this->freeClientQ);
bytes_reserved += sizeof(casChannel) *
ellCount(&this->freeChanQ);
bytes_reserved += sizeof(casEventBlock) *
ellCount(&this->freeEventQ);
bytes_reserved += sizeof(casAsyncIIO) *
ellCount(&this->freePendingIO);
#endif
if (level>=1) {
printf(
"There are currently %d bytes on the server's free list\n",
bytes_reserved);
#if 0
printf(
"%d client(s), %d channel(s), %d event(s) (monitors), and %d IO blocks\n",
ellCount(&this->freeClientQ),
ellCount(&this->freeChanQ),
ellCount(&this->freeEventQ),
ellCount(&this->freePendingIO));
#endif
printf(
"The server's integer resource id conversion table:\n");
this->lock();
this->chronIntIdResTable<casRes>::show(level);
this->unlock();
}
// @@@@@@ caPrintAddrList(&destAddr);
return;
}
//
// casEventRegistry::~casEventRegistry()
//
@@ -358,3 +334,4 @@ casEventRegistry::~casEventRegistry()
{
this->destroyAllEntries();
}
+20 -15
View File
@@ -29,6 +29,9 @@
*
* History
* $Log$
* Revision 1.6 1999/08/04 23:52:10 jhill
* chronIntIdResTable name change
*
* Revision 1.5 1997/06/13 09:15:52 jhill
* connect proto changes
*
@@ -75,14 +78,14 @@ inline casRes *caServerI::lookupRes(const caResId &idIn, casResType type)
chronIntId id (idIn);
casRes *pRes;
this->osiLock();
this->lock();
pRes = this->chronIntIdResTable<casRes>::lookup (id);
if (pRes) {
if (pRes->resourceType()!=type) {
pRes = NULL;
}
}
this->osiUnlock();
this->unlock();
return pRes;
}
@@ -118,19 +121,6 @@ inline casRes *caServerI::removeItem(casRes &res)
return this->chronIntIdResTable<casRes>::remove(res);
}
//
// caServerI::ready()
//
inline aitBool caServerI::ready()
{
if (this->haveBeenInitialized) {
return aitTrue;
}
else {
return aitFalse;
}
}
//
// caServerI::setDebugLevel()
//
@@ -139,5 +129,20 @@ inline void caServerI::setDebugLevel(unsigned debugLevelIn)
this->debugLevel = debugLevelIn;
}
inline casEventMask caServerI::valueEventMask() const
{
return this->valueEvent;
}
inline casEventMask caServerI::logEventMask() const
{
return this->logEvent;
}
inline casEventMask caServerI::alarmEventMask() const
{
return this->alarmEvent;
}
#endif // caServerIIL_h
-62
View File
@@ -1,62 +0,0 @@
/*
* $Id$
*
* Author Jeffrey O. Hill
* johill@lanl.gov
* 505 665 1831
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
*
* History
* $Log$
* Revision 1.3 1997/04/10 19:33:55 jhill
* API changes
*
* Revision 1.2 1996/11/02 00:53:57 jhill
* many improvements
*
* Revision 1.1.1.1 1996/06/20 00:28:14 jhill
* ca server installation
*
*
*/
#include"server.h"
//
// This must be virtual so that derived destructor will
// be run indirectly. Therefore it cannot be inline.
//
epicsShareFunc casAsyncIO::~casAsyncIO()
{
}
//
// casAsyncIO::destroy()
// (default is a normal delete)
//
epicsShareFunc void casAsyncIO::destroy()
{
delete this;
}
+47 -67
View File
@@ -26,32 +26,12 @@
* Advanced Photon Source
* Argonne National Laboratory
*
*
* History
* $Log$
* Revision 1.9 1998/04/16 21:17:38 jhill
* fixed spelling in comment
*
* Revision 1.8 1998/04/14 00:49:26 jhill
* cosmetic
*
* Revision 1.7 1997/08/05 00:47:00 jhill
* fixed warnings
*
* Revision 1.6 1997/04/10 19:33:56 jhill
* API changes
*
* Revision 1.5 1996/12/13 00:08:35 jhill
* dont unlock after destroy
*
* Revision 1.4 1996/11/02 00:53:58 jhill
* many improvements
*
*
*/
#include "server.h"
#include "caServerIIL.h" // caServerI in line func
#include "casCoreClientIL.h" // casCoreClient in line func
#include "casEventSysIL.h" // casEventSys in line func
#include "casAsyncIOIIL.h" // casAsyncIOI in line func
#include "casCtxIL.h" // casCtx in line func
@@ -59,13 +39,12 @@
//
// casAsyncIOI::casAsyncIOI()
//
casAsyncIOI::casAsyncIOI(casCoreClient &clientIn, casAsyncIO &ioExternalIn) :
client(clientIn),
ioExternal(ioExternalIn),
inTheEventQueue(FALSE),
posted(FALSE),
ioComplete(FALSE),
serverDelete(FALSE)
casAsyncIOI::casAsyncIOI (casCoreClient &clientIn) :
client (clientIn),
inTheEventQueue (FALSE),
posted (FALSE),
ioComplete (FALSE),
serverDelete (FALSE)
{
//
// catch situation where they create more than one
@@ -89,7 +68,7 @@ casAsyncIOI::casAsyncIOI(casCoreClient &clientIn, casAsyncIO &ioExternalIn) :
// 1) io completes, this is pulled off the queue, and result
// is sent to the client
// 2) client, channel, or PV is deleted
// 3) server tool deletes the casAsyncIO obj
// 3) server tool deletes the casAsyncXxxxIO obj
//
// Case 1) => normal completion
//
@@ -138,12 +117,11 @@ casAsyncIOI::~casAsyncIOI()
this->unlock();
}
//
// casAsyncIOI::cbFunc()
// (called when IO completion event reaches top of event queue)
//
epicsShareFunc caStatus casAsyncIOI::cbFunc(class casEventSys &)
caStatus casAsyncIOI::cbFunc(class casEventSys &)
{
casCoreClient &theClient = this->client;
caStatus status;
@@ -153,7 +131,7 @@ epicsShareFunc caStatus casAsyncIOI::cbFunc(class casEventSys &)
// asynch IO's lock) here because we need to leave the lock
// applied around the destroy() call here.
//
theClient.osiLock();
theClient.lock();
this->inTheEventQueue = FALSE;
@@ -177,15 +155,13 @@ epicsShareFunc caStatus casAsyncIOI::cbFunc(class casEventSys &)
// dont use "this" after potentially destroying the
// object here
//
this->serverDelete = TRUE;
(*this)->destroy();
this->serverDestroy();
theClient.osiUnlock();
theClient.unlock();
return S_cas_success;
}
//
// casAsyncIOI::postIOCompletionI()
//
@@ -210,9 +186,8 @@ caStatus casAsyncIOI::postIOCompletionI()
// dont use "this" after potentially destroying the
// object here
//
this->serverDelete = TRUE;
this->unlock();
(*this)->destroy();
this->serverDestroy();
return S_cas_redundantPost;
}
@@ -253,47 +228,52 @@ caServer *casAsyncIOI::getCAS() const
//
// casAsyncIOI::readOP()
//
epicsShareFunc int casAsyncIOI::readOP()
epicsShareFunc bool casAsyncIOI::readOP() const
{
//
// not a read op
//
return FALSE;
return false;
}
//
// casAsyncIOI::destroyIfReadOP()
// casAsyncIOI::serverDestroyIfReadOP()
//
void casAsyncIOI::destroyIfReadOP()
void casAsyncIOI::serverDestroyIfReadOP()
{
casCoreClient &clientCopy = this->client;
//
// client lock used because this object's
// lock may be destroyed
//
clientCopy.osiLock();
if (this->readOP()) {
this->serverDelete = TRUE;
(*this)->destroy();
}
//
// NO REF TO THIS OBJECT BELOW HERE
// BECAUSE OF THE DELETE ABOVE
//
clientCopy.osiUnlock();
casCoreClient &clientCopy = this->client;
//
// client lock used because this object's
// lock may be destroyed
//
clientCopy.lock();
if (this->readOP()) {
this->serverDestroy();
}
//
// NO REF TO THIS OBJECT BELOW HERE
// BECAUSE OF THE DELETE ABOVE
//
clientCopy.unlock();
}
//
// casAsyncIOI::reportInvalidAsynchIO()
// void casAsyncIOI::serverDestroy ()
//
void casAsyncIOI::reportInvalidAsynchIO(unsigned request)
void casAsyncIOI::serverDestroy ()
{
ca_printf("Server tools selection of async IO type\n");
ca_printf("is inappropriate = %u and will be ignored\n",
request);
this->serverDelete = TRUE;
this->destroy();
}
//
// void casAsyncIOI::destroy ()
//
void casAsyncIOI::destroy ()
{
delete this;
}
+2 -32
View File
@@ -26,19 +26,6 @@
* Advanced Photon Source
* Argonne National Laboratory
*
*
* History
* $Log$
* Revision 1.3 1996/09/16 18:23:58 jhill
* vxWorks port changes
*
* Revision 1.2 1996/09/04 20:16:24 jhill
* moved operator -> here
*
* Revision 1.1.1.1 1996/06/20 00:28:16 jhill
* ca server installation
*
*
*/
@@ -55,7 +42,7 @@
//
inline void casAsyncIOI::lock()
{
client.osiLock();
client.lock();
}
//
@@ -63,24 +50,7 @@ inline void casAsyncIOI::lock()
//
inline void casAsyncIOI::unlock()
{
client.osiUnlock();
}
//
// casAsyncIO * casAsyncIOI::operator -> ()
//
inline casAsyncIO * casAsyncIOI::operator -> ()
{
return &this->ioExternal;
}
//
// void casAsyncIOI::destroy ()
//
inline void casAsyncIOI::destroy ()
{
this->serverDelete = TRUE;
(*this)->destroy();
client.unlock();
}
#endif // casAsyncIOIIL_h
+111
View File
@@ -0,0 +1,111 @@
/*
* $Id$
*
* Author Jeffrey O. Hill
* johill@lanl.gov
* 505 665 1831
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
*/
#include "server.h"
#include "casAsyncIOIIL.h" // casAsyncIOI in line func
#include "casChannelIIL.h" // casChannelI in line func
#include "casCtxIL.h" // casCtx in line func
#include "casCoreClientIL.h" // casCoreClient in line func
//
// casAsyncPVAttachIO::casAsyncPVAttachIO()
//
casAsyncPVAttachIO::casAsyncPVAttachIO (const casCtx &ctx) :
casAsyncIOI (*ctx.getClient()),
msg (*ctx.getMsg()),
retVal (S_cas_badParameter)
{
this->client.installAsyncIO (*this);
}
//
// casAsyncPVAttachIO::~casAsyncPVAttachIO()
//
casAsyncPVAttachIO::~casAsyncPVAttachIO()
{
this->client.removeAsyncIO (*this);
}
//
// casAsyncPVAttachIO::postIOCompletion()
//
caStatus casAsyncPVAttachIO::postIOCompletion(const pvAttachReturn &retValIn)
{
this->retVal = retValIn;
return this->postIOCompletionI ();
}
//
// casAsyncPVAttachIO::cbFuncAsyncIO()
// (called when IO completion event reaches top of event queue)
//
epicsShareFunc caStatus casAsyncPVAttachIO::cbFuncAsyncIO()
{
caStatus status;
switch (this->msg.m_cmmd) {
case CA_PROTO_CLAIM_CIU:
status = this->client.createChanResponse (this->msg, this->retVal);
break;
default:
errPrintf (S_cas_invalidAsynchIO, __FILE__, __LINE__,
" - client request type = %u", this->msg.m_cmmd);
status = S_cas_invalidAsynchIO;
break;
}
return status;
}
//
// void casAsyncPVAttachIO::destroy ()
//
void casAsyncPVAttachIO::destroy ()
{
delete this;
}
//
// depricated
//
casAsyncPVCreateIO::casAsyncPVCreateIO(const casCtx &ctx) :
casAsyncPVAttachIO (ctx)
{
}
//
// depricated
//
epicsShareFunc casAsyncPVCreateIO::~casAsyncPVCreateIO()
{
}
@@ -36,61 +36,63 @@
#include "casCoreClientIL.h" // casCoreClient in line func
//
// casAsyncExIOI::casAsyncExIOI()
// casAsyncPVExistIO::casAsyncPVExistIO()
//
epicsShareFunc casAsyncExIOI::casAsyncExIOI(
const casCtx &ctx, casAsyncPVExistIO &ioIn) :
casAsyncIOI(*ctx.getClient(), ioIn),
msg(*ctx.getMsg()),
retVal(pverDoesNotExistHere),
pOutDGIntfIO(ctx.getClient()->fetchOutIntf()),
dgOutAddr(ctx.getClient()->fetchRespAddr())
casAsyncPVExistIO::casAsyncPVExistIO (const casCtx &ctx) :
casAsyncIOI ( *ctx.getClient () ),
msg ( *ctx.getMsg () ),
retVal (pverDoesNotExistHere),
dgOutAddr ( ctx.getClient ()->fetchLastRecvAddr () )
{
assert (&this->msg);
this->client.installAsyncIO(*this);
this->client.installAsyncIO (*this);
}
//
// casAsyncExIOI::~casAsyncExIOI()
// casAsyncPVExistIO::~casAsyncPVExistIO ()
//
casAsyncExIOI::~casAsyncExIOI()
casAsyncPVExistIO::~casAsyncPVExistIO ()
{
this->client.removeAsyncIO(*this);
this->client.removeAsyncIO (*this);
}
//
// casAsyncExIOI::postIOCompletion()
// casAsyncPVExistIO::postIOCompletion ()
//
epicsShareFunc caStatus casAsyncExIOI::postIOCompletion(const pvExistReturn &retValIn)
caStatus casAsyncPVExistIO::postIOCompletion (const pvExistReturn &retValIn)
{
this->retVal = retValIn;
return this->postIOCompletionI();
return this->postIOCompletionI ();
}
//
// casAsyncExIOI::cbFuncAsyncIO()
// casAsyncPVExistIO::cbFuncAsyncIO()
// (called when IO completion event reaches top of event queue)
//
epicsShareFunc caStatus casAsyncExIOI::cbFuncAsyncIO()
epicsShareFunc caStatus casAsyncPVExistIO::cbFuncAsyncIO()
{
caStatus status;
switch (this->msg.m_cmmd) {
case CA_PROTO_SEARCH:
if (this->msg.m_cmmd==CA_PROTO_SEARCH) {
//
// pass output DG address parameters
//
assert(this->pOutDGIntfIO);
status = this->client.asyncSearchResponse(*this->pOutDGIntfIO,
status = this->client.asyncSearchResponse (
this->dgOutAddr, this->msg, this->retVal);
break;
default:
this->reportInvalidAsynchIO(this->msg.m_cmmd);
status = S_cas_internal;
break;
}
else {
errPrintf (S_cas_invalidAsynchIO, __FILE__, __LINE__,
" - client request type = %u", this->msg.m_cmmd);
status = S_cas_invalidAsynchIO;
}
return status;
}
//
// void casAsyncPVExistIO::destroy ()
//
void casAsyncPVExistIO::destroy ()
{
delete this;
}
@@ -26,40 +26,6 @@
* Advanced Photon Source
* Argonne National Laboratory
*
*
* History
* $Log$
* Revision 1.7 1998/07/08 15:38:03 jhill
* fixed lost monitors during flow control problem
*
* Revision 1.6 1998/06/18 00:08:30 jhill
* deleted unused variables
*
* Revision 1.5 1998/06/16 02:18:53 jhill
* use smart gdd ptr
*
* Revision 1.4 1997/08/05 00:47:01 jhill
* fixed warnings
*
* Revision 1.3 1997/04/10 19:33:56 jhill
* API changes
*
* Revision 1.2 1996/11/06 22:15:54 jhill
* allow monitor init read to using rd async io
*
* Revision 1.1 1996/11/02 01:01:03 jhill
* installed
*
* Revision 1.3 1996/09/04 20:13:16 jhill
* initialize new member - asyncIO
*
* Revision 1.2 1996/06/26 21:18:50 jhill
* now matches gdd api revisions
*
* Revision 1.1.1.1 1996/06/20 00:28:14 jhill
* ca server installation
*
*
*/
@@ -69,25 +35,24 @@
#include "casCtxIL.h" // casCtxI in line func
//
// casAsyncRdIOI::casAsyncRdIOI()
// casAsyncReadIO::casAsyncReadIO()
//
epicsShareFunc casAsyncRdIOI::casAsyncRdIOI(const casCtx &ctx, casAsyncReadIO &ioIn) :
casAsyncIOI(*ctx.getClient(), ioIn),
casAsyncReadIO::casAsyncReadIO(const casCtx &ctx) :
casAsyncIOI(*ctx.getClient()),
msg(*ctx.getMsg()),
chan(*ctx.getChannel()),
pDD(NULL),
completionStatus(S_cas_internal)
{
assert (&this->msg);
assert (&this->chan);
this->chan.installAsyncIO(*this);
}
//
// casAsyncRdIOI::~casAsyncRdIOI()
// casAsyncReadIO::~casAsyncReadIO()
//
casAsyncRdIOI::~casAsyncRdIOI()
casAsyncReadIO::~casAsyncReadIO()
{
this->lock();
@@ -97,9 +62,9 @@ casAsyncRdIOI::~casAsyncRdIOI()
}
//
// casAsyncRdIOI::postIOCompletion()
// casAsyncReadIO::postIOCompletion()
//
epicsShareFunc caStatus casAsyncRdIOI::postIOCompletion(caStatus completionStatusIn,
caStatus casAsyncReadIO::postIOCompletion(caStatus completionStatusIn,
gdd &valueRead)
{
this->lock();
@@ -111,19 +76,18 @@ epicsShareFunc caStatus casAsyncRdIOI::postIOCompletion(caStatus completionStatu
}
//
// casAsyncRdIOI::readOP()
// casAsyncReadIO::readOP()
//
epicsShareFunc int casAsyncRdIOI::readOP()
epicsShareFunc bool casAsyncReadIO::readOP() const
{
return TRUE; // it is a read op
return true; // it is a read op
}
//
// casAsyncRdIOI::cbFuncAsyncIO()
// casAsyncReadIO::cbFuncAsyncIO()
// (called when IO completion event reaches top of event queue)
//
caStatus casAsyncRdIOI::cbFuncAsyncIO()
epicsShareFunc caStatus casAsyncReadIO::cbFuncAsyncIO()
{
caStatus status;
@@ -146,11 +110,19 @@ caStatus casAsyncRdIOI::cbFuncAsyncIO()
break;
default:
this->reportInvalidAsynchIO(this->msg.m_cmmd);
status = S_cas_internal;
errPrintf (S_cas_invalidAsynchIO, __FILE__, __LINE__,
" - client request type = %u", this->msg.m_cmmd);
status = S_cas_invalidAsynchIO;
break;
}
return status;
}
//
// void casAsyncReadIO::destroy ()
//
void casAsyncReadIO::destroy ()
{
delete this;
}
@@ -26,49 +26,31 @@
* Advanced Photon Source
* Argonne National Laboratory
*
*
* History
* $Log$
* Revision 1.4 1997/08/05 00:47:02 jhill
* fixed warnings
*
* Revision 1.3 1997/04/10 19:33:57 jhill
* API changes
*
* Revision 1.2 1996/11/06 22:15:56 jhill
* allow monitor init read to using rd async io
*
* Revision 1.1 1996/11/02 01:01:04 jhill
* installed
*
*
*/
#include "server.h"
#include "casAsyncIOIIL.h" // casAsyncIOI in line func
#include "casChannelIIL.h" // casChannelI in line func
#include "casAsyncIOIIL.h" // casAsyncIOI in line func
#include "casCtxIL.h" // casCtx in line func
//
// casAsyncWtIOI::casAsyncWtIOI()
// casAsyncWriteIO::casAsyncWriteIO()
//
epicsShareFunc casAsyncWtIOI::casAsyncWtIOI(const casCtx &ctx, casAsyncWriteIO &ioIn) :
casAsyncIOI(*ctx.getClient(), ioIn),
casAsyncWriteIO::casAsyncWriteIO(const casCtx &ctx) :
casAsyncIOI(*ctx.getClient()),
msg(*ctx.getMsg()),
chan(*ctx.getChannel()),
completionStatus(S_cas_internal)
{
assert (&this->msg);
assert (&this->chan);
this->chan.installAsyncIO(*this);
}
//
// casAsyncWtIOI::~casAsyncWtIOI()
// casAsyncWriteIO::~casAsyncWriteIO()
//
casAsyncWtIOI::~casAsyncWtIOI()
casAsyncWriteIO::~casAsyncWriteIO()
{
this->lock();
this->chan.removeAsyncIO(*this);
@@ -76,40 +58,47 @@ casAsyncWtIOI::~casAsyncWtIOI()
}
//
// casAsyncWtIOI::postIOCompletion()
// casAsyncWriteIO::postIOCompletion()
//
epicsShareFunc caStatus casAsyncWtIOI::postIOCompletion(caStatus completionStatusIn)
caStatus casAsyncWriteIO::postIOCompletion(caStatus completionStatusIn)
{
this->completionStatus = completionStatusIn;
return this->postIOCompletionI();
}
//
// casAsyncWtIOI::cbFuncAsyncIO()
// casAsyncWriteIO::cbFuncAsyncIO()
// (called when IO completion event reaches top of event queue)
//
caStatus casAsyncWtIOI::cbFuncAsyncIO()
epicsShareFunc caStatus casAsyncWriteIO::cbFuncAsyncIO()
{
caStatus status;
switch (this->msg.m_cmmd) {
case CA_PROTO_WRITE:
status = client.writeResponse(this->msg,
this->completionStatus);
break;
case CA_PROTO_WRITE_NOTIFY:
status = client.writeNotifyResponse(
this->msg, this->completionStatus);
break;
default:
this->reportInvalidAsynchIO(this->msg.m_cmmd);
status = S_cas_internal;
break;
}
return status;
caStatus status;
switch (this->msg.m_cmmd) {
case CA_PROTO_WRITE:
status = client.writeResponse(this->msg,
this->completionStatus);
break;
case CA_PROTO_WRITE_NOTIFY:
status = client.writeNotifyResponse(
this->msg, this->completionStatus);
break;
default:
errPrintf (S_cas_invalidAsynchIO, __FILE__, __LINE__,
" - client request type = %u", this->msg.m_cmmd);
status = S_cas_invalidAsynchIO;
break;
}
return status;
}
//
// void casAsyncWriteIO::destroy ()
//
void casAsyncWriteIO::destroy ()
{
delete this;
}
-100
View File
@@ -1,100 +0,0 @@
/*
* $Id$
*
* Author Jeffrey O. Hill
* johill@lanl.gov
* 505 665 1831
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
*
* History
* $Log$
* Revision 1.4 1998/02/05 22:51:34 jhill
* include resourceLib.h
*
* Revision 1.3 1997/08/05 00:47:02 jhill
* fixed warnings
*
* Revision 1.2 1997/04/10 19:33:58 jhill
* API changes
*
* Revision 1.1 1996/11/02 01:01:05 jhill
* installed
*
*
*
*/
//
// EPICS
// (some of these are included from casdef.h but
// are included first here so that they are included
// once only before epicsExportSharedSymbols is defined)
//
#include "alarm.h" // EPICS alarm severity/condition
#include "errMdef.h" // EPICS error codes
#include "gdd.h" // EPICS data descriptors
#include "resourceLib.h" // EPICS hashing templates
#define epicsExportSharedSymbols
#include "casdef.h"
//
// This must be virtual so that derived destructor will
// be run indirectly. Therefore it cannot be inline.
//
epicsShareFunc casAsyncReadIO::~casAsyncReadIO()
{
}
//
// This must be virtual so that derived destructor will
// be run indirectly. Therefore it cannot be inline.
//
epicsShareFunc casAsyncWriteIO::~casAsyncWriteIO()
{
}
//
// This must be virtual so that derived destructor will
// be run indirectly. Therefore it cannot be inline.
//
epicsShareFunc casAsyncPVExistIO::~casAsyncPVExistIO()
{
}
//
// This must be virtual so that derived destructor will
// be run indirectly. Therefore it cannot be inline.
//
epicsShareFunc casAsyncPVCreateIO::~casAsyncPVCreateIO()
{
}
//
// This must be virtual so that derived destructor will
// be run indirectly. Therefore it cannot be inline.
//
epicsShareFunc casAsyncPVAttachIO::~casAsyncPVAttachIO()
{
}
+4 -1
View File
@@ -29,6 +29,9 @@
*
* History
* $Log$
* Revision 1.4 1997/06/13 09:15:54 jhill
* connect proto changes
*
* Revision 1.3 1997/04/10 19:33:58 jhill
* API changes
*
@@ -58,7 +61,7 @@ casChanDelEv::~casChanDelEv()
caStatus casChanDelEv::cbFunc(casEventSys &eSys)
{
caStatus status;
status = eSys.getCoreClient().disconnectChan(this->id);
status = eSys.disconnectChan (this->id);
if (status == S_cas_success) {
delete this;
}
+11 -26
View File
@@ -27,24 +27,6 @@
* Argonne National Laboratory
*
*
* History
* $Log$
* Revision 1.5 1997/04/10 19:33:59 jhill
* API changes
*
* Revision 1.4 1996/09/04 20:17:34 jhill
* use ptr not ref to satisfy MSVISC++
*
* Revision 1.3 1996/08/13 22:52:31 jhill
* changes for MVC++
*
* Revision 1.2 1996/07/01 19:56:09 jhill
* one last update prior to first release
*
* Revision 1.1.1.1 1996/06/20 00:28:14 jhill
* ca server installation
*
*
*/
#include "server.h"
@@ -55,7 +37,7 @@
// casChannel::casChannel()
//
epicsShareFunc casChannel::casChannel(const casCtx &ctx) :
casPVListChan (ctx, *this)
casPVListChan (ctx)
{
}
@@ -66,12 +48,15 @@ epicsShareFunc casChannel::~casChannel()
{
}
//
// casChannel::getPV()
//
epicsShareFunc casPV *casChannel::getPV()
{
casPVI *pPVI = &this->casChannelI::getPVI();
if (pPVI!=NULL) {
return pPVI->interfaceObjectPointer();
return pPVI->apiPointer();
}
else {
return NULL;
@@ -92,26 +77,26 @@ epicsShareFunc void casChannel::setOwner(const char * const /* pUserName */,
//
// casChannel::readAccess()
//
epicsShareFunc aitBool casChannel::readAccess () const
epicsShareFunc bool casChannel::readAccess () const
{
return aitTrue;
return true;
}
//
// casChannel::writeAccess()
//
epicsShareFunc aitBool casChannel::writeAccess() const
epicsShareFunc bool casChannel::writeAccess() const
{
return aitTrue;
return true;
}
//
// casChannel::confirmationRequested()
//
epicsShareFunc aitBool casChannel::confirmationRequested() const
epicsShareFunc bool casChannel::confirmationRequested() const
{
return aitFalse;
return false;
}
//
+55 -90
View File
@@ -26,31 +26,6 @@
* Advanced Photon Source
* Argonne National Laboratory
*
*
* History
* $Log$
* Revision 1.7 1998/09/24 20:33:03 jhill
* cosmetic
*
* Revision 1.6 1998/07/08 15:38:03 jhill
* fixed lost monitors during flow control problem
*
* Revision 1.5 1998/04/14 00:50:00 jhill
* cosmetic
*
* Revision 1.4 1997/04/10 19:34:00 jhill
* API changes
*
* Revision 1.3 1996/11/02 00:54:02 jhill
* many improvements
*
* Revision 1.2 1996/09/04 20:18:03 jhill
* init new chan member
*
* Revision 1.1.1.1 1996/06/20 00:28:14 jhill
* ca server installation
*
*
*/
#include "server.h"
@@ -59,34 +34,26 @@
#include "casPVIIL.h" // casPVI inline func
#include "casCtxIL.h" // casCtx inline func
//
// casChannelI::casChannelI()
//
casChannelI::casChannelI(const casCtx &ctx, casChannel &chanAdapter) :
client(* (casStrmClient *) ctx.getClient()),
pv(*ctx.getPV()),
chan(chanAdapter),
cid(ctx.getMsg()->m_cid),
clientDestroyPending(FALSE),
accessRightsEvPending(FALSE)
casChannelI::casChannelI (const casCtx &ctx) :
client ( * (casStrmClient *) ctx.getClient ()),
pv (*ctx.getPV()),
cid (ctx.getMsg()->m_cid),
accessRightsEvPending (FALSE)
{
assert(&this->client);
assert(&this->pv);
assert(&this->chan);
assert (&this->client);
assert (&this->pv);
this->client.installChannel(*this);
this->client.installChannel (*this);
}
//
// casChannelI::~casChannelI()
//
casChannelI::~casChannelI()
{
casChanDelEv *pCDEV;
caStatus status;
{
this->lock();
//
@@ -99,14 +66,14 @@ casChannelI::~casChannelI()
//
tsDLIterBD<casAsyncIOI> tmpAIO = iterAIO;
++tmpAIO;
iterAIO->destroy();
iterAIO->serverDestroy();
iterAIO = tmpAIO;
}
//
// cancel the monitors
//
tsDLIterBD<casMonitor> iterMon(this->monitorList.first());
tsDLIterBD<casMonitor> iterMon (this->monitorList.first());
while ( iterMon!=tsDLIterBD<casMonitor>::eol() ) {
casMonitor *pMonitor;
//
@@ -126,40 +93,9 @@ casChannelI::~casChannelI()
//
this->pv.deleteSignal();
//
// If we are not in the process of deleting the client
// then inform the client that we have deleted its
// channel
//
if (!this->clientDestroyPending) {
pCDEV = new casChanDelEv(this->getCID());
if (pCDEV) {
this->client.casEventSys::addToEventQueue(*pCDEV);
}
else {
status = this->client.disconnectChan (this->getCID());
if (status) {
//
// At this point there is no space in pool
// for a tiny object and there is also
// no outgoing buffer space in which to place
// a message in which we inform the client
// that his channel was deleted.
//
// => disconnect this client via the event
// queue because deleting the client here
// will result in bugs because no doubt this
// could be called by a client member function.
//
this->client.setDestroyPending();
}
}
}
this->unlock();
}
//
// casChannelI::clearOutstandingReads()
//
@@ -177,14 +113,13 @@ void casChannelI::clearOutstandingReads()
//
tsDLIterBD<casAsyncIOI> tmp = iterIO;
++tmp;
iterIO->destroyIfReadOP();
iterIO->serverDestroyIfReadOP();
iterIO = tmp;
}
this->unlock();
}
//
// casChannelI::show()
//
@@ -195,19 +130,18 @@ void casChannelI::show(unsigned level) const
tsDLIterBD<casMonitor> iter(this->monitorList.first());
if ( iter!=tsDLIterBD<casMonitor>::eol() ) {
printf("List of CA events (monitors) for \"%s\".\n",
this->pv->getName());
this->pv.getName());
}
while ( iter!=tsDLIterBD<casMonitor>::eol() ) {
iter->show(level);
++iter;
}
(*this)->show(level);
this->show(level);
this->unlock();
}
//
// casChannelI::cbFunc()
//
@@ -224,16 +158,6 @@ caStatus casChannelI::cbFunc(casEventSys &)
return stat;
}
//
// casChannelI::destroy()
//
// call the destroy in the server tool
//
void casChannelI::destroy()
{
this->chan.destroy();
}
//
// casChannelI::resourceType()
//
@@ -242,3 +166,44 @@ casResType casChannelI::resourceType() const
return casChanT;
}
//
// casChannelI::destroy()
//
// this noop version is safe to be called indirectly
// from casChannelI::~casChannelI
//
epicsShareFunc void casChannelI::destroy()
{
}
void casChannelI::destroyClientNotify ()
{
casChanDelEv *pCDEV;
caStatus status;
pCDEV = new casChanDelEv (this->getCID());
if (pCDEV) {
this->client.casEventSys::addToEventQueue (*pCDEV);
}
else {
status = this->client.disconnectChan (this->getCID());
if (status) {
//
// At this point there is no space in pool
// for a tiny object and there is also
// no outgoing buffer space in which to place
// a message in which we inform the client
// that his channel was deleted.
//
// => disconnect this client via the event
// queue because deleting the client here
// will result in bugs because no doubt this
// could be called by a client member function.
//
this->client.setDestroyPending();
}
}
this->destroy();
}
+8 -14
View File
@@ -29,6 +29,9 @@
*
* History
* $Log$
* Revision 1.7 1999/08/04 23:18:59 jhill
* updated to new DLL terminators
*
* Revision 1.6 1997/04/10 19:34:00 jhill
* API changes
*
@@ -57,20 +60,12 @@
#include "casCoreClientIL.h"
#include "casEventSysIL.h"
//
// casChannelI::operator -> ()
//
inline casChannel * casChannelI::operator -> () const
{
return &this->chan;
}
//
// casChannelI::lock()
//
inline void casChannelI::lock() const
{
this->client.osiLock();
this->client.lock();
}
//
@@ -78,7 +73,7 @@ inline void casChannelI::lock() const
//
inline void casChannelI::unlock() const
{
this->client.osiUnlock();
this->client.unlock();
}
//
@@ -144,12 +139,11 @@ inline casMonitor *casChannelI::findMonitor(const caResId clientIdIn)
}
//
// casChannelI::clientDestroy()
// casChannelI::destroyNoClientNotify()
//
inline void casChannelI::clientDestroy()
inline void casChannelI::destroyNoClientNotify()
{
this->clientDestroyPending=TRUE;
(*this)->destroy();
this->destroy ();
}
#include "casPVIIL.h"
+43 -78
View File
@@ -35,6 +35,7 @@
#include "casEventSysIL.h" // inline func for casEventSys
#include "casCtxIL.h" // inline func for casCtx
#include "inBufIL.h" // inline func for inBuf
#include "outBufIL.h" // inline func for outBuf
#include "casPVIIL.h" // inline func for casPVI
#include "db_access.h"
@@ -45,49 +46,19 @@ static const caHdr nill_msg = {0u,0u,0u,0u,0u,0u};
// static declartions for class casClient
//
int casClient::msgHandlersInit;
pCASMsgHandler casClient::msgHandlers[CA_PROTO_LAST_CMMD+1u];
casClient::pCASMsgHandler casClient::msgHandlers[CA_PROTO_LAST_CMMD+1u];
//
// casClient::casClient()
//
casClient::casClient(caServerI &serverInternal, inBuf &inBufIn, outBuf &outBufIn) :
casCoreClient(serverInternal),
inBufRef(inBufIn), outBufRef(outBufIn)
casClient::casClient(caServerI &serverInternal, bufSizeT ioSizeMinIn) :
inBuf (MAX_MSG_SIZE, ioSizeMinIn), outBuf (MAX_MSG_SIZE),
casCoreClient (serverInternal)
{
//
// static member init
//
casClient::loadProtoJumpTable();
}
//
// casClient::init()
//
caStatus casClient::init()
{
unsigned serverDebugLevel;
caStatus status;
//
// call base class initializers
//
status = this->casCoreClient::init();
if (status) {
return status;
}
serverDebugLevel = this->ctx.getServer()->getDebugLevel();
if (serverDebugLevel>0u) {
char pName[64u];
this->clientHostName (pName, sizeof (pName));
ca_printf("CAS: created a new client for %s\n", pName);
}
return S_cas_success;
//
// static member init
//
casClient::loadProtoJumpTable();
}
//
@@ -125,7 +96,6 @@ casChannelI *casClient::resIdToChannel(const caResId &id)
return pChan;
}
//
// casClient::loadProtoJumpTable()
//
@@ -198,7 +168,6 @@ void casClient::loadProtoJumpTable()
casClient::msgHandlersInit = TRUE;
}
//
// casClient::~casClient ()
//
@@ -206,7 +175,6 @@ casClient::~casClient ()
{
}
//
// casClient::show()
//
@@ -216,25 +184,23 @@ void casClient::show(unsigned level) const
this->casCoreClient::show(level);
}
/*
* casClient::processMsg()
*/
caStatus casClient::processMsg()
//
// casClient::processMsg ()
//
caStatus casClient::processMsg ()
{
unsigned msgsize;
unsigned bytesLeft;
int status;
const caHdr *mp;
const char *rawMP;
unsigned msgsize;
unsigned bytesLeft;
int status;
const caHdr *mp;
const char *rawMP;
//
// process any messages in the in buffer
//
status = S_cas_success;
bytesLeft = this->inBufRef.bytesPresent();
while (bytesLeft) {
while (bytesLeft = this->inBuf::bytesPresent()) {
/*
* incomplete message - return success and
@@ -245,7 +211,7 @@ caStatus casClient::processMsg()
break;
}
rawMP = this->inBufRef.msgPtr();
rawMP = this->inBuf::msgPtr();
this->ctx.setMsg(rawMP);
//
@@ -275,8 +241,8 @@ caStatus casClient::processMsg()
// (guarantees that previous message does not get mixed
// up with the current message)
//
this->ctx.setChannel(NULL);
this->ctx.setPV(NULL);
this->ctx.setChannel (NULL);
this->ctx.setPV (NULL);
//
// Check for bad protocol element
@@ -289,19 +255,28 @@ caStatus casClient::processMsg()
//
// Call protocol stub
//
status = (this->*casClient::msgHandlers[mp->m_cmmd]) ();
if (status) {
break;
}
try {
status = (this->*casClient::msgHandlers[mp->m_cmmd]) ();
if (status) {
break;
}
}
catch (...) {
this->dumpMsg (mp, this->ctx.getData() );
epicsPrintf ("Attempt to execute client request failed (C++ exception)\n");
status = this->sendErr (mp, ECA_INTERNAL, "request resulted in C++ exception");
if (status) {
break;
}
break;
}
this->inBufRef.removeMsg(msgsize);
bytesLeft = this->inBufRef.bytesPresent();
this->inBuf::removeMsg (msgsize);
}
return status;
}
/*
* casClient::ignoreMsgAction()
*/
@@ -310,7 +285,6 @@ caStatus casClient::ignoreMsgAction ()
return S_cas_success;
}
/*
* casClient::uknownMessageAction()
*/
@@ -384,7 +358,6 @@ caStatus casClient::clientNameAction ()
caStatus casClient::hostNameAction ()
{return this->uknownMessageAction ();}
//
// echoAction()
//
@@ -395,7 +368,7 @@ caStatus casClient::echoAction ()
int status;
caHdr *reply;
status = this->outBufRef.allocMsg(mp->m_postsize, &reply);
status = this->outBuf::allocMsg (mp->m_postsize, &reply);
if (status) {
if (status==S_cas_hugeRequest) {
status = sendErr(mp, ECA_TOLARGE, NULL);
@@ -404,12 +377,11 @@ caStatus casClient::echoAction ()
}
*reply = *mp;
memcpy((char *) (reply+1), (char *) dp, mp->m_postsize);
this->outBufRef.commitMsg();
this->outBuf::commitMsg();
return S_cas_success;
}
/*
* casClient::noopAction()
*/
@@ -418,9 +390,6 @@ caStatus casClient::noopAction ()
return S_cas_success;
}
//
// casClient::sendErr()
//
@@ -458,7 +427,7 @@ const char *pformat,
/*
* allocate plenty of space for a sprintf() buffer
*/
status = this->outBufRef.allocMsg (size+sizeof(caHdr), &reply);
status = this->outBuf::allocMsg (size+sizeof(caHdr), &reply);
if (status) {
return status;
}
@@ -521,12 +490,11 @@ const char *pformat,
reply->m_postsize = size + sizeof(caHdr);
this->outBufRef.commitMsg();
this->outBuf::commitMsg();
return S_cas_success;
}
/*
* casClient::sendErrWithEpicsStatus()
*
@@ -548,7 +516,6 @@ caStatus casClient::sendErrWithEpicsStatus(const caHdr *pMsg,
return this->sendErr(pMsg, clientStatus, buf);
}
/*
* casClient::logBadIdWithFileAndLineno()
*/
@@ -580,7 +547,6 @@ const unsigned id
return status;
}
//
// casClient::dumpMsg()
//
@@ -600,7 +566,7 @@ void casClient::dumpMsg(const caHdr *mp, const void *dp)
pciu = this->resIdToChannel(mp->m_cid);
if (pciu) {
strncpy(pPVName, pciu->getPVI()->getName(), sizeof(pPVName));
strncpy(pPVName, pciu->getPVI().getName(), sizeof(pPVName));
if (&pciu->getClient()!=this) {
strncat(pPVName, "!Bad Client!", sizeof(pPVName));
}
@@ -637,4 +603,3 @@ const char *casClient::userName() const
{
return "?";
}
+15 -25
View File
@@ -37,25 +37,14 @@
#include "inBufIL.h" // inBuf in line func
#include "outBufIL.h" // outBuf in line func
//
// casCoreClient::init()
//
caStatus casCoreClient::init()
{
if (this->osiMutex::init()) {
return S_cas_noMemory;
}
return this->casEventSys::init();
}
//
// casCoreClient::casCoreClient()
//
casCoreClient::casCoreClient (caServerI &serverInternal) : casEventSys(*this)
casCoreClient::casCoreClient (caServerI &serverInternal)
{
assert(&serverInternal);
ctx.setServer(&serverInternal);
ctx.setClient(this);
assert (&serverInternal);
ctx.setServer (&serverInternal);
ctx.setClient (this);
}
//
@@ -67,7 +56,7 @@ casCoreClient::~casCoreClient()
ca_printf ("CAS: Connection Terminated\n");
}
this->osiLock();
this->lock();
tsDLIterBD<casAsyncIOI> iterIO(this->ioInProgList.first());
//
@@ -79,11 +68,11 @@ casCoreClient::~casCoreClient()
//
tsDLIterBD<casAsyncIOI> tmpIO = iterIO;
++tmpIO;
iterIO->destroy();
iterIO->serverDestroy();
iterIO = tmpIO;
}
this->osiUnlock();
this->unlock();
}
//
@@ -115,7 +104,7 @@ void casCoreClient::show (unsigned level) const
// one of these for each CA request type that has
// asynchronous completion
//
caStatus casCoreClient::asyncSearchResponse(casDGIntfIO &,
caStatus casCoreClient::asyncSearchResponse (
const caNetAddr &, const caHdr &, const pvExistReturn &)
{
return S_casApp_noSupport;
@@ -171,18 +160,19 @@ void casCoreClient::removeChannel(casChannelI &)
}
//
// casCoreClient::fetchRespAddr()
// casCoreClient::fetchLastRecvAddr ()
//
caNetAddr casCoreClient::fetchRespAddr()
caNetAddr casCoreClient::fetchLastRecvAddr () const
{
return caNetAddr(); // sets addr type to UDF
}
//
// casCoreClient::fetchOutIntf()
// casCoreClient::lookupRes()
//
casDGIntfIO* casCoreClient::fetchOutIntf()
casRes *casCoreClient::lookupRes(const caResId &idIn, casResType type)
{
return NULL;
casRes *pRes;
pRes = this->ctx.getServer()->lookupRes(idIn, type);
return pRes;
}
+7 -14
View File
@@ -29,6 +29,9 @@
*
* History
* $Log$
* Revision 1.2 1997/04/10 19:34:04 jhill
* API changes
*
* Revision 1.1 1996/11/02 01:01:06 jhill
* installed
*
@@ -50,24 +53,14 @@ inline caServerI &casCoreClient::getCAS() const
return *this->ctx.getServer();
}
//
// casCoreClient::lookupRes()
//
inline casRes *casCoreClient::lookupRes(const caResId &idIn, casResType type)
{
casRes *pRes;
pRes = this->ctx.getServer()->lookupRes(idIn, type);
return pRes;
}
//
// casCoreClient::installAsyncIO()
//
inline void casCoreClient::installAsyncIO(casAsyncIOI &ioIn)
{
this->osiLock();
this->lock();
this->ioInProgList.add(ioIn);
this->osiUnlock();
this->unlock();
}
//
@@ -75,10 +68,10 @@ inline void casCoreClient::installAsyncIO(casAsyncIOI &ioIn)
//
inline void casCoreClient::removeAsyncIO(casAsyncIOI &ioIn)
{
this->osiLock();
this->lock();
this->ioInProgList.remove(ioIn);
this->ctx.getServer()->ioBlockedList::signal();
this->osiUnlock();
this->unlock();
}
#endif // casCoreClientIL_h
+365 -358
View File
@@ -27,63 +27,12 @@
* Argonne National Laboratory
*
*
* History
* $Log$
* Revision 1.16 1998/12/19 00:04:51 jhill
* renamed createPV() to pvAttach()
*
* Revision 1.15 1998/04/20 18:11:01 jhill
* better debug mesg
*
* Revision 1.14 1998/04/10 23:13:14 jhill
* fixed byte swap problems, and use default port if server tool returns PV IP addr, but no port
*
* Revision 1.13 1998/02/05 22:54:19 jhill
* moved inline func here
*
* Revision 1.12 1997/08/05 00:47:06 jhill
* fixed warnings
*
* Revision 1.11 1997/06/30 22:54:27 jhill
* use %p with pointers
*
* Revision 1.10 1997/06/13 09:15:56 jhill
* connect proto changes
*
* Revision 1.9 1997/04/10 19:34:06 jhill
* API changes
*
* Revision 1.8 1997/01/10 21:17:53 jhill
* code around gnu g++ inline bug when -O isnt used
*
* Revision 1.7 1996/11/02 00:54:08 jhill
* many improvements
*
* Revision 1.6 1996/09/16 18:24:00 jhill
* vxWorks port changes
*
* Revision 1.5 1996/09/04 20:19:47 jhill
* added missing byte swap on search reply port no
*
* Revision 1.4 1996/08/13 22:54:20 jhill
* fixed little endian problem
*
* Revision 1.3 1996/08/05 19:26:15 jhill
* made os specific code smaller
*
* Revision 1.2 1996/06/26 21:18:52 jhill
* now matches gdd api revisions
*
* Revision 1.1.1.1 1996/06/20 00:28:15 jhill
* ca server installation
*
*
*/
#include "gddApps.h"
#include "server.h"
#include "caServerIIL.h" // caServerI inline func
#include "dgOutBufIL.h" // dgOutBuf inline func
#include "outBufIL.h" // inline func for outBuf
#include "dgInBufIL.h" // dgInBuf inline func
#include "casCtxIL.h" // casCtx inline func
#include "casCoreClientIL.h" // casCoreClient inline func
@@ -95,33 +44,11 @@
//
// casDGClient::casDGClient()
//
casDGClient::casDGClient(caServerI &serverIn) :
dgInBuf(*(osiMutex *)this, casDGIntfIO::optimumInBufferSize()),
dgOutBuf(*(osiMutex *)this, casDGIntfIO::optimumOutBufferSize()),
casClient(serverIn, *this, *this),
pOutMsgIO(NULL),
pInMsgIO(NULL)
casDGClient::casDGClient (caServerI &serverIn) :
casClient (serverIn, MAX_UDP+sizeof(cadg))
{
}
//
// casDGClient::init()
//
caStatus casDGClient::init()
{
caStatus status;
status = this->dgInBuf::init();
if (status) {
return status;
}
status = this->dgOutBuf::init();
if (status) {
return status;
}
return S_cas_success;
}
//
// casDGClient::~casDGClient()
// (virtual destructor)
@@ -141,12 +68,16 @@ void casDGClient::destroy()
//
// casDGClient::show()
//
void casDGClient::show(unsigned level) const
void casDGClient::show (unsigned level) const
{
this->casClient::show(level);
printf("casDGClient at %p\n", this);
this->dgInBuf::show(level);
this->dgOutBuf::show(level);
if (level>=1u) {
char buf[64];
this->clientHostName (buf, sizeof(buf));
printf ("Client Host=%s\n", buf);
}
this->inBuf::show(level);
}
//
@@ -159,7 +90,7 @@ caStatus casDGClient::searchAction()
const char *pChanName = (const char *) dp;
caStatus status;
if (this->ctx.getServer()->getDebugLevel()>2u) {
if (this->getCAS().getDebugLevel()>2u) {
char pName[64u];
this->clientHostName (pName, sizeof (pName));
printf("%s is searching for \"%s\"\n", pName, pChanName);
@@ -182,7 +113,7 @@ caStatus casDGClient::searchAction()
//
this->asyncIOFlag = 0u;
pvExistReturn pver =
(*this->ctx.getServer())->pvExistTest(this->ctx, pChanName);
this->getCAS()->pvExistTest(this->ctx, pChanName);
//
// prevent problems when they initiate
@@ -190,158 +121,167 @@ caStatus casDGClient::searchAction()
// indicating so (and vise versa)
//
if (this->asyncIOFlag) {
pver = pverAsyncCompletion;
if (pver.getStatus()!=pverAsyncCompletion) {
errMessage (S_cas_badParameter,
"- assuming asynch IO status from caServer::pvExistTest()");
}
status = S_cas_success;
}
else if (pver.getStatus() == pverAsyncCompletion) {
pver = pverDoesNotExistHere;
errMessage(S_cas_badParameter,
"- expected asynch IO status from caServer::pvExistTest()");
else {
//
// otherwise we assume sync IO operation was initiated
//
switch (pver.getStatus()) {
case pverExistsHere:
status = this->searchResponse (*mp, pver);
break;
case pverDoesNotExistHere:
status = S_cas_success;
break;
case pverAsyncCompletion:
errMessage (S_cas_badParameter,
"- unexpected asynch IO status from caServer::pvExistTest() ignored");
status = S_cas_success;
break;
default:
errMessage (S_cas_badParameter,
"- invalid return from caServer::pvExistTest() ignored");
status = S_cas_success;
break;
}
}
//
// otherwise we assume sync IO operation was initiated
//
switch (pver.getStatus()) {
case pverDoesNotExistHere:
case pverAsyncCompletion:
status = S_cas_success;
break;
case pverExistsHere:
status = this->searchResponse(*mp, pver);
break;
default:
status = S_cas_badParameter;
break;
}
return status;
return status;
}
//
// caStatus casDGClient::searchResponse()
//
caStatus casDGClient::searchResponse(const caHdr &msg,
const pvExistReturn &retVal)
const pvExistReturn &retVal)
{
caStatus status;
caHdr *search_reply;
unsigned short *pMinorVersion;
//
// normal search failure is ignored
//
if (retVal.getStatus()==pverDoesNotExistHere) {
return S_cas_success;
}
if (retVal.getStatus()!=pverExistsHere) {
fprintf(stderr,
"async exist completion with invalid return code \"pverAsynchCompletion\"?\n");
return S_cas_success;
}
//
// if we dont have a virtual out msg io pointer
// then ignore the request
//
if (!this->pOutMsgIO) {
return S_cas_success;
}
/*
* starting with V4.1 the count field is used (abused)
* by the client to store the minor version number of
* the client.
*
* Old versions expect alloc of channel in response
* to a search request. This is no longer supported.
*/
if ( !CA_V44(CA_PROTOCOL_VERSION,msg.m_count) ) {
if (this->ctx.getServer()->getDebugLevel()>0u) {
char pName[64u];
this->clientHostName (pName, sizeof (pName));
printf("client \"%s\" using EPICS R3.11 CA connect protocol was ignored\n", pName);
}
//
// old connect protocol was dropped when the
// new API was added to the server (they must
// now use clients at EPICS 3.12 or higher)
//
status = this->sendErr(&msg, ECA_DEFUNCT,
"R3.11 connect sequence from old client was ignored");
return status;
}
/*
* obtain space for the reply message
*/
status = this->allocMsg(sizeof(*pMinorVersion), &search_reply);
if (status) {
return status;
}
*search_reply = msg;
search_reply->m_postsize = sizeof(*pMinorVersion);
/*
* cid field is abused to carry the IP
* address in CA_V48 or higher
* (this allows a CA servers to serve
* as a directory service)
*
* type field is abused to carry the IP
* port number here CA_V44 or higher
* (this allows multiple CA servers on one
* host)
*/
if (CA_V48(CA_PROTOCOL_VERSION,msg.m_count)) {
if (retVal.addrIsValid()) {
caNetAddr addr = retVal.getAddr();
struct sockaddr_in ina = addr.getSockIP();
search_reply->m_cid = ntohl (ina.sin_addr.s_addr);
if (ina.sin_port==0u) {
//
// If they dont specify a port number then the default
// CA server port is assumed when it it is a server
// address redirect (it is never correct to use this
// server's port when it is a redirect).
//
search_reply->m_type = CA_SERVER_PORT;
}
else {
search_reply->m_type = ntohs (ina.sin_port);
}
}
else {
search_reply->m_cid = ~0U;
search_reply->m_type = this->pOutMsgIO->serverPortNumber();
}
}
else {
search_reply->m_cid = ~0U;
search_reply->m_type = this->pOutMsgIO->serverPortNumber();
}
search_reply->m_count = 0ul;
/*
* Starting with CA V4.1 the minor version number
* is appended to the end of each search reply.
* This value is ignored by earlier clients.
*/
pMinorVersion = (unsigned short *) (search_reply+1);
*pMinorVersion = htons (CA_MINOR_VERSION);
this->commitMsg();
return S_cas_success;
caStatus status;
caHdr *search_reply;
struct sockaddr_in ina;
unsigned short *pMinorVersion;
//
// normal search failure is ignored
//
if (retVal.getStatus()==pverDoesNotExistHere) {
return S_cas_success;
}
if (retVal.getStatus()!=pverExistsHere) {
fprintf(stderr,
"async exist completion with invalid return code \"pverAsynchCompletion\"?\n");
return S_cas_success;
}
//
// starting with V4.1 the count field is used (abused)
// by the client to store the minor version number of
// the client.
//
// Old versions expect alloc of channel in response
// to a search request. This is no longer supported.
//
if ( !CA_V44(CA_PROTOCOL_VERSION,msg.m_count) ) {
if (this->getCAS().getDebugLevel()>0u) {
char pName[64u];
this->clientHostName (pName, sizeof (pName));
printf("client \"%s\" using EPICS R3.11 CA connect protocol was ignored\n", pName);
}
//
// old connect protocol was dropped when the
// new API was added to the server (they must
// now use clients at EPICS 3.12 or higher)
//
status = this->sendErr(&msg, ECA_DEFUNCT,
"R3.11 connect sequence from old client was ignored");
return status;
}
//
// obtain space for the reply message
//
status = this->allocMsg(sizeof(*pMinorVersion), &search_reply);
if (status) {
return status;
}
*search_reply = msg;
search_reply->m_postsize = sizeof(*pMinorVersion);
//
// cid field is abused to carry the IP
// address in CA_V48 or higher
// (this allows a CA servers to serve
// as a directory service)
//
// type field is abused to carry the IP
// port number here CA_V44 or higher
// (this allows multiple CA servers on one
// host)
//
if (CA_V48(CA_PROTOCOL_VERSION,msg.m_count)) {
if (retVal.addrIsValid()) {
caNetAddr addr = retVal.getAddr();
ina = addr.getSockIP();
//
// If they dont specify a port number then the default
// CA server port is assumed when it it is a server
// address redirect (it is never correct to use this
// server's port when it is a redirect).
//
if (ina.sin_port==0u) {
ina.sin_port = htons (CA_SERVER_PORT);
}
}
else {
caNetAddr addr = this->serverAddress ();
ina = addr.getSockIP();
//
// We dont fill in the servers address here
// because the server was not bound to a particular
// interface, and we would need to waste CPU performing
// the following steps to determine the interface that
// will be used:
//
// o connect UDP socket to the destination IP
// o perform a getsockname() call
// o disconnect UDP socket from the destination IP
//
if ( ina.sin_addr.s_addr == INADDR_ANY ) {
ina.sin_addr.s_addr = ntohl(~0U);
}
}
search_reply->m_cid = ntohl (ina.sin_addr.s_addr);
search_reply->m_type = ntohs (ina.sin_port);
}
else {
caNetAddr addr = this->serverAddress ();
struct sockaddr_in ina = addr.getSockIP();
search_reply->m_cid = ~0U;
search_reply->m_type = ntohs (ina.sin_port);
}
search_reply->m_count = 0ul;
//
// Starting with CA V4.1 the minor version number
// is appended to the end of each search reply.
// This value is ignored by earlier clients.
//
pMinorVersion = (unsigned short *) (search_reply+1);
*pMinorVersion = htons (CA_MINOR_VERSION);
this->commitMsg();
return S_cas_success;
}
//
// casDGClient::searchFailResponse()
// (only when requested by the client
@@ -366,12 +306,11 @@ caStatus casDGClient::searchFailResponse(const caHdr *mp)
return S_cas_success;
}
//
// casDGClient::sendBeacon()
// (implemented here because this has knowledge of the protocol)
//
void casDGClient::sendBeacon(casDGIntfIO &io)
void casDGClient::sendBeacon ()
{
union {
caHdr msg;
@@ -387,163 +326,232 @@ void casDGClient::sendBeacon(casDGIntfIO &io)
//
// send it to all addresses on the beacon list
//
io.sendBeacon(buf, sizeof(msg), msg.m_available, msg.m_count);
this->sendBeaconIO(buf, sizeof(msg), msg.m_available, msg.m_count);
}
//
// casDGClient::ioBlockedSignal()
// casDGClient::xSend()
//
void casDGClient::ioBlockedSignal()
outBuf::flushCondition casDGClient::xSend (char *pBufIn,
bufSizeT nBytesAvailableToSend, bufSizeT nBytesNeedToBeSent,
bufSizeT &nBytesSent)
{
//
// NOOP
//
// The DG client never blocks - if we exceed the
// max simultaneous io in progress limit
// then we discard the current request
// (the client will resend later)
//
outBuf::flushCondition stat;
bufSizeT totalBytes;
char *pBuf = pBufIn;
cadg *pHdr;
assert (nBytesAvailableToSend>=nBytesNeedToBeSent);
totalBytes = 0;
while (1) {
pHdr = reinterpret_cast<cadg *>(&pBuf[totalBytes]);
assert (totalBytes<=bufSizeT_MAX-pHdr->cadg_nBytes);
assert (totalBytes+pHdr->cadg_nBytes<=nBytesAvailableToSend);
if (pHdr->cadg_addr.isValid()) {
stat = this->osdSend (reinterpret_cast<char *>(pHdr+1),
pHdr->cadg_nBytes-sizeof(*pHdr), pHdr->cadg_addr);
if (stat!=outBuf::flushProgress) {
break;
}
}
totalBytes += pHdr->cadg_nBytes;
if (totalBytes>=nBytesNeedToBeSent) {
break;
}
}
if (totalBytes) {
//
// !! this time fetch may be slowing things down !!
//
//this->lastSendTS = osiTime::getCurrent();
nBytesSent = totalBytes;
return outBuf::flushProgress;
}
else {
return outBuf::flushNone;
}
}
//
// casDGClient::processDG()
// casDGClient::xRecv ()
//
void casDGClient::processDG(casDGIntfIO &inMsgIO, casDGIntfIO &outMsgIO)
inBuf::fillCondition casDGClient::xRecv (char *pBufIn, bufSizeT nBytesToRecv,
fillParameter parm, bufSizeT &nByesRecv)
{
caStatus status;
//
// !! special locking required here in mt case
//
//
// force all replies to be sent to the client
// that made the request
//
this->pInMsgIO = &inMsgIO;
this->pOutMsgIO = &outMsgIO;
this->inBuf::clear();
this->outBuf::clear();
const char *pAfter = pBufIn + nBytesToRecv;
char *pBuf = pBufIn;
bufSizeT nDGBytesRecv;
inBuf::fillCondition stat;
cadg *pHdr;
//
// read in new input
//
if (this->fill() != casFillDisconnect) {
while (pAfter-pBuf >= MAX_UDP+sizeof(cadg)) {
pHdr = reinterpret_cast<cadg *>(pBuf);
stat = this->osdRecv (reinterpret_cast<char *>(pHdr+1), MAX_UDP, parm,
nDGBytesRecv, pHdr->cadg_addr);
if (stat==casFillProgress) {
pHdr->cadg_nBytes = nDGBytesRecv + sizeof(*pHdr);
pBuf += pHdr->cadg_nBytes;
//
// !! this time fetch may be slowing things down !!
//
//this->lastRecvTS = osiTime::getCurrent();
}
else {
break;
}
}
//
// verify that we have a message to process
//
if (this->inBuf::bytesPresent()>0u) {
this->setRecipient(this->getSender());
//
// process the message
//
status = this->processMsg();
if (status) {
char pName[64u];
this->clientHostName (pName, sizeof (pName));
errPrintf (status, __FILE__, __LINE__,
"- bad stateless protocol from \"%s\"", pName);
}
//
// force all replies to go to the sender
//
if (this->outBuf::bytesPresent()>0u) {
casVerify (this->flush()==casFlushCompleted);
}
}
}
//
// clear the input/output buffers so replies
// are always sent to the sender of the request
//
this->pInMsgIO = NULL;
this->pOutMsgIO = NULL;
this->inBuf::clear();
this->outBuf::clear();
nDGBytesRecv = pBuf - pBufIn;
if (nDGBytesRecv) {
nByesRecv = nDGBytesRecv;
return casFillProgress;
}
else {
return casFillNone;
}
}
//
// casDGClient::asyncSearchResp()
//
caStatus casDGClient::asyncSearchResponse(
casDGIntfIO &outMsgIO, const caNetAddr &outAddr,
//
// this results in many small UDP frames which unfortunately
// isnt particularly efficient
//
caStatus casDGClient::asyncSearchResponse (const caNetAddr &outAddr,
const caHdr &msg, const pvExistReturn &retVal)
{
caStatus stat;
//
// !! special locking required here in mt case
//
this->pOutMsgIO = &outMsgIO;
this->dgOutBuf::clear();
this->setRecipient(outAddr);
//
// start a DG context in the output protocol stream
// and grab the send lock
//
void *pRaw;
const outBufCtx outctx = this->outBuf::pushCtx
(sizeof(cadg), MAX_UDP, pRaw);
if (outctx.pushResult()!=outBufCtx::pushCtxSuccess) {
return S_cas_sendBlocked;
}
stat = this->searchResponse(msg, retVal);
cadg *pRespHdr = reinterpret_cast<cadg *>(pRaw);
stat = this->searchResponse (msg, retVal);
this->dgOutBuf::flush();
this->dgOutBuf::clear();
this->pOutMsgIO = NULL;
pRespHdr->cadg_nBytes = this->outBuf::popCtx (outctx);
if (pRespHdr->cadg_nBytes>0) {
pRespHdr->cadg_addr = outAddr;
this->outBuf::commitRawMsg (pRespHdr->cadg_nBytes);
}
return stat;
}
//
// casDGClient::xDGSend()
// casDGClient::processDG ()
//
xSendStatus casDGClient::xDGSend (char *pBufIn, bufSizeT nBytesNeedToBeSent,
bufSizeT &nBytesSent, const caNetAddr &recipient)
caStatus casDGClient::processDG ()
{
xSendStatus stat;
bufSizeT bytesLeft;
caStatus status;
status = S_cas_success;
while (bytesLeft = this->inBuf::bytesPresent()) {
bufSizeT dgInBytesConsumed;
const cadg *pReqHdr = reinterpret_cast<cadg *>(this->inBuf::msgPtr ());
if (!this->pOutMsgIO) {
return xSendDisconnect;
}
stat = this->pOutMsgIO->osdSend(pBufIn, nBytesNeedToBeSent,
nBytesSent, recipient);
if (stat==xSendOK) {
//
// !! this time fetch may be slowing things down !!
//
this->lastSendTS = osiTime::getCurrent();
}
return stat;
}
if (bytesLeft<sizeof(*pReqHdr)) {
this->inBuf::removeMsg (bytesLeft);
ca_printf ("casDGClient::processMsg: incomplete DG header?");
status = S_cas_internal;
break;
}
//
// casDGClient::xDGRecv()
//
xRecvStatus casDGClient::xDGRecv (char *pBufIn, bufSizeT nBytesToRecv,
bufSizeT &nByesRecv, caNetAddr &sender)
{
xRecvStatus stat;
//
// start a DG context in the output protocol stream
// and grab the send lock
//
void *pRaw;
const outBufCtx outctx = this->outBuf::pushCtx (sizeof(cadg), MAX_UDP, pRaw);
if ( outctx.pushResult() != outBufCtx::pushCtxSuccess ) {
status = S_cas_sendBlocked;
break;
}
cadg *pRespHdr = reinterpret_cast <cadg *> (pRaw);
//
// select the next DG in the input stream and start processing it
//
const bufSizeT reqBodySize = pReqHdr->cadg_nBytes-sizeof (*pReqHdr);
const inBufCtx inctx = this->inBuf::pushCtx (sizeof (*pReqHdr), reqBodySize);
if ( inctx.pushResult() != inBufCtx::pushCtxSuccess ) {
this->inBuf::removeMsg (bytesLeft);
this->outBuf::popCtx (outctx);
ca_printf ("casDGClient::processMsg: incomplete DG?\n");
status = S_cas_internal;
break;
}
if (!this->pInMsgIO) {
return xRecvDisconnect;
}
stat = this->pInMsgIO->osdRecv(pBufIn, nBytesToRecv,
nByesRecv, sender);
if (stat==xRecvOK) {
//
// !! this time fetch may be slowing things down !!
//
this->lastRecvTS = osiTime::getCurrent();
}
return stat;
}
this->lastRecvAddr = pReqHdr->cadg_addr;
//
// casDGClient::incommingBytesPresent()
//
bufSizeT casDGClient::incommingBytesPresent() const
{
//
// !!!! perhaps this would run faster if we
// !!!! checked to see if UDP frames are in
// !!!! the queue from the same client
//
return 0u;
status = this->processMsg ();
dgInBytesConsumed = this->inBuf::popCtx (inctx);
if (dgInBytesConsumed>0) {
//
// at this point processMsg() bailed out because:
// a) it used all of the incoming DG or
// b) it used all of the outgoing DG
//
// In either case commit the DG to the protocol stream and
// release the send lock
//
pRespHdr->cadg_nBytes = this->outBuf::popCtx (outctx) + sizeof(*pRespHdr);
if (pRespHdr->cadg_nBytes>sizeof(*pRespHdr)) {
pRespHdr->cadg_addr = pReqHdr->cadg_addr;
this->outBuf::commitRawMsg (pRespHdr->cadg_nBytes);
}
//
// check to see that all of the incoming UDP frame was used
//
if (dgInBytesConsumed<reqBodySize) {
//
// remove the bytes in the body that were consumed,
// but _not_ the header bytes
//
this->inBuf::removeMsg (dgInBytesConsumed);
//
// slide the UDP header forward and correct the byte count
//
{
cadg *pReqHdrMove;
cadg copy = *pReqHdr;
pReqHdrMove = reinterpret_cast <cadg *> (this->inBuf::msgPtr ());
pReqHdrMove->cadg_addr = copy.cadg_addr;
pReqHdrMove->cadg_nBytes = copy.cadg_nBytes - dgInBytesConsumed;
}
}
else {
//
// remove the header and all of the body
//
this->inBuf::removeMsg ( pReqHdr->cadg_nBytes );
}
}
if (status!=S_cas_success) {
break;
}
}
return status;
}
//
@@ -555,18 +563,17 @@ unsigned casDGClient::getDebugLevel() const
}
//
// casDGClient::fetchRespAddr()
// casDGClient::fetchLastRecvAddr ()
//
caNetAddr casDGClient::fetchRespAddr()
caNetAddr casDGClient::fetchLastRecvAddr () const
{
return this->getRecipient();
}
//
// casDGClient::fetchOutIntf()
//
casDGIntfIO* casDGClient::fetchOutIntf()
{
return this->pOutMsgIO;
return this->lastRecvAddr;
}
//
// casDGClient::clientHostName()
//
void casDGClient::clientHostName (char *pBufIn, unsigned bufSizeIn) const
{
this->lastRecvAddr.stringConvert (pBufIn, bufSizeIn);
}
+5 -7
View File
@@ -29,6 +29,9 @@
*
* History
* $Log$
* Revision 1.14 1999/08/09 20:18:43 jhill
* back out stringIdentifier class
*
* Revision 1.13 1999/08/07 01:02:31 jhill
* solaris compiler issues
*
@@ -126,11 +129,9 @@ casEventMask casEventRegistry::maskAllocator()
{
casEventMask evMask;
this->mutex.osiLock();
if (this->allocator<CHAR_BIT*sizeof(evMask.mask)) {
evMask.mask = 1u<<(this->allocator++);
}
this->mutex.osiUnlock();
return evMask;
}
@@ -147,7 +148,6 @@ casEventMask casEventRegistry::registerEvent(const char *pName)
casEventMaskEntry *pEntry;
casEventMask mask;
this->mutex.osiLock();
pEntry = this->lookup (id);
if (pEntry) {
mask = *pEntry;
@@ -155,7 +155,7 @@ casEventMask casEventRegistry::registerEvent(const char *pName)
else {
mask = this->maskAllocator();
if (mask.mask == 0u) {
errMessage(S_cas_tooManyEvents, NULL);
errMessage (S_cas_tooManyEvents, NULL);
}
else {
pEntry = new casEventMaskEntry(*this, mask, pName);
@@ -166,10 +166,10 @@ casEventMask casEventRegistry::registerEvent(const char *pName)
mask.mask = 0u;
errMessage(S_cas_noMemory,
"mask bit was lost during init");
throw S_cas_noMemory;
}
}
}
this->mutex.osiUnlock();
return mask;
}
@@ -193,13 +193,11 @@ casEventMask::casEventMask (casEventRegistry &reg, const char *pName)
//
void casEventRegistry::show(unsigned level) const
{
this->mutex.osiLock();
if (level>1u) {
printf ("casEventRegistry: bit allocator = %d\n",
this->allocator);
}
this->resTable <casEventMaskEntry, stringId>::show(level);
this->mutex.osiUnlock();
}
//
+36 -58
View File
@@ -26,28 +26,6 @@
* Advanced Photon Source
* Argonne National Laboratory
*
*
* History
* $Log$
* Revision 1.6 1997/08/05 00:47:08 jhill
* fixed warnings
*
* Revision 1.5 1997/04/10 19:34:08 jhill
* API changes
*
* Revision 1.4 1996/12/11 01:02:35 jhill
* removed casEventMaskEntry def
*
* Revision 1.3 1996/12/06 22:32:10 jhill
* force virtual destructor
*
* Revision 1.2 1996/11/02 00:54:11 jhill
* many improvements
*
* Revision 1.1.1.1 1996/06/20 00:28:16 jhill
* ca server installation
*
*
*/
@@ -59,44 +37,44 @@
class casEventRegistry;
class epicsShareClass casEventMask {
friend inline casEventMask operator| (const casEventMask &lhs,
const casEventMask &rhs);
friend inline casEventMask operator& (const casEventMask &lhs,
const casEventMask &rhs);
friend inline int operator== (const casEventMask &lhs,
const casEventMask &rhs);
friend inline int operator!= (const casEventMask &lhs,
const casEventMask &rhs);
friend class casEventRegistry;
friend inline casEventMask operator| (const casEventMask &lhs,
const casEventMask &rhs);
friend inline casEventMask operator& (const casEventMask &lhs,
const casEventMask &rhs);
friend inline int operator== (const casEventMask &lhs,
const casEventMask &rhs);
friend inline int operator!= (const casEventMask &lhs,
const casEventMask &rhs);
friend class casEventRegistry;
public:
void clear ()
{
this->mask = 0u;
}
casEventMask (casEventRegistry &reg, const char *pName);
casEventMask ()
{
this->clear();
}
void show (unsigned level) const;
int eventsSelected()
{
return this->mask!=0u;
}
int noEventsSelected()
{
return this->mask==0u;
}
inline void operator|= (const casEventMask &rhs);
inline void operator&= (const casEventMask &rhs);
void clear ()
{
this->mask = 0u;
}
casEventMask (casEventRegistry &reg, const char *pName);
casEventMask ()
{
this->clear();
}
void show (unsigned level) const;
int eventsSelected()
{
return this->mask!=0u;
}
int noEventsSelected()
{
return this->mask==0u;
}
inline void operator|= (const casEventMask &rhs);
inline void operator&= (const casEventMask &rhs);
private:
unsigned mask;
unsigned mask;
};
inline casEventMask operator| (const casEventMask &lhs, const casEventMask &rhs)
+19 -20
View File
@@ -29,6 +29,9 @@
*
* History
* $Log$
* Revision 1.9 1999/04/30 15:33:46 jhill
* better message
*
* Revision 1.8 1998/07/23 16:48:15 jhill
* eventsOff is no longere a private member
*
@@ -74,7 +77,6 @@ void casEventSys::show(unsigned level) const
{
printf ("casEventSys at %p\n", this);
if (level>=1u) {
printf ("\thas coreClient at %p\n", &this->coreClient);
printf ("\tnumEventBlocks = %u, maxLogEntries = %u\n",
this->numEventBlocks, this->maxLogEntries);
printf ("\tthere are %d events in the queue\n",
@@ -84,7 +86,6 @@ void casEventSys::show(unsigned level) const
}
}
//
// casEventSys::~casEventSys()
//
@@ -92,7 +93,7 @@ casEventSys::~casEventSys()
{
casEvent *pE;
this->mutex.osiLock();
this->mutex.lock();
if (this->pPurgeEvent != NULL) {
this->eventLogQue.remove(*this->pPurgeEvent);
@@ -108,19 +109,18 @@ casEventSys::~casEventSys()
delete pE;
}
this->mutex.osiUnlock();
this->mutex.unlock();
}
//
// casEventSys::installMonitor()
//
void casEventSys::installMonitor()
{
this->mutex.osiLock();
this->mutex.lock();
this->numEventBlocks++;
this->maxLogEntries += averageEventEntries;
this->mutex.osiUnlock();
this->mutex.unlock();
}
//
@@ -128,14 +128,13 @@ void casEventSys::installMonitor()
//
void casEventSys::removeMonitor()
{
this->mutex.osiLock();
this->mutex.lock();
assert (this->numEventBlocks>=1u);
this->numEventBlocks--;
this->maxLogEntries -= averageEventEntries;
this->mutex.osiUnlock();
this->mutex.unlock();
}
//
// casEventSys::process()
//
@@ -146,7 +145,7 @@ casProcCond casEventSys::process()
casProcCond cond = casProcOk;
unsigned long nAccepted = 0u;
this->mutex.osiLock();
this->mutex.lock();
while (!this->dontProcess) {
@@ -192,10 +191,10 @@ casProcCond casEventSys::process()
* call flush function if they provided one
*/
if (nAccepted > 0u) {
this->coreClient.eventFlush();
this->eventFlush ();
}
this->mutex.osiUnlock();
this->mutex.unlock();
//
// allows the derived class to be informed that it
@@ -218,7 +217,7 @@ casProcCond casEventSys::process()
//
void casEventSys::eventsOn()
{
this->mutex.osiLock();
this->mutex.lock();
//
// allow multiple events for each monitor
@@ -239,12 +238,12 @@ void casEventSys::eventsOn()
this->pPurgeEvent = NULL;
}
this->mutex.osiUnlock();
this->mutex.unlock();
//
// wakes up the event queue consumer
//
this->coreClient.eventSignal();
this->eventSignal ();
}
//
@@ -252,7 +251,7 @@ void casEventSys::eventsOn()
//
caStatus casEventSys::eventsOff()
{
this->mutex.osiLock();
this->mutex.lock();
//
// new events will replace the last event on
@@ -280,7 +279,7 @@ caStatus casEventSys::eventsOff()
}
}
this->mutex.osiUnlock();
this->mutex.unlock();
return S_cas_success;
}
@@ -290,10 +289,10 @@ caStatus casEventSys::eventsOff()
//
caStatus casEventPurgeEv::cbFunc (casEventSys &evSys)
{
evSys.mutex.osiLock();
evSys.mutex.lock();
evSys.dontProcess = TRUE;
evSys.pPurgeEvent = NULL;
evSys.mutex.osiUnlock();
evSys.mutex.unlock();
delete this;
+19 -38
View File
@@ -29,6 +29,9 @@
*
* History
* $Log$
* Revision 1.7 1998/07/08 15:38:05 jhill
* fixed lost monitors during flow control problem
*
* Revision 1.6 1998/02/18 22:45:29 jhill
* fixed warning
*
@@ -54,16 +57,10 @@
#ifndef casEventSysIL_h
#define casEventSysIL_h
//
// required for casCoreClient::lookupRes()
//
#include "casCoreClientIL.h"
//
// casEventSys::casEventSys ()
//
inline casEventSys::casEventSys (casCoreClient &coreClientIn) :
coreClient(coreClientIn),
inline casEventSys::casEventSys () :
pPurgeEvent(NULL),
numEventBlocks(0u),
maxLogEntries(individualEventEntries),
@@ -73,50 +70,34 @@ inline casEventSys::casEventSys (casCoreClient &coreClientIn) :
{
}
//
// casEventSys::init()
//
inline caStatus casEventSys::init()
{
return (this->mutex.init() ? S_cas_noMemory : S_cas_success);
}
//
// casEventSys::addToEventQueue()
//
inline void casEventSys::addToEventQueue(casEvent &event)
{
this->mutex.osiLock();
this->mutex.lock();
this->eventLogQue.add(event);
this->mutex.osiUnlock();
this->mutex.unlock();
//
// wake up the event queue consumer only if
// we are not supressing events to a client that
// is in flow control
//
if (!this->dontProcess) {
this->coreClient.eventSignal();
this->eventSignal();
}
}
//
// casEventSys::getCoreClient
//
inline casCoreClient &casEventSys::getCoreClient()
{
return this->coreClient;
}
//
// casEventSys::setDestroyPending()
//
void casEventSys::setDestroyPending()
inline void casEventSys::setDestroyPending()
{
this->destroyPending = aitTrue;
//
// wakes up the event queue consumer
//
this->coreClient.eventSignal();
this->eventSignal();
}
//
@@ -124,9 +105,9 @@ void casEventSys::setDestroyPending()
//
inline void casEventSys::insertEventQueue(casEvent &insert, casEvent &prevEvent)
{
this->mutex.osiLock();
this->mutex.lock();
this->eventLogQue.insertAfter(insert, prevEvent);
this->mutex.osiUnlock();
this->mutex.unlock();
}
//
@@ -134,9 +115,9 @@ inline void casEventSys::insertEventQueue(casEvent &insert, casEvent &prevEvent)
//
inline void casEventSys::pushOnToEventQueue(casEvent &event)
{
this->mutex.osiLock();
this->mutex.lock();
this->eventLogQue.push(event);
this->mutex.osiUnlock();
this->mutex.unlock();
}
//
@@ -144,21 +125,21 @@ inline void casEventSys::pushOnToEventQueue(casEvent &event)
//
inline void casEventSys::removeFromEventQueue(casEvent &event)
{
this->mutex.osiLock();
this->mutex.lock();
this->eventLogQue.remove(event);
this->mutex.osiUnlock();
this->mutex.unlock();
}
//
// casEventSys::full()
//
inline aitBool casEventSys::full()
inline bool casEventSys::full()
{
if (this->replaceEvents || this->eventLogQue.count()>=this->maxLogEntries) {
return aitTrue;
return true;
}
else {
return aitFalse;
return false;
}
}
@@ -167,7 +148,7 @@ inline aitBool casEventSys::full()
//
inline casMonitor *casEventSys::resIdToMon(const caResId id)
{
casRes *pRes = this->coreClient.lookupRes(id, casClientMonT);
casRes *pRes = this->lookupRes (id, casClientMonT);
//
// safe to cast because we have checked the type code above
+147 -290
View File
@@ -27,72 +27,6 @@
* Argonne National Laboratory
*
*
* History
* $Log$
* Revision 1.21 1999/08/04 23:54:51 jhill
* chronIntIdRes name change
*
* Revision 1.20 1999/04/30 15:37:31 jhill
* doc
*
* Revision 1.19 1998/12/19 00:04:51 jhill
* renamed createPV() to pvAttach()
*
* Revision 1.18 1998/11/18 18:52:49 jhill
* fixed casChannelI undefined symbols on WIN32
*
* Revision 1.17 1998/10/23 00:28:20 jhill
* fixed HP-UX warnings
*
* Revision 1.16 1998/07/08 15:38:05 jhill
* fixed lost monitors during flow control problem
*
* Revision 1.15 1998/06/16 02:26:09 jhill
* allow PVs to exist without a server
*
* Revision 1.14 1998/02/05 22:56:12 jhill
* cosmetic
*
* Revision 1.13 1997/08/05 00:47:09 jhill
* fixed warnings
*
* Revision 1.12 1997/06/13 09:15:58 jhill
* connect proto changes
*
* Revision 1.11 1997/04/10 19:34:10 jhill
* API changes
*
* Revision 1.10 1997/01/10 21:17:55 jhill
* code around gnu g++ inline bug when -O isnt used
*
* Revision 1.9 1996/12/06 22:33:49 jhill
* virtual ~casPVI(), ~casPVListChan(), ~casChannelI()
*
* Revision 1.8 1996/11/02 00:54:14 jhill
* many improvements
*
* Revision 1.7 1996/09/16 18:24:02 jhill
* vxWorks port changes
*
* Revision 1.6 1996/09/04 20:21:41 jhill
* removed operator -> and added member pv
*
* Revision 1.5 1996/07/01 19:56:11 jhill
* one last update prior to first release
*
* Revision 1.4 1996/06/26 23:32:17 jhill
* changed where caProto.h comes from (again)
*
* Revision 1.3 1996/06/26 21:18:54 jhill
* now matches gdd api revisions
*
* Revision 1.2 1996/06/20 18:08:35 jhill
* changed where caProto.h comes from
*
* Revision 1.1.1.1 1996/06/20 00:28:15 jhill
* ca server installation
*
*
*/
//
@@ -113,8 +47,8 @@ class casChannelI;
//
class casEvent : public tsDLNode<casEvent> {
public:
virtual ~casEvent();
virtual caStatus cbFunc(casEventSys &)=0;
virtual ~casEvent();
virtual caStatus cbFunc (casEventSys &)=0;
private:
};
@@ -152,7 +86,7 @@ public:
virtual ~ioBlocked ();
private:
ioBlockedList *pList;
virtual void ioBlockedSignal ();
virtual void ioBlockedSignal () = 0;
};
//
@@ -286,7 +220,6 @@ class casCoreClient;
class casChannelI;
class casCtx;
class caServer;
class casAsyncIO;
class casAsyncReadIO;
class casAsyncWriteIO;
class casAsyncPVExistIO;
@@ -294,31 +227,24 @@ class casAsyncPVAttachIO;
class casAsyncIOI : public casEvent, public tsDLNode<casAsyncIOI> {
public:
casAsyncIOI (casCoreClient &client, casAsyncIO &ioExternal);
casAsyncIOI (casCoreClient &client);
virtual ~casAsyncIOI();
void serverDestroyIfReadOP ();
void serverDestroy ();
caServer *getCAS() const;
protected:
casCoreClient &client;
//
// place notification of IO completion on the event queue
//
caStatus postIOCompletionI();
inline void lock();
inline void unlock();
virtual caStatus cbFuncAsyncIO()=0;
epicsShareFunc virtual int readOP();
void destroyIfReadOP();
caServer *getCAS() const;
inline void destroy();
void reportInvalidAsynchIO(unsigned);
protected:
casCoreClient &client;
casAsyncIO &ioExternal;
void lock();
void unlock();
private:
unsigned inTheEventQueue:1;
@@ -326,110 +252,24 @@ private:
unsigned ioComplete:1;
unsigned serverDelete:1;
unsigned duplicate:1;
//
// casEvent virtual call back function
// (called when IO completion event reaches top of event queue)
//
epicsShareFunc caStatus cbFunc(casEventSys &);
inline casAsyncIO * operator -> ();
//
// derived class specic call back
// (called when IO completion event reaches top of event queue)
//
epicsShareFunc virtual caStatus cbFuncAsyncIO() = 0;
epicsShareFunc virtual void destroy ();
epicsShareFunc virtual bool readOP() const;
};
//
// casAsyncRdIOI
//
// (server internal asynchronous read IO class)
//
class casAsyncRdIOI : public casAsyncIOI {
public:
epicsShareFunc casAsyncRdIOI(const casCtx &ctx, casAsyncReadIO &ioIn);
virtual ~casAsyncRdIOI();
void destroyIfReadOP();
epicsShareFunc caStatus cbFuncAsyncIO();
casAsyncIO &getAsyncIO();
epicsShareFunc caStatus postIOCompletion(caStatus completionStatus,
gdd &valueRead);
epicsShareFunc int readOP();
private:
caHdr const msg;
casChannelI &chan;
smartGDDPointer pDD;
caStatus completionStatus;
};
//
// casAsyncWtIOI
//
// (server internal asynchronous write IO class)
//
class casAsyncWtIOI : public casAsyncIOI {
public:
epicsShareFunc casAsyncWtIOI(const casCtx &ctx, casAsyncWriteIO &ioIn);
virtual ~casAsyncWtIOI();
//
// place notification of IO completion on the event queue
//
epicsShareFunc caStatus postIOCompletion(caStatus completionStatus);
epicsShareFunc caStatus cbFuncAsyncIO();
casAsyncIO &getAsyncIO();
private:
caHdr const msg;
casChannelI &chan;
caStatus completionStatus;
};
class casDGIntfIO;
//
// casAsyncExIOI
//
// (server internal asynchronous PV exist test IO class)
//
class casAsyncExIOI : public casAsyncIOI {
public:
epicsShareFunc casAsyncExIOI(const casCtx &ctx, casAsyncPVExistIO &ioIn);
virtual ~casAsyncExIOI();
//
// place notification of IO completion on the event queue
//
epicsShareFunc caStatus postIOCompletion(const pvExistReturn &retVal);
epicsShareFunc caStatus cbFuncAsyncIO();
casAsyncIO &getAsyncIO();
private:
caHdr const msg;
pvExistReturn retVal;
casDGIntfIO * const pOutDGIntfIO;
const caNetAddr dgOutAddr;
};
//
// casAsyncAtIOI
//
// (server internal asynchronous PV attach IO class)
//
class casAsyncAtIOI : public casAsyncIOI {
public:
epicsShareFunc casAsyncAtIOI(const casCtx &ctx, casAsyncPVAttachIO &ioIn);
virtual ~casAsyncAtIOI();
//
// place notification of IO completion on the event queue
//
epicsShareFunc caStatus postIOCompletion(const pvAttachReturn &retVal);
epicsShareFunc caStatus cbFuncAsyncIO();
casAsyncIO &getAsyncIO();
private:
caHdr const msg;
pvAttachReturn retVal;
};
class casDGClient;
class casChannel;
class casPVI;
@@ -443,31 +283,31 @@ class casPVI;
class casChannelI : public tsDLNode<casChannelI>, public casRes,
public casEvent {
public:
casChannelI (const casCtx &ctx, casChannel &chanAdapter);
casChannelI (const casCtx &ctx);
virtual ~casChannelI();
casCoreClient &getClient() const
casCoreClient &getClient () const
{
return this->client;
}
const caResId getCID()
const caResId getCID ()
{
return this->cid;
}
//
// fetch the unsigned integer server id for this PV
//
inline const caResId getSID();
const caResId getSID ();
//
// addMonitor()
//
inline void addMonitor(casMonitor &mon);
void addMonitor (casMonitor &mon);
//
// deleteMonitor()
//
inline void deleteMonitor(casMonitor &mon);
void deleteMonitor (casMonitor &mon);
//
// findMonitor
@@ -475,48 +315,54 @@ public:
// sane clients will require only one or two monitors
// per channel)
//
inline casMonitor *findMonitor(const caResId clientIdIn);
casMonitor *findMonitor (const caResId clientIdIn);
casPVI &getPVI() const
casPVI &getPVI () const
{
return this->pv;
}
inline void installAsyncIO(casAsyncIOI &);
inline void removeAsyncIO(casAsyncIOI &);
void installAsyncIO (casAsyncIOI &);
void removeAsyncIO (casAsyncIOI &);
inline void postEvent (const casEventMask &select, gdd &event);
void postEvent (const casEventMask &select, gdd &event);
epicsShareFunc virtual casResType resourceType() const;
epicsShareFunc virtual casResType resourceType () const;
virtual void show (unsigned level) const;
void lock () const;
void unlock () const;
virtual void destroy();
void destroyNoClientNotify ();
void destroyClientNotify ();
inline void lock() const;
inline void unlock() const;
inline void clientDestroy();
inline casChannel * operator -> () const;
void clearOutstandingReads();
void clearOutstandingReads ();
//
// access rights event call back
//
epicsShareFunc caStatus cbFunc(casEventSys &);
epicsShareFunc caStatus cbFunc (casEventSys &);
void postAccessRightsEvent ();
//
// virtual functions
//
epicsShareFunc virtual void setOwner (const char * const pUserName,
const char * const pHostName) = 0;
epicsShareFunc virtual bool readAccess () const = 0;
epicsShareFunc virtual bool writeAccess () const = 0;
epicsShareFunc virtual bool confirmationRequested () const = 0;
epicsShareFunc virtual void show (unsigned level) const;
inline void postAccessRightsEvent();
protected:
tsDLList<casMonitor> monitorList;
tsDLList<casAsyncIOI> ioInProgList;
casCoreClient &client;
casPVI &pv;
casChannel &chan;
tsDLList<casMonitor> monitorList;
tsDLList<casAsyncIOI> ioInProgList;
casCoreClient &client;
casPVI &pv;
caResId const cid; // client id
unsigned clientDestroyPending:1;
unsigned accessRightsEvPending:1;
unsigned accessRightsEvPending:1;
epicsShareFunc virtual void destroy ();
};
//
@@ -525,7 +371,7 @@ protected:
class casPVListChan : public casChannelI, public tsDLNode<casPVListChan>
{
public:
casPVListChan (const casCtx &ctx, casChannel &chanAdapter);
casPVListChan (const casCtx &ctx);
virtual ~casPVListChan();
};
@@ -538,84 +384,95 @@ class casPV;
// casPVI
//
class casPVI :
public tsSLNode<casPVI>, // server resource table installation
public casRes, // server resource table installation
public ioBlockedList // list of clients io blocked on this pv
public tsSLNode<casPVI>, // server resource table installation
public casRes, // server resource table installation
public ioBlockedList // list of clients io blocked on this pv
{
public:
casPVI (casPV &pvAdapter);
virtual ~casPVI();
//
// for use by the server library
//
inline caServerI *getPCAS() const;
//
// attach to a server
//
caStatus attachToServer (caServerI &cas);
//
// CA only does 1D arrays for now (and the new server
// temporarily does only scalars)
//
inline aitIndex nativeCount();
//
// only for use by casMonitor
//
caStatus registerEvent ();
void unregisterEvent ();
//
// only for use by casAsyncIOI
//
inline void unregisterIO();
//
// only for use by casChannelI
//
inline void installChannel(casPVListChan &chan);
//
// only for use by casChannelI
//
inline void removeChannel(casPVListChan &chan);
//
// check for none attached and delete self if so
//
inline void deleteSignal();
inline void postEvent (const casEventMask &select, gdd &event);
inline casPV *interfaceObjectPointer() const;
caServer *getExtServer() const;
//
// bestDBRType()
//
inline caStatus bestDBRType (unsigned &dbrType);
inline casPV * operator -> () const;
epicsShareFunc virtual casResType resourceType() const;
virtual void show(unsigned level) const;
virtual void destroy();
casPVI ();
virtual ~casPVI ();
//
// for use by the server library
//
caServerI *getPCAS () const;
//
// attach to a server
//
caStatus attachToServer (caServerI &cas);
//
// CA only does 1D arrays for now (and the new server
// temporarily does only scalars)
//
aitIndex nativeCount ();
//
// only for use by casMonitor
//
caStatus registerEvent ();
void unregisterEvent ();
//
// only for use by casAsyncIOI
//
void unregisterIO ();
//
// only for use by casChannelI
//
void installChannel (casPVListChan &chan);
//
// only for use by casChannelI
//
void removeChannel (casPVListChan &chan);
//
// check for none attached and delete self if so
//
void deleteSignal ();
void postEvent (const casEventMask &select, gdd &event);
caServer *getExtServer () const;
//
// bestDBRType()
//
caStatus bestDBRType (unsigned &dbrType);
epicsShareFunc virtual casResType resourceType () const;
//
// virtual functions in the public interface class
//
epicsShareFunc virtual void show (unsigned level) const;
epicsShareFunc virtual caStatus interestRegister () = 0;
epicsShareFunc virtual void interestDelete () = 0;
epicsShareFunc virtual caStatus beginTransaction () = 0;
epicsShareFunc virtual void endTransaction () = 0;
epicsShareFunc virtual caStatus read (const casCtx &ctx, gdd &prototype) = 0;
epicsShareFunc virtual caStatus write (const casCtx &ctx, gdd &value) = 0;
epicsShareFunc virtual casChannel *createChannel (const casCtx &ctx,
const char * const pUserName, const char * const pHostName) = 0;
epicsShareFunc virtual aitEnum bestExternalType () const = 0;
epicsShareFunc virtual unsigned maxDimension () const = 0;
epicsShareFunc virtual aitIndex maxBound (unsigned dimension) const = 0;
epicsShareFunc virtual const char *getName () const = 0;
epicsShareFunc casPV *apiPointer (); //retuns NULL if casPVI isnt a base of casPV
private:
tsDLList<casPVListChan> chanList;
caServerI *pCAS;
casPV &pv;
unsigned nMonAttached;
unsigned nIOAttached;
unsigned destroyInProgress:1;
tsDLList<casPVListChan> chanList;
caServerI *pCAS;
unsigned nMonAttached;
unsigned nIOAttached;
inline void lock () const;
inline void unlock () const;
inline void lock() const;
inline void unlock() const;
epicsShareFunc virtual void destroy (); // casPVI destructor noop
};
+11 -40
View File
@@ -27,35 +27,6 @@
* Argonne National Laboratory
*
*
* History
* $Log$
* Revision 1.9 1998/06/16 02:29:57 jhill
* use smart gdd ptr
*
* Revision 1.8 1997/05/05 04:50:11 jhill
* moved pLog = NULL down
*
* Revision 1.7 1997/04/10 19:34:12 jhill
* API changes
*
* Revision 1.6 1996/11/02 00:54:18 jhill
* many improvements
*
* Revision 1.5 1996/09/16 18:24:03 jhill
* vxWorks port changes
*
* Revision 1.4 1996/07/24 22:00:49 jhill
* added pushOnToEventQueue()
*
* Revision 1.3 1996/07/01 19:56:11 jhill
* one last update prior to first release
*
* Revision 1.2 1996/06/26 21:18:56 jhill
* now matches gdd api revisions
*
* Revision 1.1.1.1 1996/06/20 00:28:16 jhill
* ca server installation
*
*
*/
@@ -100,7 +71,7 @@ casMonitor::~casMonitor()
{
casCoreClient &client = this->ciu.getClient();
this->mutex.osiLock();
this->mutex.lock();
this->disable();
@@ -113,7 +84,7 @@ casMonitor::~casMonitor()
this->ciu.deleteMonitor(*this);
this->mutex.osiUnlock();
this->mutex.unlock();
}
//
@@ -123,8 +94,8 @@ void casMonitor::enable()
{
caStatus status;
this->mutex.osiLock();
if (!this->enabled && this->ciu->readAccess()) {
this->mutex.lock();
if (!this->enabled && this->ciu.readAccess()) {
this->enabled = TRUE;
status = this->ciu.getPVI().registerEvent();
if (status) {
@@ -132,7 +103,7 @@ void casMonitor::enable()
"Server tool failed to register event\n");
}
}
this->mutex.osiUnlock();
this->mutex.unlock();
}
//
@@ -140,12 +111,12 @@ void casMonitor::enable()
//
void casMonitor::disable()
{
this->mutex.osiLock();
this->mutex.lock();
if (this->enabled) {
this->enabled = FALSE;
this->ciu.getPVI().unregisterEvent();
}
this->mutex.osiUnlock();
this->mutex.unlock();
}
//
@@ -157,7 +128,7 @@ void casMonitor::push(gdd &newValue)
casMonEvent *pLog;
char full;
this->mutex.osiLock();
this->mutex.lock();
//
// get a new block if we havent exceeded quotas
@@ -209,7 +180,7 @@ void casMonitor::push(gdd &newValue)
client.addToEventQueue(*pLog);
this->mutex.osiUnlock();
this->mutex.unlock();
}
//
@@ -223,9 +194,9 @@ caStatus casMonitor::executeEvent(casMonEvent *pEV)
pVal = pEV->getValue ();
assert (pVal!=NULL);
this->mutex.osiLock();
this->mutex.lock();
status = this->callBack (*pVal);
this->mutex.osiUnlock();
this->mutex.unlock();
//
// if the event isnt accepted we will try
-206
View File
@@ -1,206 +0,0 @@
/*
* $Id$
*
* Author Jeffrey O. Hill
* johill@lanl.gov
* 505 665 1831
*
* Experimental Physics and Industrial Control System (EPICS)
*
* Copyright 1991, the Regents of the University of California,
* and the University of Chicago Board of Governors.
*
* This software was produced under U.S. Government contracts:
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
* and (W-31-109-ENG-38) at Argonne National Laboratory.
*
* Initial development by:
* The Controls and Automation Group (AT-8)
* Ground Test Accelerator
* Accelerator Technology Division
* Los Alamos National Laboratory
*
* Co-developed with
* The Controls and Computing Group
* Accelerator Systems Division
* Advanced Photon Source
* Argonne National Laboratory
*
*
* History
* $Log$
* Revision 1.5 1997/06/13 09:15:59 jhill
* connect proto changes
*
* Revision 1.4 1997/04/10 19:34:13 jhill
* API changes
*
* Revision 1.3 1996/11/02 00:54:19 jhill
* many improvements
*
* Revision 1.2 1996/09/16 18:24:04 jhill
* vxWorks port changes
*
* Revision 1.1.1.1 1996/06/20 00:28:15 jhill
* ca server installation
*
*
*/
#include"server.h"
class casMsgIO {
public:
casMsgIO();
virtual ~casMsgIO();
osiTime timeOfLastXmit() const;
osiTime timeOfLAstRecv() const;
//
// show status of IO subsystem
// (cant be const because a lock is taken)
//
void show (unsigned level) const;
//
// io independent send/recv
//
xSendStatus xSend (char *pBuf, bufSizeT nBytesAvailableToSend,
bufSizeT nBytesNeedToBeSent, bufSizeT &nBytesSent,
const caNetAddr &addr);
xRecvStatus xRecv (char *pBuf, bufSizeT nBytesToRecv,
bufSizeT &nByesRecv, caNetAddr &addr);
virtual bufSizeT incommingBytesPresent() const;
virtual casIOState state() const=0;
virtual void clientHostName (char *pBuf, unsigned bufSize) const =0;
virtual int getFD() const;
void setNonBlocking()
{
this->xSetNonBlocking();
this->blockingStatus = xIsntBlocking;
}
//
// The server's port number
// (to be used for connection requests)
//
virtual unsigned serverPortNumber()=0;
private:
//
// private data members
//
osiTime lastSendTS;
osiTime lastRecvTS;
xBlockingStatus blockingStatus;
virtual xSendStatus osdSend (const char *pBuf, bufSizeT nBytesReq,
bufSizeT &nBytesActual, const caNetAddr &addr) =0;
virtual xRecvStatus osdRecv (char *pBuf, bufSizeT nBytesReq,
bufSizeT &nBytesActual, caNetAddr &addr) =0;
virtual void osdShow (unsigned level) const = 0;
virtual void xSetNonBlocking();
};
casMsgIO::casMsgIO()
{
this->lastSendTS = this->lastRecvTS = osiTime::getCurrent ();
this->blockingStatus = xIsBlocking;
}
casMsgIO::~casMsgIO()
{
}
//
// casMsgIO::show(unsigned level) const
//
void casMsgIO::show(unsigned level) const
{
osiTime current;
double send_delay;
double recv_delay;
if (level>=1u) {
current = osiTime::getCurrent ();
send_delay = current - this->lastSendTS;
recv_delay = current - this->lastRecvTS;
printf(
"\tSecs since last send %6.2f, Secs since last receive %6.2f\n",
send_delay, recv_delay);
}
}
//
// casMsgIO::xRecv()
//
xRecvStatus casMsgIO::xRecv(char *pBuf, bufSizeT nBytes,
bufSizeT &nActualBytes, caNetAddr &from)
{
xRecvStatus stat;
stat = this->osdRecv(pBuf, nBytes, nActualBytes, from);
if (stat==xRecvOK) {
this->lastRecvTS = osiTime::getCurrent();
}
return stat;
}
//
// casMsgIO::xSend()
//
xSendStatus casMsgIO::xSend(char *pBuf, bufSizeT nBytesAvailableToSend,
bufSizeT nBytesNeedToBeSent, bufSizeT &nActualBytes,
const caNetAddr &to)
{
xSendStatus stat;
bufSizeT nActualBytesDelta;
assert (nBytesAvailableToSend>=nBytesNeedToBeSent);
nActualBytes = 0u;
if (this->blockingStatus == xIsntBlocking) {
stat = this->osdSend(pBuf, nBytesAvailableToSend,
nActualBytes, to);
if (stat == xSendOK) {
this->lastSendTS = osiTime::getCurrent();
}
return stat;
}
while (nBytesNeedToBeSent) {
stat = this->osdSend(pBuf, nBytesAvailableToSend,
nActualBytesDelta, to);
if (stat != xSendOK) {
return stat;
}
this->lastSendTS = osiTime::getCurrent();
nActualBytes += nActualBytesDelta;
if (nBytesNeedToBeSent>nActualBytesDelta) {
nBytesNeedToBeSent -= nActualBytesDelta;
}
else {
break;
}
}
return xSendOK;
}
int casMsgIO::getFD() const
{
return -1; // some os will not have file descriptors
}
void casMsgIO::xSetNonBlocking()
{
printf("virtual base casMsgIO::xSetNonBlocking() called?\n");
}
bufSizeT casMsgIO::incommingBytesPresent() const
{
return 0u;
}
+29 -56
View File
@@ -27,39 +27,8 @@
* Argonne National Laboratory
*
*
* History
* $Log$
* Revision 1.9 1998/06/18 00:09:09 jhill
* installed bwd compat casPV constructor
*
* Revision 1.8 1998/06/16 02:30:44 jhill
* allow PV to be created before the server
*
* Revision 1.7 1997/08/05 00:47:10 jhill
* fixed warnings
*
* Revision 1.6 1997/04/10 19:34:14 jhill
* API changes
*
* Revision 1.5 1996/12/06 22:34:22 jhill
* add maxDimension() and maxBound()
*
* Revision 1.4 1996/11/02 00:54:21 jhill
* many improvements
*
* Revision 1.3 1996/07/01 19:56:12 jhill
* one last update prior to first release
*
* Revision 1.2 1996/06/21 02:30:53 jhill
* solaris port
*
* Revision 1.1.1.1 1996/06/20 00:28:15 jhill
* ca server installation
*
*
*/
//
// Notes:
//
@@ -70,8 +39,7 @@
#include "casPVIIL.h" // casPVI inline func
#include "casCtxIL.h" // casCtx inline func
epicsShareFunc casPV::casPV () :
casPVI (*this)
epicsShareFunc casPV::casPV ()
{
}
@@ -79,8 +47,7 @@ epicsShareFunc casPV::casPV () :
// This constructor is preserved for backwards compatibility only.
// Please do _not_ use this constructor.
//
epicsShareFunc casPV::casPV (caServer &) :
casPVI (*this)
epicsShareFunc casPV::casPV (caServer &)
{
}
@@ -89,14 +56,23 @@ epicsShareFunc casPV::~casPV()
}
//
// casPV::show()
// casPV::destroy()
//
epicsShareFunc void casPV::show(unsigned level) const
// (this default action will _never_ be called while in the
// casPVI destructor)
//
void casPV::destroy ()
{
if (level>2u) {
printf ("casPV: Best external type = %d\n",
this->bestExternalType());
}
delete this;
}
//
// casPV::createChannel()
//
epicsShareFunc casChannel *casPV::createChannel (const casCtx &ctx, const char * const,
const char * const)
{
return new casChannel (ctx);
}
//
@@ -172,20 +148,11 @@ epicsShareFunc aitIndex casPV::maxBound(unsigned /* dimension */) const
}
//
// casPV::createChannel()
// casPV::show (unsigned level)
//
epicsShareFunc casChannel *casPV::createChannel (const casCtx &ctx, const char * const,
const char * const)
epicsShareFunc void casPV::show (unsigned level) const
{
return new casChannel (ctx);
}
//
// casPV::destroy()
//
epicsShareFunc void casPV::destroy()
{
delete this;
casPVI::show (level);
}
//
@@ -200,9 +167,7 @@ epicsShareFunc void casPV::postEvent (const casEventMask &select, gdd &event)
// Find the server associated with this PV
// ****WARNING****
// this returns NULL if the PV isnt currently installed
// into a server (this situation will exist only if
// the pv isnt deleted in a derived classes replacement
// for virtual casPV::destroy()
// into a server.
// ***************
//
epicsShareFunc caServer *casPV::getCAS() const
@@ -210,3 +175,11 @@ epicsShareFunc caServer *casPV::getCAS() const
return this->casPVI::getExtServer();
}
//
// casPV::apiPointer()
//
casPV *casPV::apiPointer ()
{
return this;
}
+40 -76
View File
@@ -26,40 +26,6 @@
* Advanced Photon Source
* Argonne National Laboratory
*
*
* History
* $Log$
* Revision 1.10 1998/06/16 02:31:36 jhill
* allow the PV to be created before the server
*
* Revision 1.9 1997/08/05 00:47:11 jhill
* fixed warnings
*
* Revision 1.8 1997/04/10 19:34:15 jhill
* API changes
*
* Revision 1.7 1996/12/12 18:55:38 jhill
* fixed client initiated pv delete calls interestDelete() VF bug
*
* Revision 1.6 1996/12/06 22:35:06 jhill
* added destroyInProgress flag
*
* Revision 1.5 1996/11/02 00:54:22 jhill
* many improvements
*
* Revision 1.4 1996/09/04 20:23:17 jhill
* init new member cas and add arg to serverToolDebug()
*
* Revision 1.3 1996/07/01 19:56:13 jhill
* one last update prior to first release
*
* Revision 1.2 1996/06/26 21:18:57 jhill
* now matches gdd api revisions
*
* Revision 1.1.1.1 1996/06/20 00:28:15 jhill
* ca server installation
*
*
*/
@@ -67,24 +33,16 @@
#include "casPVIIL.h" // casPVI inline func
#include "caServerIIL.h" // caServerI inline func
//
// casPVI::casPVI()
//
casPVI::casPVI (casPV &pvAdapterIn) :
pCAS(NULL), // initially there is no server attachment
pv(pvAdapterIn),
nMonAttached(0u),
nIOAttached(0u),
destroyInProgress(FALSE)
casPVI::casPVI () :
pCAS (NULL), // initially there is no server attachment
nMonAttached (0u),
nIOAttached (0u)
{
//
// this will always be true
//
assert (&this->pv!=NULL);
}
//
// casPVI::~casPVI()
//
@@ -99,9 +57,6 @@ casPVI::~casPVI()
this->pCAS->removeItem(*this);
assert (!this->destroyInProgress);
this->destroyInProgress = TRUE;
//
// delete any attached channels
//
@@ -113,7 +68,7 @@ casPVI::~casPVI()
tsDLIterBD<casPVListChan> tmp = iter;
++tmp;
(*iter)->destroy();
iter->destroyClientNotify ();
iter = tmp;
}
@@ -133,6 +88,17 @@ casPVI::~casPVI()
casVerify (this->nMonAttached==0u);
}
//
// casPVI::destroy()
//
// This version of destroy() is provided only because it can
// be safely calle din the casPVI destructor as a side effect
// of deleting the last channel.
//
void casPVI::destroy ()
{
}
//
// casPVI::attachToServer ()
//
@@ -158,19 +124,6 @@ caStatus casPVI::attachToServer (caServerI &cas)
return S_cas_success;
}
//
// casPVI::show()
//
void casPVI::show(unsigned level) const
{
if (level>1u) {
printf ("CA Server PV: nChanAttached=%u nMonAttached=%u nIOAttached=%u\n",
this->chanList.count(), this->nMonAttached, this->nIOAttached);
}
(*this)->show(level);
}
//
// casPVI::registerEvent()
//
@@ -181,7 +134,7 @@ caStatus casPVI::registerEvent ()
this->lock();
this->nMonAttached++;
if (this->nMonAttached==1u) {
status = (*this)->interestRegister();
status = this->interestRegister ();
}
else {
status = S_cas_success;
@@ -202,8 +155,8 @@ void casPVI::unregisterEvent()
// Dont call casPV::interestDelete() when we are in
// casPVI::~casPVI() (and casPV no longr exists)
//
if (this->nMonAttached==0u && !this->destroyInProgress) {
(*this)->interestDelete();
if (this->nMonAttached==0u) {
this->interestDelete();
}
this->unlock();
}
@@ -216,7 +169,7 @@ void casPVI::unregisterEvent()
caServer *casPVI::getExtServer() const
{
if (this->pCAS) {
return this->pCAS->getAdapter();;
return this->pCAS->getAdapter();
}
else {
return NULL;
@@ -224,19 +177,20 @@ caServer *casPVI::getExtServer() const
}
//
// casPVI::destroy()
// casPVI::show()
//
// call the destroy in the server tool
//
void casPVI::destroy()
epicsShareFunc void casPVI::show (unsigned level) const
{
//
// Flag that a server is no longer using this PV
//
this->pCAS = NULL;
this->pv.destroy();
if (level>1u) {
printf ("CA Server PV: nChanAttached=%u nMonAttached=%u nIOAttached=%u\n",
this->chanList.count(), this->nMonAttached, this->nIOAttached);
}
if (level>2u) {
printf ("\tBest external type = %d\n", this->bestExternalType());
}
}
//
// casPVI::resourceType()
//
epicsShareFunc casResType casPVI::resourceType() const
@@ -244,3 +198,13 @@ epicsShareFunc casResType casPVI::resourceType() const
return casPVT;
}
//
// casPVI::apiPointer()
// retuns NULL if casPVI isnt a base of casPV
//
epicsShareFunc casPV *casPVI::apiPointer ()
{
return NULL;
}
+11 -74
View File
@@ -27,51 +27,6 @@
* Argonne National Laboratory
*
*
* History
* $Log$
* Revision 1.13 1999/04/30 15:36:26 jhill
* better range check on index to gddAitToDbr
*
* Revision 1.12 1998/06/16 02:21:49 jhill
* dont require that a server must exist before a PV is created
*
* Revision 1.11 1997/08/05 00:47:12 jhill
* fixed warnings
*
* Revision 1.10 1997/04/10 19:34:16 jhill
* API changes
*
* Revision 1.9 1997/01/09 22:22:30 jhill
* MSC cannot use the default constructor
*
* Revision 1.8 1996/12/06 22:36:17 jhill
* use destroyInProgress flag now functional nativeCount()
*
* Revision 1.7.2.1 1996/11/25 16:31:55 jhill
* MSC cannot use the default constructor localCASRef(this->cas)
*
* Revision 1.7 1996/11/02 00:54:23 jhill
* many improvements
*
* Revision 1.6 1996/09/16 18:24:05 jhill
* vxWorks port changes
*
* Revision 1.5 1996/09/04 20:23:59 jhill
* added operator ->
*
* Revision 1.4 1996/07/01 19:56:13 jhill
* one last update prior to first release
*
* Revision 1.3 1996/06/26 21:18:58 jhill
* now matches gdd api revisions
*
* Revision 1.2 1996/06/21 02:30:55 jhill
* solaris port
*
* Revision 1.1.1.1 1996/06/20 00:28:16 jhill
* ca server installation
*
*
*/
@@ -88,25 +43,6 @@ inline caServerI *casPVI::getPCAS() const
return this->pCAS;
}
//
// casPVI::interfaceObjectPointer()
//
// casPVI must always be a base for casPV
// (the constructor assert fails if this isnt the case)
//
inline casPV *casPVI::interfaceObjectPointer() const
{
return &this->pv;
}
//
// casPVI::operator -> ()
//
casPV * casPVI::operator -> () const
{
return interfaceObjectPointer();
}
//
// casPVI::lock()
//
@@ -119,7 +55,7 @@ inline void casPVI::lock() const
// comment in casPVI::deleteSignal()
//
if (this->pCAS) {
this->pCAS->osiLock();
this->pCAS->lock();
}
else {
fprintf (stderr, "PV lock call when not attached to server?\n");
@@ -132,7 +68,7 @@ inline void casPVI::lock() const
inline void casPVI::unlock() const
{
if (this->pCAS) {
this->pCAS->osiUnlock();
this->pCAS->unlock();
}
else {
fprintf (stderr, "PV unlock call when not attached to server?\n");
@@ -191,16 +127,17 @@ inline void casPVI::deleteSignal()
// lock when we add a new channel (and the
// PV lock is realy the server's lock)
//
pLocalCAS->osiLock();
pLocalCAS->lock();
if (this->chanList.count()==0u && !this->destroyInProgress) {
(*this)->destroy();
if (this->chanList.count()==0u) {
this->pCAS = NULL;
this->destroy ();
//
// !! dont access self after destroy !!
//
}
pLocalCAS->osiUnlock();
pLocalCAS->unlock();
}
}
@@ -209,7 +146,7 @@ inline void casPVI::deleteSignal()
//
inline caStatus casPVI::bestDBRType (unsigned &dbrType)
{
unsigned bestAIT = (*this)->bestExternalType();
unsigned bestAIT = this->bestExternalType();
if (bestAIT<NELEMENTS(gddAitToDbr)&&bestAIT!=aitEnumInvalid) {
dbrType = gddAitToDbr[bestAIT];
@@ -253,12 +190,12 @@ inline void casPVI::postEvent (const casEventMask &select, gdd &event)
//
// CA only does 1D arrays for now
//
inline aitIndex casPVI::nativeCount()
inline aitIndex casPVI::nativeCount ()
{
if ((*this)->maxDimension()==0u) {
if (this->maxDimension()==0u) {
return 1u; // scalar
}
return (*this)->maxBound(0u);
return this->maxBound(0u);
}
#endif // casPVIIL_h
+2 -13
View File
@@ -28,16 +28,6 @@
* Argonne National Laboratory
*
*
* History
* $Log$
* Revision 1.2 1997/01/10 21:17:58 jhill
* code around gnu g++ inline bug when -O isnt used
*
* Revision 1.1 1996/12/06 22:36:18 jhill
* use destroyInProgress flag now functional nativeCount()
*
*
*
*/
#include "server.h"
@@ -50,9 +40,8 @@
//
// casPVListChan::casPVListChan()
//
casPVListChan::casPVListChan
(const casCtx &ctx, casChannel &chanAdapterIn) :
casChannelI(ctx, chanAdapterIn)
casPVListChan::casPVListChan (const casCtx &ctx) :
casChannelI(ctx)
{
this->pv.installChannel(*this);
}
+197 -345
View File
@@ -27,97 +27,6 @@
* Argonne National Laboratory
*
*
* History
* $Log$
* Revision 1.29 1999/05/07 23:07:11 jhill
* throw warning exception with get/put callback failure detail
*
* Revision 1.28 1999/04/30 15:46:54 jhill
* deal with situation where bounds on managed DD must be modified
*
* Revision 1.27 1998/12/19 00:04:52 jhill
* renamed createPV() to pvAttach()
*
* Revision 1.26 1998/10/28 23:51:01 jhill
* server nolonger throws exception when a poorly formed get/put call back
* request arrives. Instead a get/put call back response is sent which includes
* unsuccessful status
*
* Revision 1.25 1998/09/24 20:40:07 jhill
* o block if unable to get buffer space for the exception message
* o subtle changes related to properly dealing with situations where
* both the server tool and the client tool delete the same PV simultaneously
*
* Revision 1.24 1998/07/08 15:38:07 jhill
* fixed lost monitors during flow control problem
*
* Revision 1.23 1998/06/16 02:32:30 jhill
* use smart gdd ptr
*
* Revision 1.22 1998/05/05 16:32:17 jhill
* cleaned up file format
*
* Revision 1.21 1998/04/15 00:04:05 jhill
* cosmetic
*
* Revision 1.20 1998/04/14 23:51:10 jhill
* improved diagnostic
*
* Revision 1.19 1998/02/18 22:46:25 jhill
* improved message
*
* Revision 1.18 1997/08/05 00:47:13 jhill
* fixed warnings
*
* Revision 1.17 1997/06/30 22:54:28 jhill
* use %p with pointers
*
* Revision 1.16 1997/06/13 09:16:00 jhill
* connect proto changes
*
* Revision 1.15 1997/04/10 19:34:18 jhill
* API changes
*
* Revision 1.14 1996/12/12 18:56:27 jhill
* doc
*
* Revision 1.13 1996/12/11 01:03:52 jhill
* removed redundant bad client attach detect
*
* Revision 1.12 1996/12/06 22:36:22 jhill
* use destroyInProgress flag now functional nativeCount()
*
* Revision 1.11 1996/11/02 00:54:24 jhill
* many improvements
*
* Revision 1.10 1996/09/16 18:24:05 jhill
* vxWorks port changes
*
* Revision 1.9 1996/09/04 20:25:53 jhill
* use correct app type for exist test gdd, correct byte
* oder for mon mask, and efficient use of PV name gdd
*
* Revision 1.8 1996/08/05 23:22:57 jhill
* gddScaler => gddScalar
*
* Revision 1.7 1996/08/05 19:26:51 jhill
* doc
*
* Revision 1.5 1996/07/09 22:53:33 jhill
* init stat and sev in gdd
*
* Revision 1.4 1996/07/01 19:56:14 jhill
* one last update prior to first release
*
* Revision 1.3 1996/06/26 21:18:59 jhill
* now matches gdd api revisions
*
* Revision 1.2 1996/06/21 02:30:57 jhill
* solaris port
*
* Revision 1.1.1.1 1996/06/20 00:28:15 jhill
* ca server installation
*
*
*/
@@ -137,6 +46,70 @@
static const caHdr nill_msg = {0u,0u,0u,0u,0u,0u};
//
// casStrmClient::casStrmClient()
//
casStrmClient::casStrmClient (caServerI &serverInternal) :
casClient (serverInternal, 1)
{
this->lock();
this->ctx.getServer()->installClient (this);
this->pHostName = new char [1u];
if (!this->pHostName) {
throw S_cas_noMemory;
}
*this->pHostName = '\0';
this->pUserName = new char [1u];
if (!this->pUserName) {
free (this->pHostName);
throw S_cas_noMemory;
}
*this->pUserName= '\0';
this->unlock();
}
//
// casStrmClient::~casStrmClient()
//
casStrmClient::~casStrmClient()
{
this->lock();
//
// remove this from the list of connected clients
//
this->ctx.getServer()->removeClient(this);
if (this->pUserName) {
delete [] this->pUserName;
}
if (this->pHostName) {
delete [] this->pHostName;
}
//
// delete all channel attached
//
tsDLIterBD<casChannelI> iter(this->chanList.first());
while (iter!=tsDLIterBD<casChannelI>::eol()) {
//
// destroying the channel removes it from the list
//
tsDLIterBD<casChannelI> tmp = iter;
++tmp;
iter->destroyNoClientNotify();
iter = tmp;
}
this->unlock();
}
//
// casStrmClient::verifyRequest()
//
@@ -169,101 +142,10 @@ caStatus casStrmClient::verifyRequest (casChannelI *&pChan)
return ECA_NORMAL;
}
//
// casStrmClient::casStrmClient()
//
casStrmClient::casStrmClient(caServerI &serverInternal) :
inBuf(*(osiMutex *)this, casStreamIO::optimumBufferSize()),
outBuf(*(osiMutex *)this, casStreamIO::optimumBufferSize()),
casClient(serverInternal, *this, *this),
pUserName(NULL), pHostName(NULL)
{
this->ctx.getServer()->installClient(this);
}
//
// casStrmClient::init()
//
caStatus casStrmClient::init()
{
caStatus status;
//
// call base class initializers
//
status = casClient::init();
if (status) {
return status;
}
status = this->inBuf::init();
if (status) {
return status;
}
status = this->outBuf::init();
if (status) {
return status;
}
this->pHostName = new char [1u];
if (!this->pHostName) {
return S_cas_noMemory;
}
*this->pHostName = '\0';
this->pUserName = new char [1u];
if (!this->pUserName) {
return S_cas_noMemory;
}
*this->pUserName= '\0';
return this->start();
}
//
// casStrmClient::~casStrmClient()
//
casStrmClient::~casStrmClient()
{
this->osiLock();
//
// remove this from the list of connected clients
//
this->ctx.getServer()->removeClient(this);
if (this->pUserName) {
delete [] this->pUserName;
}
if (this->pHostName) {
delete [] this->pHostName;
}
//
// delete all channel attached
//
tsDLIterBD<casChannelI> iter(this->chanList.first());
while (iter!=tsDLIterBD<casChannelI>::eol()) {
//
// destroying the channel removes it from the list
//
tsDLIterBD<casChannelI> tmp = iter;
++tmp;
iter->clientDestroy();
iter = tmp;
}
this->osiUnlock();
}
//
// find the monitor associated with a resource id
//
inline casClientMon *caServerI::resIdToClientMon(const caResId &idIn)
inline casClientMon *caServerI::resIdToClientMon (const caResId &idIn)
{
casRes *pRes;
@@ -275,7 +157,6 @@ inline casClientMon *caServerI::resIdToClientMon(const caResId &idIn)
return (casClientMon *) pRes;
}
//
// casStrmClient::show (unsigned level)
//
@@ -309,7 +190,7 @@ caStatus casStrmClient::readAction ()
/*
* verify read access
*/
if ((*pChan)->readAccess()!=aitTrue) {
if (pChan->readAccess()!=aitTrue) {
int v41;
v41 = CA_V41(CA_PROTOCOL_VERSION,this->minor_version_number);
@@ -340,8 +221,6 @@ caStatus casStrmClient::readAction ()
return status;
}
//
// casStrmClient::readResponse()
//
@@ -382,7 +261,7 @@ caStatus casStrmClient::readResponse (casChannelI *pChan, const caHdr &msg,
if (mapDBRStatus<0) {
desc.dump();
errPrintf (S_cas_badBounds, __FILE__, __LINE__, "- get notify with PV=%s type=%u count=%u",
pChan->getPVI()->getName(), msg.m_type, msg.m_count);
pChan->getPVI().getName(), msg.m_type, msg.m_count);
return this->sendErrWithEpicsStatus(&msg, S_cas_badBounds, ECA_GETFAIL);
}
#ifdef CONVERSION_REQUIRED
@@ -408,7 +287,6 @@ caStatus casStrmClient::readResponse (casChannelI *pChan, const caHdr &msg,
return localStatus;
}
//
// casStrmClient::readNotifyAction()
//
@@ -427,7 +305,7 @@ caStatus casStrmClient::readNotifyAction ()
//
// verify read access
//
if ((*pChan)->readAccess()!=aitTrue) {
if (pChan->readAccess()!=aitTrue) {
if (CA_V41(CA_PROTOCOL_VERSION, this->minor_version_number)) {
return this->readNotifyResponseECA_XXX (NULL, *mp, NULL, ECA_NORDACCESS);
}
@@ -545,7 +423,7 @@ caStatus casStrmClient::readNotifyResponseECA_XXX (casChannelI *pChan,
if (mapDBRStatus<0) {
pDesc->dump();
errPrintf (S_cas_badBounds, __FILE__, __LINE__, "- get notify with PV=%s type=%u count=%u",
pChan->getPVI()->getName(), msg.m_type, msg.m_count);
pChan->getPVI().getName(), msg.m_type, msg.m_count);
reply->m_cid = ECA_GETFAIL;
}
else {
@@ -637,7 +515,7 @@ caStatus casStrmClient::monitorResponse(casChannelI &chan, const caHdr &msg,
//
// verify read access
//
if (!chan->readAccess()) {
if (!chan.readAccess()) {
completionStatusCopy = S_cas_noRead;
}
@@ -722,8 +600,6 @@ caStatus casStrmClient::monitorResponse(casChannelI &chan, const caHdr &msg,
return S_cas_success;
}
/*
* casStrmClient::writeAction()
*/
@@ -741,7 +617,7 @@ caStatus casStrmClient::writeAction()
//
// verify write access
//
if ((*pChan)->writeAccess()!=aitTrue) {
if (pChan->writeAccess()!=aitTrue) {
int v41;
v41 = CA_V41(CA_PROTOCOL_VERSION,this->minor_version_number);
@@ -818,7 +694,7 @@ caStatus casStrmClient::writeNotifyAction()
//
// verify write access
//
if ((*pChan)->writeAccess()!=aitTrue) {
if (pChan->writeAccess()!=aitTrue) {
if (CA_V41(CA_PROTOCOL_VERSION,this->minor_version_number)) {
return this->casStrmClient::writeNotifyResponseECA_XXX(
*mp, ECA_NOWTACCESS);
@@ -941,7 +817,7 @@ caStatus casStrmClient::hostNameAction()
size-1);
pMalloc[size-1]='\0';
this->osiLock();
this->lock();
if (this->pHostName) {
delete [] this->pHostName;
@@ -950,16 +826,15 @@ caStatus casStrmClient::hostNameAction()
tsDLIterBD<casChannelI> iter(this->chanList.first());
while ( iter!=tsDLIterBD<casChannelI>::eol() ) {
(*iter)->setOwner(this->pUserName, this->pHostName);
iter->setOwner(this->pUserName, this->pHostName);
++iter;
}
this->osiUnlock();
this->unlock();
return S_cas_success;
}
/*
* casStrmClient::clientNameAction()
*/
@@ -990,7 +865,7 @@ caStatus casStrmClient::clientNameAction()
size-1);
pMalloc[size-1]='\0';
this->osiLock();
this->lock();
if (this->pUserName) {
delete [] this->pUserName;
@@ -999,16 +874,14 @@ caStatus casStrmClient::clientNameAction()
tsDLIterBD<casChannelI> iter(this->chanList.first());
while ( iter!=tsDLIterBD<casChannelI>::eol() ) {
(*iter)->setOwner(this->pUserName, this->pHostName);
iter->setOwner(this->pUserName, this->pHostName);
++iter;
}
this->osiUnlock();
this->unlock();
return S_cas_success;
}
/*
* casStrmClientMon::claimChannelAction()
*/
@@ -1064,7 +937,7 @@ caStatus casStrmClient::claimChannelAction()
// prevent problems such as the PV being deleted before the
// channel references it
//
this->osiLock();
this->lock();
this->asyncIOFlag = 0u;
//
@@ -1092,7 +965,7 @@ caStatus casStrmClient::claimChannelAction()
else {
status = this->createChanResponse(*mp, pvar);
}
this->osiUnlock();
this->unlock();
return status;
}
@@ -1107,12 +980,12 @@ caStatus casStrmClient::createChanResponse(const caHdr &hdr, const pvAttachRetur
casChannel *pChan;
casChannelI *pChanI;
caHdr *claim_reply;
caHdr *dummy;
unsigned dbrType;
bufSizeT nBytes;
caStatus status;
if (pvar.getStatus() != S_cas_success) {
return this->channelCreateFailed(&hdr, pvar.getStatus());
return this->channelCreateFailed (&hdr, pvar.getStatus());
}
pPV = pvar.getPV();
@@ -1122,7 +995,7 @@ caStatus casStrmClient::createChanResponse(const caHdr &hdr, const pvAttachRetur
// pv isnt in this server
//
if (pPV == NULL) {
return this->channelCreateFailed(&hdr, S_casApp_pvNotFound);
return this->channelCreateFailed (&hdr, S_casApp_pvNotFound);
}
//
@@ -1136,27 +1009,27 @@ caStatus casStrmClient::createChanResponse(const caHdr &hdr, const pvAttachRetur
//
// NOTE:
// We are allocating enough space for both the claim
// response and the access response so that we know for
// response and the access rights response so that we know for
// certain that they will both be sent together.
//
status = this->allocMsg (sizeof(caHdr), &dummy);
if (status) {
return status;
}
void *pRaw;
const outBufCtx outctx = this->outBuf::pushCtx
(0, 2*sizeof(caHdr), pRaw);
if (outctx.pushResult()!=outBufCtx::pushCtxSuccess) {
return S_cas_sendBlocked;
}
//
// create server tool XXX derived from casChannel
//
this->ctx.setPV(pPV);
pChan = (*pPV)->createChannel(this->ctx,
this->pUserName, this->pHostName);
this->ctx.setPV (pPV);
pChan = pPV->createChannel (this->ctx, this->pUserName, this->pHostName);
if (!pChan) {
pvar.getPV()->deleteSignal();
return this->channelCreateFailed(&hdr, S_cas_noMemory);
this->outBuf::popCtx (outctx);
pPV->deleteSignal();
return this->channelCreateFailed (&hdr, S_cas_noMemory);
}
this->osiUnlock();
pChanI = (casChannelI *) pChan;
//
@@ -1167,15 +1040,17 @@ caStatus casStrmClient::createChanResponse(const caHdr &hdr, const pvAttachRetur
//
status = casStrmClient::accessRightsResponse(pChanI);
if (status) {
this->outBuf::popCtx (outctx);
errMessage(status, "incompplete channel create?");
pChanI->clientDestroy();
pChanI->destroyNoClientNotify();
return this->channelCreateFailed(&hdr, status);
}
status = pPV->bestDBRType(dbrType);
if (status) {
this->outBuf::popCtx (outctx);
errMessage(status, "best external dbr type fetch failed");
pChanI->clientDestroy();
pChanI->destroyNoClientNotify();
return this->channelCreateFailed(&hdr, status);
}
@@ -1189,15 +1064,8 @@ caStatus casStrmClient::createChanResponse(const caHdr &hdr, const pvAttachRetur
// here to be certain that we are at the correct place in
// the protocol buffer.
//
// The 3rd arg indicates - dont lock the buffer again
//
status = this->allocMsg (0u, &claim_reply, FALSE);
//
// Not sending the access rights response and the claim
// response is a severe error which is avoided by
// the first (oversize) allocMsg
//
assert (status==S_cas_success);
status = this->allocMsg (0u, &claim_reply);
assert (status==S_cas_success);
*claim_reply = nill_msg;
claim_reply->m_cmmd = CA_PROTO_CLAIM_CIU;
@@ -1205,16 +1073,18 @@ caStatus casStrmClient::createChanResponse(const caHdr &hdr, const pvAttachRetur
claim_reply->m_count = pPV->nativeCount();
claim_reply->m_cid = hdr.m_cid;
claim_reply->m_available = pChanI->getSID();
this->commitMsg();
//
// Unlock the buffer (and convert it to network format
//
this->commitMsg();
//
// commit the message
//
nBytes = this->outBuf::popCtx (outctx);
assert ( nBytes == 2*sizeof(caHdr) );
this->outBuf::commitRawMsg (nBytes);
return status;
}
/*
* casStrmClient::channelCreateFailed()
*
@@ -1259,7 +1129,6 @@ caStatus createStatus)
return createStatus;
}
/*
* casStrmClient::disconnectChan()
*
@@ -1293,8 +1162,6 @@ caStatus casStrmClient::disconnectChan(caResId id)
return createStatus;
}
//
// casStrmClient::eventsOnAction()
//
@@ -1312,8 +1179,6 @@ caStatus casStrmClient::eventsOffAction()
return this->casEventSys::eventsOff();
}
//
// eventAddAction()
//
@@ -1339,15 +1204,15 @@ caStatus casStrmClient::eventAddAction ()
//
caProtoMask = ntohs (pMonInfo->m_mask);
if (caProtoMask&DBE_VALUE) {
mask |= this->getCAS().getAdapter()->valueEventMask;
mask |= this->getCAS().valueEventMask();
}
if (caProtoMask&DBE_LOG) {
mask |= this->getCAS().getAdapter()->logEventMask;
mask |= this->getCAS().logEventMask();
}
if (caProtoMask&DBE_ALARM) {
mask |= this->getCAS().getAdapter()->alarmEventMask;
mask |= this->getCAS().alarmEventMask();
}
if (mask.noEventsSelected()) {
@@ -1362,7 +1227,7 @@ caStatus casStrmClient::eventAddAction ()
// to postpone asynchronous IO we can safely restart this
// request later.
//
status = this->read(pDD);
status = this->read (pDD);
//
// always send immediate monitor response at event add
//
@@ -1384,7 +1249,7 @@ caStatus casStrmClient::eventAddAction ()
// there isnt pool space for a gdd then delete
// (disconnect) the channel
//
(*pciu)->destroy();
pciu->destroyClientNotify ();
return S_cas_success;
}
else {
@@ -1402,7 +1267,7 @@ caStatus casStrmClient::eventAddAction ()
// If we cant allocate space for a monitor then
// delete (disconnect) the channel
//
(*pciu)->destroy();
pciu->destroyClientNotify ();
}
return status;
}
@@ -1412,7 +1277,6 @@ caStatus casStrmClient::eventAddAction ()
}
//
// casStrmClient::clearChannelAction()
//
@@ -1463,7 +1327,7 @@ caStatus casStrmClient::clearChannelAction ()
// space for the response
//
if (pciu) {
pciu->clientDestroy ();
pciu->destroyNoClientNotify ();
}
*reply = *mp;
@@ -1473,8 +1337,6 @@ caStatus casStrmClient::clearChannelAction ()
}
//
// casStrmClient::eventCancelAction()
//
@@ -1535,7 +1397,6 @@ caStatus casStrmClient::eventCancelAction ()
return S_cas_success;
}
#if 0
/*
* casStrmClient::noReadAccessEvent()
@@ -1590,7 +1451,6 @@ caStatus casStrmClient::noReadAccessEvent(casClientMon *pMon)
}
#endif
//
// casStrmClient::readSyncAction()
//
@@ -1606,13 +1466,13 @@ caStatus casStrmClient::readSyncAction()
// any pending asynchronous IO associated with
// a read.
//
this->osiLock();
this->lock();
tsDLIterBD<casChannelI> iter(this->chanList.first());
while ( iter!=tsDLIterBD<casChannelI>::eol() ) {
iter->clearOutstandingReads();
++iter;
}
this->osiUnlock();
this->unlock();
status = this->allocMsg(0u, &reply);
if(status){
@@ -1626,8 +1486,6 @@ caStatus casStrmClient::readSyncAction()
return S_cas_success;
}
//
// casStrmClient::accessRightsResponse()
//
@@ -1637,42 +1495,41 @@ caStatus casStrmClient::readSyncAction()
//
caStatus casStrmClient::accessRightsResponse(casChannelI *pciu)
{
caHdr *reply;
unsigned ar;
int v41;
int status;
/*
* noop if this is an old client
*/
v41 = CA_V41(CA_PROTOCOL_VERSION, this->minor_version_number);
if(!v41){
return S_cas_success;
}
ar = 0; /* none */
if ((*pciu)->readAccess()) {
ar |= CA_PROTO_ACCESS_RIGHT_READ;
}
if ((*pciu)->writeAccess()) {
ar |= CA_PROTO_ACCESS_RIGHT_WRITE;
}
status = this->allocMsg(0u, &reply);
if(status){
return status;
}
*reply = nill_msg;
reply->m_cmmd = CA_PROTO_ACCESS_RIGHTS;
reply->m_cid = pciu->getCID();
reply->m_available = ar;
this->commitMsg();
return S_cas_success;
caHdr *reply;
unsigned ar;
int v41;
int status;
/*
* noop if this is an old client
*/
v41 = CA_V41(CA_PROTOCOL_VERSION, this->minor_version_number);
if(!v41){
return S_cas_success;
}
ar = 0; /* none */
if (pciu->readAccess()) {
ar |= CA_PROTO_ACCESS_RIGHT_READ;
}
if (pciu->writeAccess()) {
ar |= CA_PROTO_ACCESS_RIGHT_WRITE;
}
status = this->allocMsg(0u, &reply);
if(status){
return status;
}
*reply = nill_msg;
reply->m_cmmd = CA_PROTO_ACCESS_RIGHTS;
reply->m_cid = pciu->getCID();
reply->m_available = ar;
this->commitMsg();
return S_cas_success;
}
//
// casStrmClient::write()
//
@@ -1701,7 +1558,7 @@ caStatus casStrmClient::write()
//
// the PV state must not be modified during a transaction
//
status = (*pPV)->beginTransaction();
status = pPV->beginTransaction();
if (status) {
return status;
}
@@ -1741,12 +1598,11 @@ caStatus casStrmClient::write()
"- expected asynch IO creation from casPV::write()");
}
(*pPV)->endTransaction();
pPV->endTransaction();
return status;
}
//
// casStrmClient::writeScalarData()
//
@@ -1807,7 +1663,7 @@ caStatus casStrmClient::writeScalarData()
//
// call the server tool's virtual function
//
status = (*this->ctx.getPV())->write(this->ctx, *pDD);
status = this->ctx.getPV()->write(this->ctx, *pDD);
return status;
}
@@ -1891,7 +1747,7 @@ caStatus casStrmClient::writeArrayData()
//
// call the server tool's virtual function
//
status = (*this->ctx.getPV())->write(this->ctx, *pDD);
status = this->ctx.getPV()->write(this->ctx, *pDD);
return status;
}
@@ -1918,7 +1774,7 @@ caStatus casStrmClient::read(smartGDDPointer &pDescRet)
//
// the PV state must not be modified during a transaction
//
status = (*this->ctx.getPV())->beginTransaction();
status = this->ctx.getPV()->beginTransaction();
if (status) {
return status;
}
@@ -1931,7 +1787,7 @@ caStatus casStrmClient::read(smartGDDPointer &pDescRet)
//
// call the server tool's virtual function
//
status = (*this->ctx.getPV())->read(this->ctx, *pDescRet);
status = this->ctx.getPV()->read(this->ctx, *pDescRet);
//
// prevent problems when they initiate
@@ -1956,7 +1812,7 @@ caStatus casStrmClient::read(smartGDDPointer &pDescRet)
pDescRet = NULL;
}
(*this->ctx.getPV())->endTransaction();
this->ctx.getPV()->endTransaction();
return status;
}
@@ -2119,9 +1975,9 @@ const char *casStrmClient::hostName() const
//
// caServerI::roomForNewChannel()
//
inline aitBool caServerI::roomForNewChannel() const
inline bool caServerI::roomForNewChannel() const
{
return aitTrue;
return true;
}
//
@@ -2129,10 +1985,10 @@ inline aitBool caServerI::roomForNewChannel() const
//
void casStrmClient::installChannel(casChannelI &chan)
{
this->osiLock();
this->lock();
this->getCAS().installItem (chan);
this->chanList.add(chan);
this->osiUnlock();
this->unlock();
}
//
@@ -2142,75 +1998,71 @@ void casStrmClient::removeChannel(casChannelI &chan)
{
casRes *pRes;
this->osiLock();
this->lock();
pRes = this->getCAS().removeItem(chan);
assert (&chan == (casChannelI *)pRes);
this->chanList.remove(chan);
this->osiUnlock();
this->unlock();
}
//
// casStrmClient::xSend()
//
xSendStatus casStrmClient::xSend(char *pBufIn, bufSizeT nBytesAvailableToSend,
outBuf::flushCondition casStrmClient::xSend (char *pBufIn, bufSizeT nBytesAvailableToSend,
bufSizeT nBytesNeedToBeSent, bufSizeT &nActualBytes)
{
xSendStatus stat;
outBuf::flushCondition stat;
bufSizeT nActualBytesDelta;
bufSizeT totalBytes;
assert (nBytesAvailableToSend>=nBytesNeedToBeSent);
nActualBytes = 0u;
if (this->blockingState() == xIsntBlocking) {
//
// !! this time fetch may be slowing things down !!
//
stat = this->osdSend(pBufIn, nBytesAvailableToSend,
nActualBytes);
if (stat == xSendOK) {
this->lastSendTS = osiTime::getCurrent();
}
return stat;
}
nActualBytes = 0u;
totalBytes = 0u;
while (TRUE) {
stat = this->osdSend(&pBufIn[nActualBytes],
nBytesAvailableToSend, nActualBytesDelta);
if (stat != xSendOK) {
return stat;
stat = this->osdSend (&pBufIn[totalBytes],
nBytesAvailableToSend-totalBytes, nActualBytesDelta);
if (stat != outBuf::flushProgress) {
if (totalBytes>0) {
nActualBytes = totalBytes;
//
// !! this time fetch may be slowing things down !!
//
//this->lastSendTS = osiTime::getCurrent();
return outBuf::flushProgress;
}
else {
return stat;
}
}
//
// !! this time fetch may be slowing things down !!
//
this->lastSendTS = osiTime::getCurrent();
nActualBytes += nActualBytesDelta;
totalBytes += nActualBytesDelta;
if (nBytesNeedToBeSent <= nActualBytesDelta) {
break;
if (totalBytes>=nBytesNeedToBeSent) {
//
// !! this time fetch may be slowing things down !!
//
//this->lastSendTS = osiTime::getCurrent();
nActualBytes = totalBytes;
return outBuf::flushProgress;
}
nBytesAvailableToSend -= nActualBytesDelta;
nBytesNeedToBeSent -= nActualBytesDelta;
}
return xSendOK;
}
//
// casStrmClient::xRecv()
//
xRecvStatus casStrmClient::xRecv(char *pBufIn, bufSizeT nBytes,
bufSizeT &nActualBytes)
inBuf::fillCondition casStrmClient::xRecv(char *pBufIn, bufSizeT nBytes,
enum inBuf::fillParameter, bufSizeT &nActualBytes)
{
xRecvStatus stat;
inBuf::fillCondition stat;
stat = this->osdRecv(pBufIn, nBytes, nActualBytes);
if (stat==xRecvOK) {
stat = this->osdRecv (pBufIn, nBytes, nActualBytes);
//if (stat==casFillProgress) {
//
// !! this time fetch may be slowing things down !!
//
this->lastRecvTS = osiTime::getCurrent();
}
//this->lastRecvTS = osiTime::getCurrent();
//}
return stat;
}
+159 -159
View File
@@ -40,17 +40,8 @@
#include "gdd.h" // EPICS data descriptors
#include "shareLib.h" // EPICS compiler specific sharable lib keywords
//
// This eliminates a warning resulting from passing *this
// to a base class during derived class construction.
//
#if defined(_MSC_VER)
# pragma warning (disable:4355)
#endif
typedef aitUint32 caStatus;
/*
* ===========================================================
* for internal use by the server library
@@ -88,6 +79,8 @@ typedef aitUint32 caStatus;
#define S_cas_badBounds (M_cas | 30) /*server tool changed bounds on request*/
#define S_cas_pvAlreadyAttached (M_cas | 31) /*PV attached to another server*/
#define S_cas_badRequest (M_cas | 32) /*client's request was invalid*/
#define S_cas_invalidAsynchIO (M_cas | 33) /*inappropriate asynchronous IO type*/
/*
* ===========================================================
* returned by the application (to the server library)
@@ -147,7 +140,7 @@ public:
return *this;
}
pvExistReturnEnum getStatus() const {return this->status;}
int addrIsValid() const {return this->address.isSock();}
int addrIsValid() const {return this->address.isValid();}
caNetAddr getAddr() const {return this->address;}
private:
pvExistReturnEnum status;
@@ -251,6 +244,8 @@ class caServerI;
//
class caServer {
private:
friend class casPVI;
//
// this private data member appears first so that
// initialization of the constant event masks below
@@ -259,24 +254,12 @@ private:
// We do not use private inheritance here in order
// to avoid os/io dependent -I during server tool compile
//
caServerI *pCAS;
caServerI *pCAS;
public:
epicsShareFunc caServer (unsigned pvCountEstimate=1024u);
epicsShareFunc virtual ~caServer() = 0;
//caStatus enableClients ();
//caStatus disableClients ();
epicsShareFunc void setDebugLevel (unsigned level);
epicsShareFunc unsigned getDebugLevel ();
epicsShareFunc casEventMask registerEvent (const char *pName);
//
// show()
//
epicsShareFunc virtual void show (unsigned level) const;
//
// pvExistTest()
//
@@ -353,20 +336,6 @@ public:
epicsShareFunc virtual pvAttachReturn pvAttach (const casCtx &ctx,
const char *pPVAliasName);
//
// common event masks
// (what is currently used by the CA clients)
//
const casEventMask valueEventMask; // DBE_VALUE
const casEventMask logEventMask; // DBE_LOG
const casEventMask alarmEventMask; // DBE_ALARM
//
// this is only used by casPVI::casPVI() too convert from
// caServer to a caServerI
//
friend class casPVI;
//
// createPV() (deprecated)
// The virtual member function "createPV" will be deleted in a
@@ -375,6 +344,31 @@ public:
//
epicsShareFunc virtual pvCreateReturn createPV (const casCtx &ctx,
const char *pPVAliasName);
//
// obtain an event mask for a named event type
// to be used with casPV::postEvent()
//
epicsShareFunc casEventMask registerEvent (const char *pName);
//
// common event masks
// (what is currently used by the CA clients)
//
epicsShareFunc casEventMask valueEventMask() const; // DBE_VALUE
epicsShareFunc casEventMask logEventMask() const; // DBE_LOG
epicsShareFunc casEventMask alarmEventMask() const; // DBE_ALARM
epicsShareFunc void setDebugLevel (unsigned level);
epicsShareFunc unsigned getDebugLevel () const;
//
// show()
//
epicsShareFunc virtual void show (unsigned level) const;
//caStatus enableClients ();
//caStatus disableClients ();
};
//
@@ -567,6 +561,9 @@ public:
// pointer returned must remain valid for the life time
// o fthe process variable
//
//
// !! not thread safe !!
//
epicsShareFunc virtual const char *getName() const = 0;
//
@@ -582,14 +579,19 @@ public:
epicsShareFunc caServer *getCAS() const;
//
// only used when caStrmClient converts between
// casPV * and casPVI *
// only used when caStrmClient converts from
// casPV * to casPVI *
//
friend class casStrmClient;
private:
casPV *apiPointer (); //retruns NULL if casPVI isnt a base of casPV
public:
//
// This constructor is preserved for backwards compatibility only.
// Please do _not_ use this constructor.
// This constructor has been depricated, and is preserved for
// backwards compatibility only. Please do not use it.
//
epicsShareFunc casPV (caServer &);
};
@@ -618,32 +620,32 @@ public:
//
class casChannel : private casPVListChan {
public:
epicsShareFunc casChannel(const casCtx &ctx);
epicsShareFunc casChannel (const casCtx &ctx);
epicsShareFunc virtual ~casChannel();
//
// Called when the user name and the host name are changed
// for a live connection.
//
epicsShareFunc virtual void setOwner(const char * const pUserName,
epicsShareFunc virtual void setOwner (const char * const pUserName,
const char * const pHostName);
//
// the following are encouraged to change during an channel's
// lifetime
//
epicsShareFunc virtual aitBool readAccess () const;
epicsShareFunc virtual aitBool writeAccess () const;
epicsShareFunc virtual bool readAccess () const;
epicsShareFunc virtual bool writeAccess () const;
// return true to hint that the opi should ask the operator
// for confirmation prior writing to this PV
epicsShareFunc virtual aitBool confirmationRequested () const;
epicsShareFunc virtual bool confirmationRequested () const;
//
// This is called for each channel in the server if
// caServer::show() is called and the level is high
// enough
//
epicsShareFunc virtual void show(unsigned level) const;
epicsShareFunc virtual void show (unsigned level) const;
//
// destroy() is called when
@@ -653,13 +655,13 @@ public:
//
// the casChannel::destroy() executes a "delete this"
//
epicsShareFunc virtual void destroy();
epicsShareFunc virtual void destroy ();
//
// server tool calls this to indicate change in access
// rights has occurred
//
epicsShareFunc void postAccessRightsEvent();
epicsShareFunc void postAccessRightsEvent ();
//
// Find the PV associated with this channel
@@ -670,7 +672,7 @@ public:
// for virtual casChannel::destroy()
// ***************
//
epicsShareFunc casPV *getPV();
epicsShareFunc casPV *getPV ();
//
// only used when casStrmClient converts between
@@ -684,12 +686,12 @@ public:
//
// The following virtual functions allow for asynchronous completion:
//
// Virtual Function Asynchronous IO Class
// ----------------- ---------------------
// caServer::pvExistTest() casAsyncPVExistIO
// caServer::pvAttach() casAsyncPVAttachIO
// casPV::read() casAsyncReadIO
// casPV::write() casAsyncWriteIO
// Virtual Function Asynchronous IO Class
// ----------------- ---------------------
// caServer::pvExistTest() casAsyncPVExistIO
// caServer::pvAttach() casAsyncPVAttachIO
// casPV::read() casAsyncReadIO
// casPV::write() casAsyncWriteIO
//
// To initiate asynchronous completion create a corresponding
// asynchronous IO object from within one of the virtual
@@ -702,14 +704,14 @@ public:
// Deletion Responsibility
// -------- --------------
// o the server lib will not call "delete" directly for any
// casAsyncIO created by the server tool because we dont know
// casAsyncXxxIO created by the server tool because we dont know
// that "new" was called to create the object.
// o The server tool is responsible for reclaiming storage for any
// casAsyncIO it creates. The destroy virtual function will
// casAsyncXxxxIO it creates. The destroy virtual function will
// assist the server tool with this responsibility. The
// virtual function casAsyncIO::destroy() does a "delete this".
// o Avoid deleting the casAsyncIO immediately after calling
// postIOCompletion(). Instead proper operation requires that
// virtual function casAsyncXxxxIO::destroy() does a "delete this".
// o Avoid deleting the async IO object immediately after calling
// postIOCompletion(). Instead, proper operation requires that
// the server tool wait for the server lib to call destroy after
// the response is successfully queued to the client
// o If for any reason the server tool needs to cancel an IO
@@ -717,33 +719,10 @@ public:
// S_casApp_canceledAsyncIO. Deleting the asynchronous io
// object prior to its being allowed to forward an IO termination
// message to the client will result in NO IO CALL BACK TO THE
// CLIENT PROGRAM (in this situation a warning message will be printed by
// the server lib).
// CLIENT PROGRAM (in this situation a warning message will be
// printed by the server lib).
//
//
// casAsyncIO
//
// this class implements a common virtual destroy for
// all of the asynchronous IO classes
//
class casAsyncIO {
public:
//
// force virtual destructor
//
epicsShareFunc virtual ~casAsyncIO() = 0;
//
// called by the server lib after the response message
// is succesfully queued to the client or when the
// IO operation is canceled (client disconnects etc).
//
// default destroy executes a "delete this".
//
epicsShareFunc virtual void destroy();
};
//
// casAsyncReadIO
// - for use with casPV::read()
@@ -758,29 +737,21 @@ public:
// in the destructor, for the class deriving from
// casAsyncReadIO.
// **
class casAsyncReadIO : public casAsyncIO, private casAsyncRdIOI {
class casAsyncReadIO : private casAsyncIOI {
public:
//
// casAsyncReadIO()
//
epicsShareFunc casAsyncReadIO(const casCtx &ctx) :
casAsyncRdIOI(ctx, *this) {}
//
// force virtual destructor
//
epicsShareFunc virtual ~casAsyncReadIO();
epicsShareFunc casAsyncReadIO (const casCtx &ctx);
epicsShareFunc virtual ~casAsyncReadIO ();
//
// place notification of IO completion on the event queue
// (this function does not delete the casAsyncIO object).
// (this function does not delete the casAsyncReadIO object).
// Only the first call to this function has any effect.
//
epicsShareFunc caStatus postIOCompletion(caStatus completionStatusIn, gdd &valueRead)
{
return this->casAsyncRdIOI::postIOCompletion (
completionStatusIn, valueRead);
}
epicsShareFunc caStatus postIOCompletion (caStatus completionStatusIn, gdd &valueRead);
//
// Find the server associated with this async IO
@@ -789,10 +760,25 @@ public:
// into a server
// ***************
//
epicsShareFunc caServer *getCAS() const
{
return this->casAsyncRdIOI::getCAS();
}
epicsShareFunc caServer *getCAS () const;
//
// called by the server lib after the response message
// is succesfully queued to the client or when the
// IO operation is canceled (client disconnects etc).
//
// default destroy executes a "delete this".
//
epicsShareFunc virtual void destroy ();
private:
caHdr const msg;
casChannelI &chan;
smartGDDPointer pDD;
caStatus completionStatus;
epicsShareFunc bool readOP() const;
epicsShareFunc caStatus cbFuncAsyncIO();
};
//
@@ -810,28 +796,20 @@ public:
// casAsyncWriteIO.
// **
//
class casAsyncWriteIO : public casAsyncIO, private casAsyncWtIOI {
class casAsyncWriteIO : private casAsyncIOI {
public:
//
// casAsyncWriteIO()
//
epicsShareFunc casAsyncWriteIO(const casCtx &ctx) :
casAsyncWtIOI(ctx, *this) {}
//
// force virtual destructor
//
epicsShareFunc virtual ~casAsyncWriteIO();
epicsShareFunc casAsyncWriteIO (const casCtx &ctx);
epicsShareFunc virtual ~casAsyncWriteIO ();
//
// place notification of IO completion on the event queue
// (this function does not delete the casAsyncIO object).
// (this function does not delete the casAsyncWriteIO object).
// Only the first call to this function has any effect.
//
epicsShareFunc caStatus postIOCompletion(caStatus completionStatusIn)
{
return this->casAsyncWtIOI::postIOCompletion (completionStatusIn);
}
epicsShareFunc caStatus postIOCompletion (caStatus completionStatusIn);
//
// Find the server associated with this async IO
@@ -840,38 +818,44 @@ public:
// into a server
// ***************
//
epicsShareFunc caServer *getCAS() const
{
return this->casAsyncWtIOI::getCAS();
}
epicsShareFunc caServer *getCAS () const;
//
// called by the server lib after the response message
// is succesfully queued to the client or when the
// IO operation is canceled (client disconnects etc).
//
// default destroy executes a "delete this".
//
epicsShareFunc virtual void destroy ();
private:
caHdr const msg;
casChannelI &chan;
caStatus completionStatus;
epicsShareFunc caStatus cbFuncAsyncIO ();
};
//
// casAsyncPVExistIO
// - for use with caServer::pvExistTest()
//
class casAsyncPVExistIO : public casAsyncIO, private casAsyncExIOI {
class casAsyncPVExistIO : private casAsyncIOI {
public:
//
// casAsyncPVExistIO()
//
epicsShareFunc casAsyncPVExistIO(const casCtx &ctx) :
casAsyncExIOI(ctx, *this) {}
//
// force virtual destructor
//
epicsShareFunc virtual ~casAsyncPVExistIO();
epicsShareFunc casAsyncPVExistIO (const casCtx &ctx);
epicsShareFunc virtual ~casAsyncPVExistIO ();
//
// place notification of IO completion on the event queue
// (this function does not delete the casAsyncIO object).
// (this function does not delete the casAsyncPVExistIO object).
// Only the first call to this function has any effect.
//
epicsShareFunc caStatus postIOCompletion(const pvExistReturn &retValIn)
{
return this->casAsyncExIOI::postIOCompletion (retValIn);
}
epicsShareFunc caStatus postIOCompletion (const pvExistReturn &retValIn);
//
// Find the server associated with this async IO
@@ -880,38 +864,43 @@ public:
// into a server
// ***************
//
epicsShareFunc caServer *getCAS() const
{
return this->casAsyncExIOI::getCAS();
}
epicsShareFunc caServer *getCAS() const;
//
// called by the server lib after the response message
// is succesfully queued to the client or when the
// IO operation is canceled (client disconnects etc).
//
// default destroy executes a "delete this".
//
epicsShareFunc virtual void destroy();
private:
caHdr const msg;
pvExistReturn retVal;
const caNetAddr dgOutAddr;
epicsShareFunc caStatus cbFuncAsyncIO();
};
//
// casAsyncPVAttachIO
// - for use with caServer::pvAttach()
//
class casAsyncPVAttachIO : public casAsyncIO, private casAsyncAtIOI {
class casAsyncPVAttachIO : private casAsyncIOI {
public:
//
// casAsyncPVAttachIO()
//
epicsShareFunc casAsyncPVAttachIO (const casCtx &ctx) :
casAsyncAtIOI(ctx, *this) {}
//
// force virtual destructor
//
epicsShareFunc virtual ~casAsyncPVAttachIO();
epicsShareFunc casAsyncPVAttachIO (const casCtx &ctx);
epicsShareFunc virtual ~casAsyncPVAttachIO ();
//
// place notification of IO completion on the event queue
// (this function does not delete the casAsyncIO object).
// (this function does not delete the casAsyncPVAttachIO object).
// Only the first call to this function has any effect.
//
epicsShareFunc caStatus postIOCompletion(const pvAttachReturn &retValIn)
{
return this->casAsyncAtIOI::postIOCompletion (retValIn);
}
epicsShareFunc caStatus postIOCompletion (const pvAttachReturn &retValIn);
//
// Find the server associated with this async IO
@@ -920,20 +909,31 @@ public:
// into a server
// ***************
//
epicsShareFunc caServer *getCAS() const
{
return this->casAsyncAtIOI::getCAS();
}
epicsShareFunc caServer *getCAS() const;
//
// called by the server lib after the response message
// is succesfully queued to the client or when the
// IO operation is canceled (client disconnects etc).
//
// default destroy executes a "delete this".
//
epicsShareFunc virtual void destroy ();
private:
caHdr const msg;
pvAttachReturn retVal;
epicsShareFunc caStatus cbFuncAsyncIO ();
};
//
// casAsyncPVCreateIO (deprecated)
// (this class will be deleted in a future release)
//
class casAsyncPVCreateIO : public casAsyncPVAttachIO {
class casAsyncPVCreateIO : private casAsyncPVAttachIO {
public:
epicsShareFunc casAsyncPVCreateIO(const casCtx &ctx) :
casAsyncPVAttachIO (ctx) {}
epicsShareFunc casAsyncPVCreateIO(const casCtx &ctx);
epicsShareFunc virtual ~casAsyncPVCreateIO();
};
-55
View File
@@ -1,58 +1,3 @@
#include "server.h"
#include "inBufIL.h"
//
// this needs to be here (and not in dgInBufIL.h) if we
// are to avoid undefined symbols under gcc 2.7.x without -O
//
// dgInBuf::dgInBuf ()
//
dgInBuf::dgInBuf (osiMutex &mutexIn, unsigned bufSizeIn) :
inBuf(mutexIn, bufSizeIn)
{
}
//
// dgInBuf::~dgInBuf()
// (force virtual constructor)
//
dgInBuf::~dgInBuf()
{
}
//
// this needs to be here (and not in dgInBufIL.h) if we
// are to avoid undefined symbols under gcc 2.7.x without -O
//
// dgInBuf::hasAddress()
//
int dgInBuf::hasAddress() const
{
return this->from.isSock();
}
//
// dgInBuf::xRecv ()
//
xRecvStatus dgInBuf::xRecv (char *pBufIn, bufSizeT nBytesToRecv,
bufSizeT &nByesRecv)
{
caNetAddr addr;
xRecvStatus stat;
stat = this->xDGRecv (pBufIn, nBytesToRecv, nByesRecv, addr);
if (stat == xRecvOK) {
this->from = addr;
}
return stat;
}
//
// dgInBuf::getSender()
//
caNetAddr dgInBuf::getSender() const
{
return this->from;
}
-9
View File
@@ -4,14 +4,5 @@
#include "inBufIL.h"
//
// dgInBuf::clear()
//
inline void dgInBuf::clear()
{
this->from.clear();
this->inBuf::clear();
}
#endif // dgInBufILh
-69
View File
@@ -1,69 +0,0 @@
#include "server.h"
#include "outBufIL.h"
//
// this needs to be here (and not in dgInBufIL.h) if we
// are to avoid undefined symbols under gcc 2.7.x when
// -O is not used
//
// dgOutBuf::dgOutBuf ()
//
dgOutBuf::dgOutBuf (osiMutex &mutexIn, unsigned bufSizeIn) :
outBuf(mutexIn, bufSizeIn)
{
}
//
// dgOutBuf::~dgOutBuf()
// (force virtual destructor)
//
dgOutBuf::~dgOutBuf()
{
}
//
// dgOutBuf::xSend()
//
xSendStatus dgOutBuf::xSend (char *pBufIn,
bufSizeT nBytesAvailableToSend, bufSizeT nBytesNeedToBeSent,
bufSizeT &nBytesSent)
{
assert(nBytesAvailableToSend>=nBytesNeedToBeSent);
return xDGSend(pBufIn, nBytesAvailableToSend, nBytesSent, this->to);
}
//
// this needs to be here (and not in dgInBufIL.h) if we
// are to avoid undefined symbols under gcc 2.7.x (without -O)
//
// dgOutBuf::clear()
//
void dgOutBuf::clear()
{
this->to.clear();
this->outBuf::clear();
}
//
// this needs to be here (and not in dgInBufIL.h) if we
// are to avoid undefined symbols under gcc 2.7.x (without -O)
//
// dgOutBuf::setRecipient()
//
void dgOutBuf::setRecipient(const caNetAddr &addr)
{
this->to = addr;
}
//
// this needs to be here (and not in dgInBufIL.h) if we
// are to avoid undefined symbols under gcc 2.7.x (without -O)
//
// dgOutBuf::getRecipient()
//
caNetAddr dgOutBuf::getRecipient()
{
return this->to;
}
-13
View File
@@ -1,13 +0,0 @@
#ifndef dgOutBufILh
#define dgOutBufILh
#include "outBufIL.h"
//
// All of the functions in this file moved to dgOutBuf.cc because
// of inline problems with g++ 2.7.2 (without -O)
//
#endif // dgOutBufILh
+96 -51
View File
@@ -26,59 +26,68 @@
* Advanced Photon Source
* Argonne National Laboratory
*
*
* History
* $Log$
* Revision 1.1.1.1 1996/06/20 00:28:15 jhill
* ca server installation
*
*
*/
#include "server.h"
#include "inBufIL.h" // inBuf in line func
//
// inBuf::inBuf()
//
inBuf::inBuf (bufSizeT bufSizeIn, bufSizeT ioMinSizeIn) :
bufSize (bufSizeIn), ioMinSize (ioMinSizeIn),
bytesInBuffer (0u), nextReadIndex (0u),
ctxRecursCount (0u)
{
if (this->ioMinSize==0) {
this->ioMinSize = 1;
}
assert (this->bufSize>this->ioMinSize);
this->pBuf = new char [this->bufSize];
if (!this->pBuf) {
this->bufSize = 0u;
throw S_cas_noMemory;
}
}
//
// inBuf::~inBuf()
// (virtual destructor)
//
inBuf::~inBuf()
inBuf::~inBuf ()
{
if (this->pBuf) {
delete [] this->pBuf;
}
assert (this->ctxRecursCount==0);
delete [] this->pBuf;
}
//
// inBuf::show()
//
void inBuf::show(unsigned level) const
void inBuf::show (unsigned level) const
{
if (level>1u) {
printf(
"\tUnprocessed request bytes = %d\n",
this->bytesAvailable());
}
if (level>1u) {
printf(
"\tUnprocessed request bytes = %d\n",
this->bytesAvailable());
}
}
//
// inBuf::fill()
//
casFillCondition inBuf::fill()
inBuf::fillCondition inBuf::fill (fillParameter parm)
{
unsigned bytesReq;
unsigned bytesRecv;
xRecvStatus stat;
if (!this->pBuf) {
return casFillDisconnect;
}
bufSizeT bytesOpen;
bufSizeT bytesRecv;
inBuf::fillCondition stat;
//
// move back any prexisting data to the start of the buffer
//
if (this->nextReadIndex>0u) {
unsigned unprocessedBytes;
if ( this->nextReadIndex > 0 ) {
bufSizeT unprocessedBytes;
unprocessedBytes = this->bytesInBuffer - this->nextReadIndex;
//
// memmove() handles overlapping buffers
@@ -94,36 +103,72 @@ casFillCondition inBuf::fill()
//
// noop if the buffer is full
//
bytesReq = this->bufSize - this->bytesInBuffer;
if (bytesReq <= 0u) {
return casFillFull;
}
stat = this->xRecv(&this->pBuf[this->bytesInBuffer],
bytesReq, bytesRecv);
if (stat != xRecvOK) {
return casFillDisconnect;
}
if (bytesRecv==0u) {
bytesOpen = this->bufSize - this->bytesInBuffer;
if (bytesOpen < this->ioMinSize) {
return casFillNone;
}
assert (bytesRecv<=bytesReq);
this->bytesInBuffer += bytesRecv;
if (this->getDebugLevel()>2u) {
char buf[64];
stat = this->xRecv (&this->pBuf[this->bytesInBuffer],
bytesOpen, parm, bytesRecv);
if (stat == casFillProgress) {
assert (bytesRecv<=bytesOpen);
this->bytesInBuffer += bytesRecv;
this->clientHostName(buf, sizeof(buf));
if (this->getDebugLevel()>2u) {
char buf[64];
printf ("CAS: incomming %u byte msg from %s\n",
bytesRecv, buf);
this->clientHostName(buf, sizeof(buf));
printf ("CAS: incomming %u byte msg from %s\n",
bytesRecv, buf);
}
}
if (this->bufSize==this->bytesInBuffer) {
return casFillFull;
}
else {
return casFillPartial;
}
return stat;
}
//
// inBuf::pushCtx ()
//
const inBufCtx inBuf::pushCtx (bufSizeT headerSize, bufSizeT bodySize)
{
if (headerSize+bodySize>(this->bytesInBuffer - this->nextReadIndex) ||
this->ctxRecursCount==UINT_MAX) {
return inBufCtx ();
}
else {
inBufCtx result (*this);
bufSizeT effectiveNextReadIndex = this->nextReadIndex + headerSize;
this->pBuf = this->pBuf + effectiveNextReadIndex;
this->bytesInBuffer -= effectiveNextReadIndex;
this->nextReadIndex = 0;
this->bytesInBuffer = bodySize;
this->bufSize = this->bytesInBuffer;
this->ctxRecursCount++;
return result;
}
}
//
// inBuf::popCtx ()
//
bufSizeT inBuf::popCtx (const inBufCtx &ctx)
{
if (ctx.stat==inBufCtx::pushCtxSuccess) {
bufSizeT bytesRemoved = this->nextReadIndex;
this->pBuf = ctx.pBuf;
this->bufSize = ctx.bufSize;
this->bytesInBuffer = ctx.bytesInBuffer;
this->nextReadIndex = ctx.nextReadIndex;
assert (this->ctxRecursCount>0);
this->ctxRecursCount--;
this->mutex.unlock();
return bytesRemoved;
}
else {
return 0;
}
}
+32 -32
View File
@@ -2,32 +2,10 @@
#ifndef inBufILh
#define inBufILh
//
// inBuf::inBuf()
//
inline inBuf::inBuf(osiMutex &mutexIn, unsigned bufSizeIn) :
mutex(mutexIn), pBuf(NULL), bufSize(bufSizeIn),
bytesInBuffer(0u), nextReadIndex(0u)
{
}
//
// inBuf::init()
//
inline caStatus inBuf::init()
{
this->pBuf = new char [this->bufSize];
if (!this->pBuf) {
this->bufSize = 0u;
return S_cas_noMemory;
}
return S_cas_success;
}
//
// inBuf::bytesPresent()
//
inline bufSizeT inBuf::bytesPresent() const
inline bufSizeT inBuf::bytesPresent () const
{
return this->bytesInBuffer-this->nextReadIndex;
}
@@ -35,7 +13,7 @@ inline bufSizeT inBuf::bytesPresent() const
//
// inBuf::bytesAvailable()
//
inline bufSizeT inBuf::bytesAvailable() const
inline bufSizeT inBuf::bytesAvailable () const
{
bufSizeT bp;
bp = this->bytesPresent();
@@ -46,18 +24,18 @@ inline bufSizeT inBuf::bytesAvailable() const
//
// inBuf::full()
//
inline aitBool inBuf::full() const
inline bool inBuf::full () const
{
if (this->bytesPresent()>=this->bufSize) {
return aitTrue;
if (this->bufSize-this->bytesPresent()<this->ioMinSize) {
return true;
}
return aitFalse;
return false;
}
//
// inBuf::clear()
//
inline void inBuf::clear()
inline void inBuf::clear ()
{
this->bytesInBuffer = 0u;
this->nextReadIndex = 0u;
@@ -66,7 +44,7 @@ inline void inBuf::clear()
//
// inBuf::msgPtr()
//
inline char *inBuf::msgPtr() const
inline char *inBuf::msgPtr () const
{
return &this->pBuf[this->nextReadIndex];
}
@@ -74,10 +52,32 @@ inline char *inBuf::msgPtr() const
//
// inBuf::removeMsg()
//
inline void inBuf::removeMsg(unsigned nBytes)
inline void inBuf::removeMsg (bufSizeT nBytes)
{
this->nextReadIndex += nBytes;
assert(this->nextReadIndex<=this->bytesInBuffer);
assert (this->nextReadIndex<=this->bytesInBuffer);
}
//
// inBufCtx::inBufCtx ()
//
inline inBufCtx::inBufCtx () :
stat (pushCtxNoSpace) {}
//
// inBufCtx::inBufCtx ()
//
inline inBufCtx::inBufCtx (const inBuf &inBufIn) :
stat (pushCtxSuccess), pBuf (inBufIn.pBuf),
bufSize (inBufIn.bufSize), bytesInBuffer (inBufIn.bytesInBuffer),
nextReadIndex (inBufIn.nextReadIndex) {}
//
// inBufCtx::pushResult
//
inline inBufCtx::pushCtxResult inBufCtx::pushResult () const
{
return this->stat;
}
#endif // inBufILh
+123 -167
View File
@@ -27,27 +27,6 @@
* Argonne National Laboratory
*
*
* History
* $Log$
* Revision 1.6 1996/12/06 22:36:29 jhill
* use destroyInProgress flag now functional nativeCount()
*
* Revision 1.5 1996/11/02 00:54:30 jhill
* many improvements
*
* Revision 1.4 1996/09/16 18:24:07 jhill
* vxWorks port changes
*
* Revision 1.3 1996/09/04 20:27:01 jhill
* doccasdef.h
*
* Revision 1.2 1996/08/13 22:53:59 jhill
* fixed little endian problem
*
* Revision 1.1.1.1 1996/06/20 00:28:15 jhill
* ca server installation
*
*
*/
#include "server.h"
@@ -56,25 +35,14 @@
//
// outBuf::outBuf()
//
outBuf::outBuf(osiMutex &mutexIn, unsigned bufSizeIn) :
mutex(mutexIn),
pBuf(NULL),
bufSize(bufSizeIn),
stack(0u)
{
}
//
// outBuf::init()
//
caStatus outBuf::init()
outBuf::outBuf (unsigned bufSizeIn) :
bufSize (bufSizeIn), stack (0u), ctxRecursCount (0u)
{
this->pBuf = new char [this->bufSize];
if (!this->pBuf) {
return S_cas_noMemory;
throw S_cas_noMemory;
}
memset (this->pBuf, '\0', this->bufSize);
return S_cas_success;
}
//
@@ -82,86 +50,66 @@ caStatus outBuf::init()
//
outBuf::~outBuf()
{
if (this->pBuf) {
delete [] this->pBuf;
}
assert (this->ctxRecursCount==0);
delete [] this->pBuf;
}
//
// outBuf::allocMsg()
// outBuf::allocRawMsg ()
//
// allocates space in the outgoing message buffer
//
// (if space is avilable this leaves the send lock applied)
//
caStatus outBuf::allocMsg (
bufSizeT extsize, // extension size
caHdr **ppMsg,
int lockRequired
)
caStatus outBuf::allocRawMsg (bufSizeT msgsize, void **ppMsg)
{
bufSizeT msgsize;
bufSizeT stackNeeded;
extsize = CA_MESSAGE_ALIGN(extsize);
msgsize = CA_MESSAGE_ALIGN (msgsize);
msgsize = extsize + sizeof(caHdr);
if (msgsize>this->bufSize || this->pBuf==NULL) {
this->mutex.lock ();
if (msgsize>this->bufSize) {
this->mutex.unlock ();
return S_cas_hugeRequest;
}
stackNeeded = this->bufSize - msgsize;
//
// In some special situations we preallocate space for
// two messages and prefer not to lock twice
// (so that lock/unlock pairs will match)
//
if (lockRequired) {
this->mutex.osiLock();
}
if (this->stack > stackNeeded) {
/*
* Try to flush the output queue
*/
this->flush(casFlushSpecified, msgsize);
//
// Try to flush the output queue
//
this->flush (this->stack-stackNeeded);
/*
* If this failed then the fd is nonblocking
* and we will let select() take care of it
*/
//
// If this failed then the fd is nonblocking
// and we will let select() take care of it
//
if (this->stack > stackNeeded) {
this->mutex.osiUnlock();
this->mutex.unlock();
this->sendBlockSignal();
return S_cas_sendBlocked;
}
}
/*
* it fits so commitMsg() will move the stack pointer forward
*/
*ppMsg = (caHdr *) &this->pBuf[this->stack];
//
// it fits so commitMsg() will move the stack pointer forward
//
*ppMsg = (void *) &this->pBuf[this->stack];
return S_cas_success;
}
/*
* outBuf::commitMsg()
*/
//
// outBuf::commitMsg ()
//
void outBuf::commitMsg ()
{
caHdr *mp;
bufSizeT extSize;
bufSizeT diff;
ca_uint16_t diff;
ca_uint16_t extSize;
mp = (caHdr *) &this->pBuf[this->stack];
extSize = CA_MESSAGE_ALIGN(mp->m_postsize);
extSize = static_cast <ca_uint16_t> ( CA_MESSAGE_ALIGN (mp->m_postsize) );
//
// Guarantee that all portions of outgoing messages
@@ -169,133 +117,141 @@ void outBuf::commitMsg ()
//
diff = extSize - mp->m_postsize;
if (diff>0u) {
char *pExt = (char *) (mp+1);
memset(pExt + mp->m_postsize, '\0', diff);
memset ( reinterpret_cast<char *>(mp+1) + mp->m_postsize, '\0', diff );
}
mp->m_postsize = extSize;
if (this->getDebugLevel()) {
ca_printf (
"CAS Response => cmd=%d id=%x typ=%d cnt=%d psz=%d avail=%x outBuf ptr=%lx\n",
mp->m_cmmd,
mp->m_cid,
mp->m_type,
mp->m_count,
mp->m_postsize,
mp->m_available,
(long)mp);
mp->m_cmmd, mp->m_cid, mp->m_type, mp->m_count, mp->m_postsize,
mp->m_available, (long)mp);
}
/*
* convert to network byte order
* (data following header is handled elsewhere)
*/
//
// convert to network byte order
// (data following header is handled elsewhere)
//
mp->m_cmmd = htons (mp->m_cmmd);
mp->m_postsize = htons (mp->m_postsize);
mp->m_postsize = htons (extSize);
mp->m_type = htons (mp->m_type);
mp->m_count = htons (mp->m_count);
mp->m_cid = htonl (mp->m_cid);
mp->m_available = htonl (mp->m_available);
this->stack += sizeof(caHdr) + extSize;
assert (this->stack <= this->bufSize);
this->mutex.osiUnlock();
commitRawMsg (extSize + sizeof(*mp));
}
//
// outBuf::flush()
// outBuf::flush ()
//
casFlushCondition outBuf::flush(casFlushRequest req, bufSizeT spaceRequired)
outBuf::flushCondition outBuf::flush (bufSizeT spaceRequired)
{
bufSizeT nBytes;
bufSizeT stackNeeded;
bufSizeT nBytesNeeded;
xSendStatus stat;
casFlushCondition cond;
bufSizeT nBytesRequired;
flushCondition cond;
if (!this->pBuf) {
return casFlushDisconnect;
}
this->mutex.lock();
this->mutex.osiLock();
if (this->ctxRecursCount>0) {
this->mutex.unlock();
return flushNone;
}
if (req==casFlushAll) {
nBytesNeeded = this->stack;
if (spaceRequired>this->bufSize) {
nBytesRequired = this->stack;
}
else {
stackNeeded = this->bufSize - spaceRequired;
if (this->stack>stackNeeded) {
nBytesNeeded = this->stack - stackNeeded;
bufSizeT stackPermitted;
stackPermitted = this->bufSize - spaceRequired;
if (this->stack>stackPermitted) {
nBytesRequired = this->stack - stackPermitted;
}
else {
nBytesNeeded = 0u;
nBytesRequired = 0u;
}
}
if (nBytesNeeded==0u) {
this->mutex.osiUnlock();
return casFlushCompleted;
}
cond = this->xSend(this->pBuf, this->stack,
nBytesRequired, nBytes);
if (cond==flushProgress) {
bufSizeT len;
nBytes = 0u;
stat = this->xSend(this->pBuf, this->stack,
nBytesNeeded, nBytes);
if (stat == xSendOK) {
if (nBytes) {
bufSizeT len;
char buf[64];
if (nBytes >= this->stack) {
this->stack=0u;
cond = casFlushCompleted;
}
else {
len = this->stack-nBytes;
//
// memmove() is ok with overlapping buffers
//
memmove (this->pBuf, &this->pBuf[nBytes], len);
this->stack = len;
cond = casFlushPartial;
}
if (this->getDebugLevel()>2u) {
this->clientHostName(buf,sizeof(buf));
ca_printf(
"CAS: Sent a %d byte reply to %s\n",
nBytes, buf);
}
if (nBytes >= this->stack) {
this->stack = 0u;
}
else {
cond = casFlushNone;
len = this->stack-nBytes;
//
// memmove() is ok with overlapping buffers
//
memmove (this->pBuf, &this->pBuf[nBytes], len);
this->stack = len;
}
}
else {
cond = casFlushDisconnect;
}
this->mutex.osiUnlock();
if (this->getDebugLevel()>2u) {
char buf[64];
this->clientHostName (buf, sizeof(buf));
ca_printf ("CAS: Sent a %d byte reply to %s\n",
nBytes, buf);
}
}
this->mutex.unlock();
return cond;
}
//
// outBuf::show(unsigned level)
// outBuf::pushCtx ()
//
void outBuf::show(unsigned level) const
const outBufCtx outBuf::pushCtx (bufSizeT headerSize, bufSizeT maxBodySize, void *&pHeader)
{
if (level>1u) {
printf(
"\tUndelivered response bytes =%d\n",
this->bytesPresent());
}
bufSizeT totalSize = headerSize + maxBodySize;
caStatus status;
status = this->allocRawMsg (totalSize, &pHeader);
if (status!=S_cas_success) {
return outBufCtx ();
}
else if (this->ctxRecursCount==UINT_MAX) {
this->mutex.unlock();
return outBufCtx ();
}
else {
outBufCtx result (*this);
this->pBuf = this->pBuf + this->stack + headerSize;
this->stack = 0;
this->bufSize = maxBodySize;
this->ctxRecursCount++;
return result;
}
}
//
// outBuf::sendBlockSignal()
// outBuf::popCtx ()
//
void outBuf::sendBlockSignal()
bufSizeT outBuf::popCtx (const outBufCtx &ctx)
{
fprintf(stderr, "In virtula base sendBlockSignal() ?\n");
if (ctx.stat==outBufCtx::pushCtxSuccess) {
bufSizeT bytesAdded = this->stack;
this->pBuf = ctx.pBuf;
this->bufSize = ctx.bufSize;
this->stack = ctx.stack;
assert (this->ctxRecursCount>0u);
this->ctxRecursCount--;
return bytesAdded;
}
else {
return 0;
}
}
//
// outBuf::show (unsigned level)
//
void outBuf::show (unsigned level) const
{
if (level>1u) {
printf("\tUndelivered response bytes = %d\n", this->bytesPresent());
}
}
+65 -14
View File
@@ -3,29 +3,80 @@
#define outBufILh
//
// outBuf::bytesPresent()
// outBuf::bytesPresent ()
// number of bytes in the output queue
//
inline bufSizeT outBuf::bytesPresent() const
inline bufSizeT outBuf::bytesPresent () const
{
return this->stack;
//
// Note on use of lock here:
// This guarantees that any pushCtx() operation
// in progress completes before another thread checks.
//
this->mutex.lock ();
bufSizeT result = this->stack;
this->mutex.unlock ();
return result;
}
//
// outBuf::bytesFree()
// number of bytes unused in the output queue
// outBuf::clear ()
//
inline bufSizeT outBuf::bytesFree() const
{
return this->bufSize - this->stack;
}
//
// outBuf::clear()
//
inline void outBuf::clear()
inline void outBuf::clear ()
{
//
// Note on use of lock here:
// This guarantees that any pushCtx() operation
// in progress completes before another thread
// clears.
//
this->mutex.lock ();
this->stack = 0u;
this->mutex.unlock ();
}
//
// outBuf::allocMsg ()
//
// allocates space in the outgoing message buffer
//
// (if space is avilable this leaves the send lock applied)
//
inline caStatus outBuf::allocMsg (bufSizeT extsize, caHdr **ppMsg)
{
return this->allocRawMsg (extsize + sizeof(caHdr), (void **)ppMsg);
}
//
// outBuf::commitRawMsg()
//
inline void outBuf::commitRawMsg (bufSizeT size)
{
this->stack += size;
assert (this->stack <= this->bufSize);
this->mutex.unlock();
}
//
// outBufCtx::outBufCtx ()
//
inline outBufCtx::outBufCtx () :
stat (pushCtxNoSpace) {}
//
// outBufCtx::outBufCtx ()
//
inline outBufCtx::outBufCtx (const outBuf &outBufIn) :
stat (pushCtxSuccess), pBuf (outBufIn.pBuf),
bufSize (outBufIn.bufSize), stack (outBufIn.stack) {}
//
// outBufCtx::pushResult
//
inline outBufCtx::pushCtxResult outBufCtx::pushResult () const
{
return this->stat;
}
#endif // outBufILh
+270 -252
View File
@@ -78,11 +78,10 @@ void serverToolDebugFunc(const char *pFile, unsigned line, const char *pComment)
caStatus createDBRDD(unsigned dbrType, aitIndex dbrCount, smartGDDPointer &pDescRet);
caStatus copyBetweenDD(gdd &dest, gdd &src);
enum xRecvStatus {xRecvOK, xRecvDisconnect};
enum xSendStatus {xSendOK, xSendDisconnect};
enum xBlockingStatus {xIsBlocking, xIsntBlocking};
enum casIOState {casOnLine, casOffLine};
typedef unsigned bufSizeT;
static const unsigned bufSizeT_MAX = UINT_MAX;
enum casProcCond {casProcOk, casProcDisconnect};
@@ -115,51 +114,48 @@ class caServerI;
class casEventSys {
friend class casEventPurgeEv;
public:
inline casEventSys (casCoreClient &coreClientIn);
inline caStatus init();
casEventSys ();
virtual ~casEventSys();
virtual void destroy()=0;
void show (unsigned level) const;
casProcCond process ();
void show(unsigned level) const;
casProcCond process();
void installMonitor ();
void removeMonitor ();
void installMonitor();
void removeMonitor();
void removeFromEventQueue (casEvent &);
void addToEventQueue (casEvent &);
inline void removeFromEventQueue(casEvent &);
inline void addToEventQueue(casEvent &);
void insertEventQueue (casEvent &insert, casEvent &prevEvent);
void pushOnToEventQueue (casEvent &event);
inline void insertEventQueue(casEvent &insert, casEvent &prevEvent);
inline void pushOnToEventQueue(casEvent &event);
bool full ();
inline aitBool full();
casMonitor *resIdToMon (const caResId id);
inline casMonitor *resIdToMon(const caResId id);
bool getNDuplicateEvents () const;
inline casCoreClient &getCoreClient();
inline aitBool getNDuplicateEvents () const;
inline void setDestroyPending();
void setDestroyPending();
void eventsOn();
caStatus eventsOff();
virtual caStatus disconnectChan (caResId id) = 0;
private:
tsDLList<casEvent> eventLogQue;
osiMutex mutex;
casCoreClient &coreClient;
casEventPurgeEv *pPurgeEvent; // flow control purge complete event
unsigned numEventBlocks; // N event blocks installed
unsigned maxLogEntries; // max log entries
unsigned char destroyPending;
unsigned char replaceEvents; // replace last existing event on queue
unsigned char dontProcess; // flow ctl is on - dont process event queue
virtual void eventFlush () = 0;
virtual void eventSignal () = 0;
virtual casRes *lookupRes (const caResId &idIn, casResType type) = 0;
};
//
@@ -227,168 +223,188 @@ private:
unsigned nAsyncIO; // checks for improper use of async io
};
enum casFillCondition{
casFillNone,
casFillPartial,
casFillFull,
casFillDisconnect};
//
// inBufCtx
//
class inBufCtx {
friend class inBuf;
public:
enum pushCtxResult {pushCtxNoSpace, pushCtxSuccess};
inBufCtx (const inBuf &); // success
inBufCtx (); // failure
pushCtxResult pushResult () const;
private:
pushCtxResult stat;
char *pBuf;
bufSizeT bufSize;
bufSizeT bytesInBuffer;
bufSizeT nextReadIndex;
};
//
// inBuf
//
class inBuf {
friend class inBufCtx;
public:
//
// this needs to be here (and not in dgInBufIL.h) if we
// are to avoid undefined symbols under gcc 2.7.x without -O
//
inline inBuf(osiMutex &mutexIn, unsigned bufSizeIn);
inline caStatus init(); //constructor does not return status
virtual ~inBuf();
inline bufSizeT bytesPresent() const;
enum fillCondition {casFillNone, casFillProgress,
casFillDisconnect};
inline bufSizeT bytesAvailable() const ;
// this is a hack for a Solaris IP kernel feature
enum fillParameter {fpNone, fpUseBroadcastInterface};
inBuf (bufSizeT bufSizeIn, bufSizeT ioMinSizeIn);
virtual ~inBuf ();
bufSizeT bytesPresent () const;
bufSizeT bytesAvailable () const;
bool full () const;
//
// fill the input buffer with any incoming messages
//
fillCondition fill (enum fillParameter parm=fpNone);
void show (unsigned level) const;
inline aitBool full() const;
protected:
inline void clear();
void clear ();
char *msgPtr () const;
void removeMsg (bufSizeT nBytes);
inline char *msgPtr() const;
inline void removeMsg(unsigned nBytes);
//
// fill the input buffer with any incoming messages
//
casFillCondition fill ();
void show (unsigned level) const;
virtual unsigned getDebugLevel() const = 0;
virtual bufSizeT incommingBytesPresent() const = 0;
virtual xRecvStatus xRecv (char *pBuf, bufSizeT nBytesToRecv,
bufSizeT &nByesRecv) = 0;
virtual void clientHostName (char *pBuf,
unsigned bufSize) const = 0;
//
// This is used to create recursive protocol stacks. A subsegment
// of the buffer of max size "maxSize" is assigned to the next
// layer down in the protocol stack by pushCtx () until popCtx ()
// is called. The roiutine popCtx () returns the actual number
// of bytes used by the next layer down.
//
// pushCtx() returns an outBufCtx to be restored by popCtx()
//
const inBufCtx inBuf::pushCtx (bufSizeT headerSize, bufSizeT bodySize);
bufSizeT popCtx (const inBufCtx &); // returns actual size
private:
osiMutex &mutex;
char *pBuf;
bufSizeT bufSize;
bufSizeT bytesInBuffer;
bufSizeT nextReadIndex;
osiMutex mutex;
char *pBuf;
bufSizeT bufSize;
bufSizeT bytesInBuffer;
bufSizeT nextReadIndex;
bufSizeT ioMinSize;
unsigned ctxRecursCount;
virtual unsigned getDebugLevel () const = 0;
virtual bufSizeT incommingBytesPresent () const = 0;
virtual fillCondition xRecv (char *pBuf, bufSizeT nBytesToRecv,
enum inBuf::fillParameter parm, bufSizeT &nByesRecv) = 0;
virtual void clientHostName (char *pBuf, unsigned bufSize) const = 0;
};
//
// dgInBuf
// outBufCtx
//
class dgInBuf : public inBuf {
class outBufCtx {
friend class outBuf;
public:
dgInBuf (osiMutex &mutexIn, unsigned bufSizeIn);
virtual ~dgInBuf();
enum pushCtxResult {pushCtxNoSpace, pushCtxSuccess};
outBufCtx (const outBuf &); // success
outBufCtx (); // failure
inline void clear();
int hasAddress() const;
caNetAddr getSender() const;
xRecvStatus xRecv (char *pBufIn, bufSizeT nBytesToRecv,
bufSizeT &nByesRecv);
virtual xRecvStatus xDGRecv (char *pBuf, bufSizeT nBytesToRecv,
bufSizeT &nByesRecv, caNetAddr &sender) = 0;
pushCtxResult pushResult () const;
private:
caNetAddr from;
pushCtxResult stat;
char *pBuf;
bufSizeT bufSize;
bufSizeT stack;
};
//
// outBuf
//
enum casFlushCondition{
casFlushNone,
casFlushPartial,
casFlushCompleted,
casFlushDisconnect};
enum casFlushRequest{
casFlushAll,
casFlushSpecified};
class outBuf {
friend class outBufCtx;
public:
outBuf (osiMutex &, unsigned bufSizeIn);
caStatus init(); //constructor does not return status
virtual ~outBuf()=0;
inline bufSizeT bytesPresent() const;
enum flushCondition {flushNone, flushProgress, flushDisconnect};
inline bufSizeT bytesFree() const;
outBuf (bufSizeT bufSizeIn);
virtual ~outBuf ()=0;
bufSizeT bytesPresent() const;
//
// flush output queue
// (returns the number of bytes sent)
//
casFlushCondition flush(casFlushRequest req = casFlushAll,
bufSizeT spaceRequired=0u);
//
flushCondition flush (bufSizeT spaceRequired=bufSizeT_MAX);
void show (unsigned level) const;
protected:
//
// allocate message buffer space
// (leaves message buffer locked)
//
caStatus allocMsg (unsigned extsize, caHdr **ppMsg, int lockRequired=1);
caStatus allocMsg (bufSizeT extsize, caHdr **ppMsg);
//
// allocate message buffer space
// (leaves message buffer locked)
//
caStatus allocRawMsg (bufSizeT size, void **ppMsg);
//
// This is used to create recursive protocol stacks. A subsegment
// of the buffer of max size "maxSize" is assigned to the next
// layer down in the protocol stack by pushCtx () until popCtx ()
// is called. The roiutine popCtx () returns the actual number
// of bytes used by the next layer down.
//
// pushCtx() returns an outBufCtx to be restored by popCtx()
//
const outBufCtx pushCtx (bufSizeT headerSize, bufSizeT maxBodySize, void *&pHeader);
bufSizeT popCtx (const outBufCtx &); // returns actual size
//
// commits message allocated with allocMsg()
//
void commitMsg ();
void show(unsigned level) const;
//
// commits message allocated with allocRawMsg()
//
void commitRawMsg (bufSizeT size);
void clear ();
private:
osiMutex mutex;
char *pBuf;
bufSizeT bufSize;
bufSizeT stack;
unsigned ctxRecursCount;
virtual unsigned getDebugLevel() const = 0;
virtual void sendBlockSignal();
virtual void sendBlockSignal() = 0;
//
// io dependent
//
virtual xSendStatus xSend (char *pBuf, bufSizeT nBytesAvailableToSend,
virtual flushCondition xSend (char *pBuf, bufSizeT nBytesAvailableToSend,
bufSizeT nBytesNeedToBeSent, bufSizeT &nBytesSent) = 0;
virtual void clientHostName (char *pBuf, unsigned bufSize) const = 0;
inline void clear();
private:
osiMutex &mutex;
char *pBuf;
const bufSizeT bufSize;
bufSizeT stack;
};
//
// dgOutBuf
//
class dgOutBuf : public outBuf {
public:
dgOutBuf (osiMutex &mutexIn, unsigned bufSizeIn);
virtual ~dgOutBuf();
caNetAddr getRecipient();
void setRecipient(const caNetAddr &addr);
void clear();
xSendStatus xSend (char *pBufIn, bufSizeT nBytesAvailableToSend,
bufSizeT nBytesNeedToBeSent, bufSizeT &nBytesSent);
virtual xSendStatus xDGSend (char *pBuf, bufSizeT nBytesNeedToBeSent,
bufSizeT &nBytesSent, const caNetAddr &recipient) = 0;
private:
caNetAddr to;
};
//
// casCoreClient
// (this will eventually support direct communication
@@ -400,31 +416,26 @@ class casCoreClient : public osiMutex, public ioBlocked,
//
// allows casAsyncIOI constructor to check for asynch IO duplicates
//
friend casAsyncIOI::casAsyncIOI(casCoreClient &clientIn, casAsyncIO &ioExternalIn);
friend casAsyncIOI::casAsyncIOI(casCoreClient &clientIn);
public:
casCoreClient(caServerI &serverInternal);
caStatus init();
virtual ~casCoreClient();
virtual void destroy();
virtual caStatus disconnectChan(caResId id);
virtual void eventSignal() = 0;
virtual void eventFlush() = 0;
virtual caStatus start () = 0;
virtual void show (unsigned level) const;
virtual void installChannel (casChannelI &);
virtual void removeChannel (casChannelI &);
inline void installAsyncIO(casAsyncIOI &ioIn);
void installAsyncIO(casAsyncIOI &ioIn);
inline void removeAsyncIO(casAsyncIOI &ioIn);
void removeAsyncIO(casAsyncIOI &ioIn);
inline casRes *lookupRes(const caResId &idIn, casResType type);
casRes *lookupRes(const caResId &idIn, casResType type);
inline caServerI &getCAS() const;
caServerI &getCAS() const;
virtual caStatus monitorResponse(casChannelI &chan, const caHdr &msg,
virtual caStatus monitorResponse (casChannelI &chan, const caHdr &msg,
const gdd *pDesc, const caStatus status);
virtual caStatus accessRightsResponse(casChannelI *);
@@ -434,7 +445,7 @@ public:
// asynchronous completion
//
virtual caStatus asyncSearchResponse(
casDGIntfIO &outMsgIO, const caNetAddr &outAddr,
const caNetAddr &outAddr,
const caHdr &, const pvExistReturn &);
virtual caStatus createChanResponse(
const caHdr &, const pvAttachReturn &);
@@ -446,11 +457,10 @@ public:
virtual caStatus writeNotifyResponse (const caHdr &, const caStatus);
//
// The following are only used with async IO for
// DG clients
// used only with DG clients
//
virtual caNetAddr fetchRespAddr();
virtual casDGIntfIO* fetchOutIntf();
virtual caNetAddr fetchLastRecvAddr () const;
protected:
casCtx ctx;
unsigned char asyncIOFlag;
@@ -462,20 +472,19 @@ private:
//
// casClient
//
class casClient;
typedef caStatus (casClient::*pCASMsgHandler) ();
class casClient : public casCoreClient {
class casClient : public casCoreClient, public inBuf, public outBuf {
public:
casClient (caServerI &, inBuf &, outBuf &);
caStatus init(); //constructor does not return status
typedef caStatus (casClient::*pCASMsgHandler) ();
casClient (caServerI &, bufSizeT ioMinSizeIn);
virtual ~casClient ();
void show(unsigned level) const;
void show (unsigned level) const;
//
// send error response to a message
//
caStatus sendErr(const caHdr *, const int reportedStatus,
caStatus sendErr (const caHdr *, const int reportedStatus,
const char *pFormat, ...);
unsigned getMinorVersion() const {return this->minor_version_number;}
@@ -484,37 +493,27 @@ public:
//
// find the channel associated with a resource id
//
casChannelI *resIdToChannel(const caResId &id);
casChannelI *resIdToChannel (const caResId &id);
virtual void clientHostName (char *pBuf,
unsigned bufSize) const = 0;
virtual void clientHostName (char *pBuf, unsigned bufSize) const = 0;
protected:
unsigned minor_version_number;
osiTime lastSendTS;
osiTime lastRecvTS;
caStatus processMsg();
//
//
//
caStatus sendErrWithEpicsStatus(const caHdr *pMsg,
caStatus epicsStatus, caStatus clientStatus);
//
// logBadIdWithFileAndLineno()
//
# define logBadId(MP, DP, CACSTAT, RESID) \
this->logBadIdWithFileAndLineno(MP, DP, CACSTAT, __FILE__, __LINE__, RESID)
caStatus logBadIdWithFileAndLineno(const caHdr *mp,
const void *dp, const int cacStat, const char *pFileName,
const unsigned lineno, const unsigned resId);
caStatus processMsg();
private:
inBuf &inBufRef;
outBuf &outBufRef;
//
// dump message to stderr
@@ -557,16 +556,13 @@ private:
static int msgHandlersInit;
};
//
// casStrmClient
//
class casStrmClient : public inBuf, public outBuf, public casClient,
class casStrmClient : public casClient,
public tsDLNode<casStrmClient> {
public:
casStrmClient (caServerI &cas);
caStatus init(); //constructor does not return status
virtual ~casStrmClient();
void show (unsigned level) const;
@@ -596,9 +592,6 @@ public:
caStatus monitorResponse(casChannelI &chan, const caHdr &msg,
const gdd *pDesc, const caStatus status);
//
//
//
caStatus noReadAccessEvent(casClientMon *);
//
@@ -610,6 +603,11 @@ public:
caStatus disconnectChan (caResId id);
unsigned getDebugLevel() const;
virtual void clientHostName (char *pBuf, unsigned bufSize) const = 0;
protected:
private:
tsDLList<casChannelI> chanList;
char *pUserName;
@@ -665,14 +663,16 @@ private:
//
// io independent send/recv
//
xSendStatus xSend (char *pBuf, bufSizeT nBytesAvailableToSend,
outBuf::flushCondition xSend (char *pBuf, bufSizeT nBytesAvailableToSend,
bufSizeT nBytesNeedToBeSent, bufSizeT &nBytesSent);
xRecvStatus xRecv (char *pBuf, bufSizeT nBytesToRecv,
bufSizeT &nByesRecv);
inBuf::fillCondition xRecv (char *pBuf, bufSizeT nBytesToRecv,
fillParameter parm, bufSizeT &nByesRecv);
virtual xBlockingStatus blockingState() const = 0;
virtual xSendStatus osdSend (const char *pBuf, bufSizeT nBytesReq,
virtual outBuf::flushCondition osdSend (const char *pBuf, bufSizeT nBytesReq,
bufSizeT &nBytesActual) = 0;
virtual xRecvStatus osdRecv (char *pBuf, bufSizeT nBytesReq,
virtual inBuf::fillCondition osdRecv (char *pBuf, bufSizeT nBytesReq,
bufSizeT &nBytesActual) = 0;
caStatus readNotifyResponseECA_XXX (casChannelI *pChan,
@@ -683,32 +683,33 @@ private:
class casDGIntfIO;
//
// casDGClient
//
class casDGClient : public dgInBuf, public dgOutBuf, public casClient {
class casDGClient : public casClient {
public:
casDGClient (caServerI &serverIn);
virtual ~casDGClient();
caStatus init(); // constructor does not return status
void show (unsigned level) const;
//
// only for use with DG io
//
static void sendBeacon(casDGIntfIO &io);
void sendBeacon ();
virtual void sendBeaconIO (char &msg, unsigned length, aitUint32 &m_ipa, aitUint16 &m_port) = 0;
void destroy();
void processDG(casDGIntfIO &inMsgIO, casDGIntfIO &outMsgIO);
unsigned getDebugLevel() const;
virtual void clientHostName (char *pBuf,
unsigned bufSize) const = 0;
void clientHostName (char *pBuf, unsigned bufSize) const;
caNetAddr fetchLastRecvAddr () const;
virtual caNetAddr serverAddress () const = 0;
protected:
@@ -717,11 +718,10 @@ protected:
return this->casEventSys::process();
}
private:
casDGIntfIO *pOutMsgIO;
casDGIntfIO *pInMsgIO;
caStatus processDG ();
void ioBlockedSignal(); // dummy
private:
caNetAddr lastRecvAddr;
//
// one function for each CA request type
@@ -731,24 +731,34 @@ private:
//
// searchFailResponse()
//
caStatus searchFailResponse(const caHdr *pMsg);
caStatus searchFailResponse (const caHdr *pMsg);
caStatus searchResponse(const caHdr &, const pvExistReturn &);
caStatus searchResponse (const caHdr &, const pvExistReturn &);
caStatus asyncSearchResponse(
casDGIntfIO &outMsgIO, const caNetAddr &outAddr,
caStatus asyncSearchResponse (const caNetAddr &outAddr,
const caHdr &msg, const pvExistReturn &);
caNetAddr fetchRespAddr();
casDGIntfIO* fetchOutIntf();
//
// IO depen
//
xRecvStatus xDGRecv (char *pBuf, bufSizeT nBytesToRecv,
bufSizeT &nByesRecv, caNetAddr &sender);
xSendStatus xDGSend (char *pBuf, bufSizeT nBytesNeedToBeSent,
bufSizeT &nBytesSent, const caNetAddr &recipient);
bufSizeT incommingBytesPresent() const;
outBuf::flushCondition xSend (char *pBufIn, bufSizeT nBytesAvailableToSend,
bufSizeT nBytesNeedToBeSent, bufSizeT &nBytesSent);
inBuf::fillCondition xRecv (char *pBufIn, bufSizeT nBytesToRecv,
fillParameter parm, bufSizeT &nByesRecv);
virtual outBuf::flushCondition osdSend (const char *pBuf, bufSizeT nBytesReq,
const caNetAddr &addr) = 0;
virtual inBuf::fillCondition osdRecv (char *pBuf, bufSizeT nBytesReq,
fillParameter parm, bufSizeT &nBytesActual, caNetAddr &addr) = 0;
//
// cadg
//
struct cadg {
caNetAddr cadg_addr; // invalid address indicates pad
bufSizeT cadg_nBytes;
};
};
//
@@ -776,9 +786,9 @@ class casEventRegistry : private resTable <casEventMaskEntry, stringId> {
friend class casEventMaskEntry;
public:
casEventRegistry (osiMutex &mutexIn) :
casEventRegistry () :
resTable<casEventMaskEntry, stringId> (casEventRegistryHashTableSize),
mutex(mutexIn), allocator(0) {}
allocator(0) {}
virtual ~casEventRegistry();
@@ -787,7 +797,6 @@ public:
void show (unsigned level) const;
private:
osiMutex &mutex;
unsigned allocator;
casEventMask maskAllocator();
@@ -816,7 +825,7 @@ public:
//
// find the channel associated with a resource id
//
inline casChannelI *resIdToChannel(const caResId &id);
casChannelI *resIdToChannel(const caResId &id);
//
// find the PV associated with a resource id
@@ -828,60 +837,69 @@ public:
//
casClientMon *resIdToClientMon(const caResId &idIn);
casDGClient &castClient() {return this->dgClient;}
void installClient (casStrmClient *pClient);
void installClient(casStrmClient *pClient);
void removeClient(casStrmClient *pClient);
void removeClient (casStrmClient *pClient);
//
// is there space for a new channel
//
aitBool roomForNewChannel() const;
bool roomForNewChannel() const;
unsigned getDebugLevel() const { return debugLevel; }
inline void setDebugLevel (unsigned debugLevelIn);
void show(unsigned level) const;
casRes *lookupRes (const caResId &idIn, casResType type);
caServer *getAdapter ();
void installItem (casRes &res);
casRes *removeItem (casRes &res);
//
// call virtual function in the interface class
//
caServer * operator -> ();
void connectCB (casIntfOS &);
//
// common event masks
// (what is currently used by the CA clients)
//
casEventMask valueEventMask() const; // DBE_VALUE registerEvent("value")
casEventMask logEventMask() const; // DBE_LOG registerEvent("log")
casEventMask alarmEventMask() const; // DBE_ALARM registerEvent("alarm")
private:
void advanceBeaconPeriod();
tsDLList<casStrmClient> clientList;
tsDLList<casIntfOS> intfList;
double maxBeaconInterval;
double beaconPeriod;
caServer &adapter;
unsigned debugLevel;
//
// predefined event types
//
casEventMask valueEvent; // DBE_VALUE registerEvent("value")
casEventMask logEvent; // DBE_LOG registerEvent("log")
casEventMask alarmEvent; // DBE_ALARM registerEvent("alarm")
double getBeaconPeriod() const;
//
// send beacon and advance beacon timer
//
void sendBeacon();
unsigned getDebugLevel() const { return debugLevel; }
inline void setDebugLevel(unsigned debugLevelIn);
double getBeaconPeriod() const { return this->beaconPeriod; }
void show(unsigned level) const;
inline casRes *lookupRes(const caResId &idIn, casResType type);
inline caServer *getAdapter();
inline void installItem (casRes &res);
inline casRes *removeItem(casRes &res);
//
// call virtual function in the interface class
//
inline caServer * operator -> ();
void connectCB(casIntfOS &);
inline aitBool ready();
caStatus addAddr(const caNetAddr &addr, int autoBeaconAddr,
int addConfigAddr);
private:
void advanceBeaconPeriod();
casDGOS dgClient;
//casCtx ctx;
tsDLList<casStrmClient> clientList;
tsDLList<casIntfOS> intfList;
double maxBeaconInterval;
double beaconPeriod;
caServer &adapter;
unsigned debugLevel;
unsigned char haveBeenInitialized;
caStatus attachInterface (const caNetAddr &addr, bool autoBeaconAddr,
bool addConfigAddr);
};
#define CAServerConnectPendQueueSize 10
+25 -52
View File
@@ -4,21 +4,6 @@
* caServerOS.c
* $Id$
*
*
* $Log$
* Revision 1.2 1997/04/10 19:34:28 jhill
* API changes
*
* Revision 1.1 1996/11/02 01:01:27 jhill
* installed
*
* Revision 1.2 1996/08/05 19:28:49 jhill
* space became tab
*
* Revision 1.1.1.1 1996/06/20 00:28:06 jhill
* ca server installation
*
*
*/
@@ -32,23 +17,35 @@
//
class casBeaconTimer : public osiTimer {
public:
casBeaconTimer (double delay, caServerOS &osIn) :
osiTimer(delay), os (osIn) {}
void expire();
double delay() const;
bool again() const;
const char *name() const;
casBeaconTimer (double delay, caServerOS &osIn) :
osiTimer(delay), os (osIn) {}
void expire();
double delay() const;
bool again() const;
const char *name() const;
private:
caServerOS &os;
caServerOS &os;
};
//
// aServerOS::operator -> ()
// caServerOS::caServerOS()
//
inline caServerI * caServerOS::operator -> ()
caServerOS::caServerOS ()
{
return &this->cas;
this->pBTmr = new casBeaconTimer(0.0, *this);
if (!this->pBTmr) {
throw S_cas_noMemory;
}
}
//
// caServerOS::~caServerOS()
//
caServerOS::~caServerOS()
{
if (this->pBTmr) {
delete this->pBTmr;
}
}
//
@@ -56,7 +53,7 @@ inline caServerI * caServerOS::operator -> ()
//
void casBeaconTimer::expire()
{
os->sendBeacon ();
os.sendBeacon ();
}
//
@@ -72,7 +69,7 @@ bool casBeaconTimer::again() const
//
double casBeaconTimer::delay() const
{
return os->getBeaconPeriod();
return os.getBeaconPeriod();
}
//
@@ -83,27 +80,3 @@ const char *casBeaconTimer::name() const
return "casBeaconTimer";
}
//
// caServerOS::init()
//
caStatus caServerOS::init()
{
this->pBTmr = new casBeaconTimer((*this)->getBeaconPeriod(), *this);
if (!this->pBTmr) {
ca_printf("CAS: Unable to start server beacon\n");
return S_cas_noMemory;
}
return S_cas_success;
}
//
// caServerOS::~caServerOS()
//
caServerOS::~caServerOS()
{
if (this->pBTmr) {
delete this->pBTmr;
}
}
+480 -34
View File
@@ -1,16 +1,18 @@
/*
*
* casDGIntfOS.cc
* $Id$
*
*
*/
//
//
// casDGIntfOS.cc
// $Id$
//
//
//
//
// CA server
//
#include "server.h"
#include "inBufIL.h" // inBuf in line func
#include "outBufIL.h" // outBuf in line func
#include "casIODIL.h" // IO Depen in line func
//
@@ -29,23 +31,302 @@ private:
void callBack ();
};
//
// casDGBCastReadReg
//
class casDGBCastReadReg : public fdReg {
public:
casDGBCastReadReg (casDGIntfOS &osIn) :
fdReg (osIn.getBCastFD(), fdrRead), os (osIn) {}
~casDGBCastReadReg ();
void show (unsigned level) const;
private:
casDGIntfOS &os;
void callBack ();
};
//
// casDGWriteReg
//
class casDGWriteReg : public fdReg {
public:
casDGWriteReg (casDGIntfOS &osIn) :
fdReg (osIn.getFD(), fdrWrite), os (osIn) {}
~casDGWriteReg ();
void show (unsigned level) const;
private:
casDGIntfOS &os;
void callBack ();
};
//
// class casDGEvWakeup
//
class casDGEvWakeup : public osiTimer {
public:
casDGEvWakeup(casDGIntfOS &osIn) :
osiTimer(0.0), os(osIn) {}
~casDGEvWakeup();
void expire();
void show(unsigned level) const;
const char *name() const;
private:
casDGIntfOS &os;
};
//
// class casDGIOWakeup
//
class casDGIOWakeup : public osiTimer {
public:
casDGIOWakeup (casDGIntfOS &osIn) :
osiTimer (0.0), os(osIn) {}
~casDGIOWakeup ();
void expire();
void show(unsigned level) const;
const char *name() const;
private:
casDGIntfOS &os;
};
//
// casDGIntfOS::casDGIntfOS()
//
casDGIntfOS::casDGIntfOS(casDGClient &clientIn) :
casDGIntfIO(clientIn),
pRdReg(NULL)
casDGIntfOS::casDGIntfOS (caServerI &serverIn, const caNetAddr &addr,
bool autoBeaconAddr, bool addConfigBeaconAddr) :
casDGIntfIO (serverIn, addr, autoBeaconAddr, addConfigBeaconAddr),
pRdReg (NULL),
pBCastRdReg (NULL),
pWtReg (NULL),
pEvWk (NULL),
pIOWk (NULL),
sendBlocked (false)
{
this->xSetNonBlocking();
this->armRecv();
}
//
// casDGIntfOS::~casDGIntfOS()
//
casDGIntfOS::~casDGIntfOS()
{
this->disarmSend();
this->disarmRecv();
if (this->pEvWk) {
delete this->pEvWk;
}
if (this->pIOWk) {
delete this->pIOWk;
}
}
//
// casDGEvWakeup::~casDGEvWakeup()
//
casDGEvWakeup::~casDGEvWakeup()
{
this->os.pEvWk = NULL;
}
//
// casDGEvWakeup::name()
//
const char *casDGEvWakeup::name() const
{
return "casDGEvWakeup";
}
//
// casDGEvWakeup::show()
//
void casDGEvWakeup::show(unsigned level) const
{
printf ("casDGEvWakeup at %p {\n", this);
this->osiTimer::show(level);
printf ("}\n");
}
//
// casDGEvWakeup::expire()
//
void casDGEvWakeup::expire()
{
this->os.casEventSys::process();
}
//
// casDGIOWakeup::~casDGIOWakeup()
//
casDGIOWakeup::~casDGIOWakeup()
{
this->os.pIOWk = NULL;
}
//
// casDGIOWakeup::expire()
//
// Running this indirectly off of the timer queue
// guarantees that we will not call processInput()
// recursively
//
void casDGIOWakeup::expire()
{
//
// in case there is something in the input buffer
// and currently nothing to be read from UDP
//
// processInput() does an armRecv() so
// if recv is not armed, there is space in
// the input buffer, and there eventually will
// be something to read from TCP this works
//
this->os.processInput ();
}
//
// casDGIOWakeup::name()
//
const char *casDGIOWakeup::name() const
{
return "casDGIOWakeup";
}
//
// casDGIOWakeup::show()
//
void casDGIOWakeup::show(unsigned level) const
{
printf ("casDGIOWakeup at %p {\n", this);
this->osiTimer::show(level);
printf ("}\n");
}
//
// casDGIntfOS::armRecv ()
//
inline void casDGIntfOS::armRecv()
{
if (!this->pRdReg) {
if (this->inBuf::full()!=aitTrue) {
this->pRdReg = new casDGReadReg(*this);
if (!this->pRdReg) {
errMessage (S_cas_noMemory, "armRecv()");
throw S_cas_noMemory;
}
}
}
if (this->validBCastFD() && this->pBCastRdReg==NULL) {
if (this->inBuf::full()!=aitTrue) {
this->pBCastRdReg = new casDGBCastReadReg(*this);
if (!this->pBCastRdReg) {
errMessage (S_cas_noMemory, "armRecv()");
throw S_cas_noMemory;
}
}
}
}
//
// casDGIntfOS::disarmRecv()
//
inline void casDGIntfOS::disarmRecv()
{
if (this->pRdReg) {
delete this->pRdReg;
}
if (this->pBCastRdReg) {
delete this->pBCastRdReg;
}
}
//
// casDGIntfOS::armSend()
//
inline void casDGIntfOS::armSend()
{
if (this->outBuf::bytesPresent()==0u) {
return;
}
if (!this->pWtReg) {
this->pWtReg = new casDGWriteReg(*this);
if (!this->pWtReg) {
errMessage (S_cas_noMemory, "armSend()");
throw S_cas_noMemory;
}
}
}
//
// casDGIntfOS::disarmSend()
//
inline void casDGIntfOS::disarmSend ()
{
if (this->pWtReg) {
delete this->pWtReg;
}
}
//
// casDGIntfOS::ioBlockedSignal()
//
void casDGIntfOS::ioBlockedSignal()
{
if (!this->pIOWk) {
this->pIOWk = new casDGIOWakeup(*this);
if (!this->pIOWk) {
errMessage (S_cas_noMemory,
"casDGIntfOS::ioBlockedSignal()");
throw S_cas_noMemory;
}
}
}
//
// casDGIntfOS::eventSignal()
//
void casDGIntfOS::eventSignal()
{
if (!this->pEvWk) {
this->pEvWk = new casDGEvWakeup (*this);
if (!this->pEvWk) {
errMessage (S_cas_noMemory,
"casDGIntfOS::eventSignal ()");
throw S_cas_noMemory;
}
}
}
//
// casDGIntfOS::eventFlush()
//
void casDGIntfOS::eventFlush()
{
//
// if there is nothing pending in the input
// queue, then flush the output queue
//
if (this->inBuf::bytesAvailable()==0u) {
this->armSend ();
}
}
//
@@ -55,22 +336,20 @@ void casDGIntfOS::show(unsigned level) const
{
printf ("casDGIntfOS at %p\n", this);
if (this->pRdReg) {
this->pRdReg->show(level);
this->pRdReg->show (level);
}
}
/*
* casDGIntfOS::start()
*/
caStatus casDGIntfOS::start()
{
if (this->pRdReg==NULL) {
this->pRdReg = new casDGReadReg (*this);
if (this->pRdReg==NULL) {
return S_cas_noMemory;
}
if (this->pWtReg) {
this->pWtReg->show (level);
}
return S_cas_success;
if (this->pBCastRdReg) {
this->pBCastRdReg->show (level);
}
if (this->pEvWk) {
this->pEvWk->show (level);
}
if (this->pIOWk) {
this->pIOWk->show (level);
}
}
//
@@ -78,16 +357,7 @@ caStatus casDGIntfOS::start()
//
void casDGReadReg::callBack()
{
this->os.recvCB();
}
//
// casDGIntfOS::recvCB()
//
void casDGIntfOS::recvCB()
{
assert (this->pRdReg);
this->processDG();
this->os.recvCB (inBuf::fpNone);
}
//
@@ -95,6 +365,7 @@ void casDGIntfOS::recvCB()
//
casDGReadReg::~casDGReadReg()
{
os.pRdReg = NULL;
}
//
@@ -106,3 +377,178 @@ void casDGReadReg::show(unsigned level) const
printf("casDGReadReg at %p\n", this);
}
//
// casDGBCastReadReg::callBack()
//
void casDGBCastReadReg::callBack()
{
this->os.recvCB (inBuf::fpUseBroadcastInterface);
}
//
// casDGBCastReadReg::~casDGBCastReadReg()
//
casDGBCastReadReg::~casDGBCastReadReg()
{
os.pBCastRdReg = NULL;
}
//
// casDGReadReg::show()
//
void casDGBCastReadReg::show(unsigned level) const
{
this->fdReg::show(level);
printf("casDGBCastReadReg at %p\n", this);
}
//
// casDGWriteReg::~casDGWriteReg()
//
casDGWriteReg::~casDGWriteReg()
{
os.pWtReg = NULL; // allow rearm (send callbacks are one shots)
}
//
// casDGWriteReg::callBack()
//
void casDGWriteReg::callBack()
{
casDGIntfOS *pDGIOS = &this->os;
delete this; // allows rearm to occur if required
pDGIOS->sendCB();
//
// NO CODE HERE - see delete above
//
}
//
// casDGWriteReg::show()
//
void casDGWriteReg::show(unsigned level) const
{
this->fdReg::show (level);
printf ("casDGWriteReg: at %p\n", this);
}
//
// casDGIntfOS::sendBlockSignal()
//
void casDGIntfOS::sendBlockSignal()
{
this->sendBlocked=TRUE;
this->armSend();
}
//
// casDGIntfOS::sendCB()
//
void casDGIntfOS::sendCB()
{
flushCondition flushCond;
//
// attempt to flush the output buffer
//
flushCond = this->flush();
if (flushCond==flushProgress) {
if (this->sendBlocked) {
this->sendBlocked = FALSE;
}
//
// this reenables receipt of incoming frames once
// the output has been flushed when the incomming
// address is different
//
this->armRecv ();
}
# if defined(DEBUG)
printf ("write attempted on %d result was %d\n", this->getFD(), flushCond);
printf ("Recv backlog %u\n", this->inBuf::bytesPresent());
printf ("Send backlog %u\n", this->outBuf::bytesPresent());
# endif
//
// If we are unable to flush out all of the events
// in casDgEvWakeup::expire() because the
// client is slow then we must check again here when
// we _are_ able to write to see if additional events
// can be sent to the slow client.
//
this->casEventSys::process();
//
// If we were able to send something then we need
// to process the input queue in case we were send
// blocked.
//
this->processInput ();
}
//
// casDGIntfOS::recvCB()
//
void casDGIntfOS::recvCB (inBuf::fillParameter parm)
{
caNetAddr from;
assert (this->pRdReg);
//
// copy in new messages
//
this->inBuf::fill (parm);
this->processInput ();
//
// If there isnt any space then temporarily
// stop calling this routine until problem is resolved
// either by:
// (1) sending or
// (2) a blocked IO op unblocks
//
// (casDGReadReg is _not_ a onceOnly fdReg -
// therefore an explicit delete is required here)
//
if (this->inBuf::full()==aitTrue) {
this->disarmRecv(); // this deletes the casDGReadReg object
}
}
//
// casDGIntfOS::processInput()
//
void casDGIntfOS::processInput()
{
caStatus status;
//
// attempt to process the datagram in the input
// buffer
//
status = this->processDG ();
if (status!=S_cas_success &&
status!=S_cas_sendBlocked &&
status!=S_casApp_postponeAsyncIO) {
char pName[64u];
this->clientHostName (pName, sizeof (pName));
errPrintf (status, __FILE__, __LINE__,
"unexpected problem with UDP input from \"%s\"", pName);
}
//
// if anything is in the send buffer
// and there are not requests pending in the
// input buffer then keep sending the output
// buffer until it is empty
//
if (this->outBuf::bytesPresent()>0u) {
if ( this->bytesAvailable () == 0 ) {
this->armSend ();
}
}
}
+17 -14
View File
@@ -6,6 +6,9 @@
*
*
* $Log$
* Revision 1.7 1999/08/05 00:07:56 jhill
* osiTimer constructor now requires delay of type double
*
* Revision 1.6 1998/10/23 00:27:14 jhill
* fixed problem where send was not always rearmed if this
* was indirectly necessary in the send callback because
@@ -39,6 +42,8 @@
*
*/
#if 0
//
// CA server
//
@@ -114,6 +119,8 @@ void casDGEvWakeup::expire()
//
void casDGOS::sendBlockSignal()
{
this->sendBlocked=TRUE;
this->armSend();
}
//
@@ -124,8 +131,9 @@ void casDGOS::eventSignal()
if (!this->pEvWk) {
this->pEvWk = new casDGEvWakeup(*this);
if (!this->pEvWk) {
errMessage(S_cas_noMemory,
errMessage (S_cas_noMemory,
"casDGOS::eventSignal()");
throw S_cas_noMemory;
}
}
}
@@ -135,10 +143,15 @@ void casDGOS::eventSignal()
//
void casDGOS::eventFlush()
{
this->flush();
//
// if there is nothing pending in the input
// queue, then flush the output queue
//
if (this->inBuf::bytesAvailable()==0u) {
this->armSend ();
}
}
//
// casDGOS::casDGOS()
//
@@ -148,7 +161,6 @@ casDGOS::casDGOS(caServerI &cas) :
{
}
//
// casDGOS::~casDGOS()
//
@@ -171,7 +183,6 @@ void casDGOS::show(unsigned level) const
}
}
//
// casDGOS::processInput ()
// - a noop
@@ -181,12 +192,4 @@ casProcCond casDGOS::processInput ()
return casProcOk;
}
//
// casDGOS::start()
// - a noop
//
caStatus casDGOS::start()
{
return S_cas_success;
}
#endif
+35 -34
View File
@@ -12,6 +12,7 @@
// CA server
//
#include "server.h"
#include "casIODIL.h"
//
// casServerReg
@@ -19,7 +20,7 @@
class casServerReg : public fdReg {
public:
casServerReg (casIntfOS &osIn) :
fdReg (osIn.getFD(), fdrRead), os (osIn) {}
fdReg (osIn.casIntfIO::getFD(), fdrRead), os (osIn) {}
~casServerReg ();
private:
casIntfOS &os;
@@ -27,34 +28,25 @@ private:
void callBack ();
};
//
// casIntfOS::init()
// casIntfOS::casIntfOS()
//
caStatus casIntfOS::init(const caNetAddr &addrIn, casDGClient &dgClientIn,
int autoBeaconAddr, int addConfigBeaconAddr)
{
caStatus stat;
stat = this->casIntfIO::init(addrIn, dgClientIn,
autoBeaconAddr, addConfigBeaconAddr);
if (stat) {
return stat;
}
this->setNonBlocking();
if (this->pRdReg==NULL) {
this->pRdReg = new casServerReg(*this);
if (this->pRdReg==NULL) {
return S_cas_noMemory;
}
}
return S_cas_success;
casIntfOS::casIntfOS (caServerI &casIn, const caNetAddr &addrIn,
bool autoBeaconAddr, bool addConfigBeaconAddr) :
casDGIntfOS (casIn, addrIn, autoBeaconAddr, addConfigBeaconAddr),
cas (casIn),
casIntfIO (addrIn)
{
this->setNonBlocking();
this->pRdReg = new casServerReg(*this);
if (this->pRdReg==NULL) {
errMessage (S_cas_noMemory,
"casIntfOS::casIntfOS()");
throw S_cas_noMemory;
}
}
//
// casIntfOS::~casIntfOS()
//
@@ -65,15 +57,6 @@ casIntfOS::~casIntfOS()
}
}
//
// casIntfOS::newDGIntfIO()
//
casDGIntfIO *casIntfOS::newDGIntfIO(casDGClient &dgClientIn) const
{
return new casDGIntfOS(dgClientIn);
}
//
// casServerReg::callBack()
//
@@ -90,3 +73,21 @@ casServerReg::~casServerReg()
{
}
//
// casIntfOS::show ()
//
void casIntfOS::show (unsigned level)
{
printf ("casIntfOS at %p\n", this);
this->casIntfIO::show (level);
this->casDGIntfOS::show (level);
}
//
// casIntfOS::serverAddress ()
//
caNetAddr casIntfOS::serverAddress () const
{
return this->casIntfIO::serverAddress();
}
+69 -66
View File
@@ -27,61 +27,92 @@ class casBeaconTimer;
//
class caServerOS {
friend class casServerReg;
friend class casBeaconTimer;
public:
caServerOS (caServerI &casIn) :
cas (casIn), pBTmr (NULL) {}
caStatus init ();
caServerOS ();
virtual ~caServerOS ();
caStatus start ();
inline caServerI * operator -> ();
private:
caServerI &cas;
casBeaconTimer *pBTmr;
virtual double getBeaconPeriod() const = 0;
virtual void sendBeacon() = 0;
};
class casDGClient;
class casDGReadReg;
class casDGBCastReadReg;
class casDGWriteReg;
class casDGEvWakeup;
class casDGIOWakeup;
//
// casDGIntfOS
//
class casDGIntfOS : public casDGIntfIO {
friend class casDGReadReg;
friend class casDGBCastReadReg;
friend class casDGWriteReg;
friend class casDGEvWakeup;
friend class casDGIOWakeup;
public:
casDGIntfOS(casDGClient &client);
virtual ~casDGIntfOS();
caStatus start();
casDGIntfOS (caServerI &serverIn, const caNetAddr &addr,
bool autoBeaconAddr=TRUE, bool addConfigBeaconAddr=FALSE);
void show(unsigned level) const;
virtual ~casDGIntfOS ();
void show (unsigned level) const;
void recvCB();
void sendCB();
private:
casDGReadReg *pRdReg;
casDGReadReg *pRdReg;
casDGBCastReadReg *pBCastRdReg; // fix for solaris bug
casDGWriteReg *pWtReg;
casDGEvWakeup *pEvWk;
casDGIOWakeup *pIOWk;
unsigned char sendBlocked;
void armRecv ();
void armSend ();
void disarmRecv ();
void disarmSend ();
void recvCB (inBuf::fillParameter parm);
void sendCB ();
void sendBlockSignal ();
void ioBlockedSignal ();
void eventSignal ();
void eventFlush ();
void processInput();
};
//
// casIntfOS
//
class casIntfOS : public casIntfIO, public tsDLNode<casIntfOS>
class casIntfOS : public casIntfIO, public tsDLNode<casIntfOS>,
public casDGIntfOS
{
friend class casDGEvWakeup;
friend class casServerReg;
public:
casIntfOS (caServerI &casIn) :
cas (casIn), pRdReg (NULL) {}
caStatus init(const caNetAddr &addr, casDGClient &dgClientIn,
int autoBeaconAddr, int addConfigBeaconAddr);
casIntfOS (caServerI &casIn, const caNetAddr &addr,
bool autoBeaconAddr=true, bool addConfigBeaconAddr=false);
virtual ~casIntfOS();
void show (unsigned level);
caNetAddr serverAddress () const;
private:
caServerI &cas;
casServerReg *pRdReg;
void recvCB ();
void sendCB () {}; // NOOP satifies template
casDGIntfIO *newDGIntfIO (casDGClient &dgClientIn) const;
private:
caServerI &cas;
casServerReg *pRdReg;
};
class casStreamWriteReg;
@@ -93,28 +124,13 @@ class casStreamIOWakeup;
// casStreamOS
//
class casStreamOS : public casStreamIO {
friend class casStreamWriteReg;
friend class casStreamReadReg;
friend class casStreamEvWakeup;
friend class casStreamIOWakeup;
public:
casStreamOS(caServerI &, const ioArgsToNewStreamIO &ioArgs);
caStatus init();
~casStreamOS();
//
// process any incomming messages
//
casProcCond processInput();
caStatus start();
void recvCB();
void sendCB();
void sendBlockSignal();
void ioBlockedSignal();
void eventSignal();
void eventFlush();
casStreamOS (caServerI &, const ioArgsToNewStreamIO &ioArgs);
~casStreamOS ();
void show (unsigned level) const;
private:
@@ -122,7 +138,7 @@ private:
casStreamReadReg *pRdReg;
casStreamEvWakeup *pEvWk;
casStreamIOWakeup *pIOWk;
unsigned sendBlocked:1;
unsigned char sendBlocked;
//
//
//
@@ -130,34 +146,21 @@ private:
inline void armRecv ();
inline void disarmSend();
inline void disarmRecv();
};
class casDGEvWakeup;
//
// casDGOS
//
class casDGOS : public casDGIO {
friend class casDGEvWakeup;
public:
casDGOS(caServerI &cas);
~casDGOS();
//
// process any incomming messages
//
casProcCond processInput();
casProcCond processInput ();
void sendBlockSignal();
void recvCB ();
void sendCB ();
void eventSignal();
void eventFlush();
void sendBlockSignal ();
void ioBlockedSignal ();
void show(unsigned level) const;
caStatus start();
private:
casDGEvWakeup *pEvWk;
void eventSignal ();
void eventFlush ();
};
// no additions below this line
+37 -73
View File
@@ -51,6 +51,7 @@ inline casStreamReadReg::casStreamReadReg (casStreamOS &osIn) :
//
inline casStreamReadReg::~casStreamReadReg ()
{
os.pRdReg = NULL;
# if defined(DEBUG)
printf ("Read off %d\n", this->os.getFD());
printf ("Recv backlog %u\n",
@@ -95,6 +96,7 @@ inline casStreamWriteReg::casStreamWriteReg (casStreamOS &osIn) :
//
inline casStreamWriteReg::~casStreamWriteReg ()
{
os.pWtReg = NULL;
# if defined(DEBUG)
printf ("Write off %d\n", this->os.getFD());
printf ("Recv backlog %u\n",
@@ -231,6 +233,7 @@ inline void casStreamOS::armRecv()
this->pRdReg = new casStreamReadReg(*this);
if (!this->pRdReg) {
errMessage(S_cas_noMemory, "armRecv()");
throw S_cas_noMemory;
}
}
}
@@ -264,7 +267,6 @@ inline void casStreamOS::disarmRecv()
{
if (this->pRdReg) {
delete this->pRdReg;
this->pRdReg = NULL;
}
}
@@ -281,6 +283,7 @@ inline void casStreamOS::armSend()
this->pWtReg = new casStreamWriteReg(*this);
if (!this->pWtReg) {
errMessage(S_cas_noMemory, "armSend() failed");
throw S_cas_noMemory;
}
}
}
@@ -292,7 +295,6 @@ inline void casStreamOS::disarmSend ()
{
if (this->pWtReg) {
delete this->pWtReg;
this->pWtReg = NULL;
}
}
@@ -306,6 +308,7 @@ void casStreamOS::ioBlockedSignal()
if (!this->pIOWk) {
errMessage(S_cas_noMemory,
"casStreamOS::ioBlockedSignal()");
throw S_cas_noMemory;
}
}
}
@@ -320,6 +323,7 @@ void casStreamOS::eventSignal()
if (!this->pEvWk) {
errMessage(S_cas_noMemory,
"casStreamOS::eventSignal()");
throw S_cas_noMemory;
}
}
}
@@ -338,41 +342,21 @@ void casStreamOS::eventFlush()
}
}
//
// casStreamOS::casStreamOS()
//
casStreamOS::casStreamOS(caServerI &cas, const ioArgsToNewStreamIO &ioArgs) :
casStreamIO(cas, ioArgs),
pWtReg(NULL),
pRdReg(NULL),
pEvWk(NULL),
pIOWk(NULL),
sendBlocked(FALSE)
casStreamIO (cas, ioArgs),
pWtReg (NULL),
pRdReg (NULL),
pEvWk (NULL),
pIOWk (NULL),
sendBlocked (FALSE)
{
}
//
// casStreamOS::init()
//
caStatus casStreamOS::init()
{
caStatus status;
//
// init the base classes
//
status = this->casStreamIO::init();
if (status) {
return status;
}
this->xSetNonBlocking();
return S_cas_success;
this->armRecv();
}
//
// casStreamOS::~casStreamOS()
//
@@ -417,17 +401,6 @@ void casStreamOS::show(unsigned level) const
}
}
//
// casClientStart ()
//
caStatus casStreamOS::start()
{
this->armRecv();
return S_cas_success;
}
//
// casStreamReadReg::show()
//
@@ -454,7 +427,7 @@ void casStreamReadReg::callBack ()
//
void casStreamOS::recvCB()
{
casFillCondition fillCond;
inBuf::fillCondition fillCond;
casProcCond procCond;
assert (this->pRdReg);
@@ -463,31 +436,34 @@ void casStreamOS::recvCB()
// copy in new messages
//
fillCond = this->fill();
procCond = this->processInput();
if (fillCond == casFillDisconnect ||
procCond == casProcDisconnect) {
if (fillCond == casFillDisconnect) {
delete this;
}
else if (this->inBuf::full()==aitTrue) {
//
// If there isnt any space then temporarily
// stop calling this routine until problem is resolved
// either by:
// (1) sending or
// (2) a blocked IO op unblocks
//
// (casStreamReadReg is _not_ a onceOnly fdReg -
// therefore an explicit delete is required here)
//
this->disarmRecv(); // this deletes the casStreamReadReg object
}
else {
procCond = this->processInput();
if (procCond == casProcDisconnect) {
delete this;
}
else if (this->inBuf::full()==aitTrue) {
//
// If there isnt any space then temporarily
// stop calling this routine until problem is resolved
// either by:
// (1) sending or
// (2) a blocked IO op unblocks
//
// (casStreamReadReg is _not_ a onceOnly fdReg -
// therefore an explicit delete is required here)
//
this->disarmRecv(); // this deletes the casStreamReadReg object
}
}
//
// NO CODE HERE
// (see delete above)
//
}
//
// casStreamOS::sendBlockSignal()
//
@@ -497,7 +473,6 @@ void casStreamOS::sendBlockSignal()
this->armSend();
}
//
// casStreamWriteReg::show()
//
@@ -507,7 +482,6 @@ void casStreamWriteReg::show(unsigned level) const
printf ("casStreamWriteReg at %p\n", this);
}
//
// casStreamWriteReg::callBack()
//
@@ -526,31 +500,21 @@ void casStreamWriteReg::callBack()
//
void casStreamOS::sendCB()
{
casFlushCondition flushCond;
outBuf::flushCondition flushCond;
casProcCond procCond;
this->pWtReg = NULL; // allow rearm (send callbacks are one shots)
//
// attempt to flush the output buffer
//
flushCond = this->flush();
if (flushCond==casFlushCompleted ||
flushCond==casFlushPartial) {
if (flushCond==flushProgress) {
if (this->sendBlocked) {
this->sendBlocked = FALSE;
}
}
else if (flushCond==casFlushDisconnect) {
else if (flushCond==outBuf::flushDisconnect) {
return;
}
#if defined(DEBUG)
else if (flushCond==casFlushNone) {
}
else {
assert(0);
}
#endif
//
// If we are unable to flush out all of the events
+3 -10
View File
@@ -7,6 +7,9 @@
// (for single threaded version of the server)
//
// $Log$
// Revision 1.4 1998/02/05 23:03:39 jhill
// hp comiler workaround changes
//
// Revision 1.3 1997/06/13 09:16:10 jhill
// connect proto changes
//
@@ -39,16 +42,6 @@ ioBlocked::~ioBlocked()
{
}
//
// ioBlocked::ioBlockedSignal()
//
void ioBlocked::ioBlockedSignal()
{
//
// NOOP
//
}
//
// ioBlockedList::ioBlockedList ()
//
+122 -145
View File
@@ -4,32 +4,6 @@
// verify connection state prior to doing anything in this file
//
//
// $Log$
// Revision 1.8 1998/05/29 20:08:20 jhill
// use new sock ioctl() typedef
//
// Revision 1.7 1997/08/05 00:47:22 jhill
// fixed warnings
//
// Revision 1.6 1997/06/30 23:40:48 jhill
// use %p for pointers
//
// Revision 1.5 1997/06/13 09:16:12 jhill
// connect proto changes
//
// Revision 1.4 1997/04/10 19:40:31 jhill
// API changes
//
// Revision 1.3 1996/11/02 00:54:42 jhill
// many improvements
//
// Revision 1.2 1996/06/21 02:12:40 jhill
// SOLARIS port
//
// Revision 1.1.1.1 1996/06/20 00:28:19 jhill
// ca server installation
//
//
#include <ctype.h>
@@ -42,6 +16,105 @@ static char *getToken(const char **ppString, char *pBuf, unsigned bufSIze);
int caServerIO::staticInitialized;
//
// caServerIO::caServerIO()
//
caServerIO::caServerIO ()
{
if (!bsdSockAttach()) {
throw S_cas_internal;
}
caServerIO::staticInit();
}
//
// caServerIO::locateInterfaces()
//
void caServerIO::locateInterfaces ()
{
char buf[64u];
const char *pStr;
char *pToken;
caStatus stat;
unsigned short port;
struct sockaddr_in saddr;
bool autoBeaconAddr;
//
// first try for the server's private port number env var.
// If this available use the CA server port number (used by
// clients to find the server). If this also isnt available
// then use a hard coded default - CA_SERVER_PORT.
//
if (envGetConfigParamPtr(&EPICS_CAS_SERVER_PORT)) {
port = caFetchPortConfig(&EPICS_CAS_SERVER_PORT, CA_SERVER_PORT);
}
else {
port = caFetchPortConfig(&EPICS_CA_SERVER_PORT, CA_SERVER_PORT);
}
memset ((char *)&saddr,0,sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = ntohs (port);
pStr = envGetConfigParam(&EPICS_CA_AUTO_ADDR_LIST, sizeof(buf), buf);
if (pStr) {
if (strstr(pStr,"no")||strstr(pStr,"NO")) {
autoBeaconAddr = false;
}
else if (strstr(pStr,"yes")||strstr(pStr,"YES")) {
autoBeaconAddr = true;
}
else {
fprintf(stderr,
"CAS: EPICS_CA_AUTO_ADDR_LIST = \"%s\"? Assuming \"YES\"\n", pStr);
autoBeaconAddr = true;
}
}
else {
autoBeaconAddr = true;
}
//
// bind to the the interfaces specified - otherwise wildcard
// with INADDR_ANY and allow clients to attach from any interface
//
pStr = envGetConfigParamPtr(&EPICS_CAS_INTF_ADDR_LIST);
if (pStr) {
bool configAddrOnceFlag = true;
stat = S_cas_noInterface;
while ( (pToken = getToken(&pStr, buf, sizeof(buf))) ) {
int status;
status = aToIPAddr (pToken, 0u, &saddr);
if (status) {
ca_printf(
"%s: Parsing '%s'\n",
__FILE__,
EPICS_CAS_INTF_ADDR_LIST.name);
ca_printf(
"\tBad internet address or host name: '%s'\n",
pToken);
continue;
}
stat = this->attachInterface (caNetAddr(saddr), autoBeaconAddr, configAddrOnceFlag);
if (stat) {
errMessage(stat, NULL);
break;
}
configAddrOnceFlag = false;
}
}
else {
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
stat = this->attachInterface (caNetAddr(saddr), autoBeaconAddr, true);
if (stat) {
errMessage(stat, NULL);
}
}
}
//
// caServerIO::~caServerIO()
//
@@ -64,102 +137,6 @@ inline void caServerIO::staticInit()
caServerIO::staticInitialized = TRUE;
}
//
// caServerIO::init()
//
caStatus caServerIO::init(caServerI &cas)
{
char buf[64u];
const char *pStr;
char *pToken;
caStatus stat;
unsigned short port;
struct sockaddr_in saddr;
int autoBeaconAddr;
if (!bsdSockAttach()) {
return S_cas_internal;
}
caServerIO::staticInit();
//
// first try for the server's private port number env var.
// If this available use the CA server port number (used by
// clients to find the server). If this also isnt available
// then use a hard coded default - CA_SERVER_PORT.
//
if (envGetConfigParamPtr(&EPICS_CAS_SERVER_PORT)) {
port = caFetchPortConfig(&EPICS_CAS_SERVER_PORT, CA_SERVER_PORT);
}
else {
port = caFetchPortConfig(&EPICS_CA_SERVER_PORT, CA_SERVER_PORT);
}
memset((char *)&saddr,0,sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = ntohs (port);
pStr = envGetConfigParam(&EPICS_CA_AUTO_ADDR_LIST, sizeof(buf), buf);
if (pStr) {
if (strstr(pStr,"no")||strstr(pStr,"NO")) {
autoBeaconAddr = FALSE;
}
else if (strstr(pStr,"yes")||strstr(pStr,"YES")) {
autoBeaconAddr = TRUE;
}
else {
fprintf(stderr,
"CAS: EPICS_CA_AUTO_ADDR_LIST = \"%s\"? Assuming \"YES\"\n", pStr);
autoBeaconAddr = TRUE;
}
}
else {
autoBeaconAddr = TRUE;
}
//
// bind to the the interfaces specified - otherwise wildcard
// with INADDR_ANY and allow clients to attach from any interface
//
pStr = envGetConfigParamPtr(&EPICS_CAS_INTF_ADDR_LIST);
if (pStr) {
int configAddrOnceFlag = TRUE;
stat = S_cas_noInterface;
while ( (pToken = getToken(&pStr, buf, sizeof(buf))) ) {
int status;
status = aToIPAddr (pToken, 0u, &saddr);
if (status) {
ca_printf(
"%s: Parsing '%s'\n",
__FILE__,
EPICS_CAS_INTF_ADDR_LIST.name);
ca_printf(
"\tBad internet address or host name: '%s'\n",
pToken);
continue;
}
stat = cas.addAddr(caNetAddr(saddr), autoBeaconAddr, configAddrOnceFlag);
if (stat) {
errMessage(stat, NULL);
break;
}
configAddrOnceFlag = FALSE;
}
}
else {
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
stat = cas.addAddr(caNetAddr(saddr), autoBeaconAddr, TRUE);
if (stat) {
errMessage(stat, NULL);
}
}
return stat;
}
//
// caServerIO::show()
//
@@ -173,29 +150,29 @@ void caServerIO::show (unsigned /* level */) const
//
static char *getToken(const char **ppString, char *pBuf, unsigned bufSIze)
{
const char *pToken;
unsigned i;
pToken = *ppString;
while(isspace(*pToken)&&*pToken){
pToken++;
}
for (i=0u; i<bufSIze; i++) {
if (isspace(pToken[i]) || pToken[i]=='\0') {
pBuf[i] = '\0';
break;
}
pBuf[i] = pToken[i];
}
*ppString = &pToken[i];
if(*pToken){
return pBuf;
}
else{
return NULL;
const char *pToken;
unsigned i;
pToken = *ppString;
while(isspace(*pToken)&&*pToken){
pToken++;
}
for (i=0u; i<bufSIze; i++) {
if (isspace(pToken[i]) || pToken[i]=='\0') {
pBuf[i] = '\0';
break;
}
pBuf[i] = pToken[i];
}
*ppString = &pToken[i];
if(*pToken){
return pBuf;
}
else{
return NULL;
}
}
-21
View File
@@ -31,24 +31,3 @@
#include "server.h"
#include "dgInBufIL.h" // in line func for dgInBuf
#include "bsdSocketResource.h"
casDGIO::~casDGIO()
{
}
//
// casDGIO::clientHostName()
//
void casDGIO::clientHostName (char *pBufIn, unsigned bufSizeIn) const
{
if (this->hasAddress()) {
struct sockaddr_in addr = this->getSender();
ipAddrToA (&addr, pBufIn, bufSizeIn);
}
else {
if (bufSizeIn>=1u) {
pBufIn[0u] = '\0';
}
}
}
+360 -364
View File
@@ -41,193 +41,161 @@
//
// casDGIntfIO::casDGIntfIO()
//
casDGIntfIO::casDGIntfIO(casDGClient &clientIn) :
pAltOutIO(NULL),
client(clientIn),
sock(INVALID_SOCKET),
sockState(casOffLine),
connectWithThisPort(0),
dgPort(0)
casDGIntfIO::casDGIntfIO (caServerI &serverIn, const caNetAddr &addr,
bool autoBeaconAddr, bool addConfigBeaconAddr) :
casDGClient (serverIn)
{
ellInit(&this->beaconAddrList);
}
struct sockaddr_in serverAddr;
struct sockaddr_in serverBCastAddr;
int status;
unsigned short beaconPort;
ellInit(&this->beaconAddrList);
if (!bsdSockAttach()) {
throw S_cas_internal;
}
this->sock = casDGIntfIO::makeSockDG();
if (this->sock==INVALID_SOCKET) {
throw S_cas_internal;
}
//
// casDGIntfIO::init()
//
caStatus casDGIntfIO::init(const caNetAddr &addr, unsigned connectWithThisPortIn,
int autoBeaconAddr, int addConfigBeaconAddr,
int useBroadcastAddr, casDGIntfIO *pAltOutIn)
{
int yes = TRUE;
struct sockaddr_in serverAddr;
int status;
unsigned short beaconPort;
ELLLIST BCastAddrList;
//
// Fetch port configuration from EPICS environment variables
//
if (envGetConfigParamPtr(&EPICS_CAS_SERVER_PORT)) {
this->dgPort = caFetchPortConfig(&EPICS_CAS_SERVER_PORT,
CA_SERVER_PORT);
}
else {
this->dgPort = caFetchPortConfig(&EPICS_CA_SERVER_PORT,
CA_SERVER_PORT);
}
beaconPort = caFetchPortConfig(&EPICS_CA_REPEATER_PORT,
CA_REPEATER_PORT);
if (!bsdSockAttach()) {
return S_cas_internal;
}
//
// set up the primary address of the server
//
serverAddr = addr;
serverAddr.sin_port = htons (this->dgPort);
//
// discover beacon addresses associated with this interface
//
{
ELLLIST BCastAddrList;
caAddrNode *pAddr;
if (pAltOutIn) {
this->pAltOutIO = pAltOutIn;
}
else {
this->pAltOutIO = this;
}
ellInit (&BCastAddrList);
caDiscoverInterfaces (&BCastAddrList, this->sock, beaconPort,
serverAddr.sin_addr); // match addr
this->sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (this->sock == INVALID_SOCKET) {
errMessage(S_cas_noMemory,
"CAS: unable to create cast socket\n");
return S_cas_noMemory;
}
if (ellCount(&BCastAddrList)<1) {
errMessage (S_cas_noInterface, "unable to continue");
socket_close (this->sock);
throw S_cas_noInterface;
}
pAddr = (caAddrNode *) ellFirst (&BCastAddrList);
serverBCastAddr = pAddr->destAddr.in;
serverBCastAddr.sin_port = htons (this->dgPort);
status = setsockopt(
this->sock,
SOL_SOCKET,
SO_BROADCAST,
(char *)&yes,
sizeof(yes));
if (status<0) {
errMessage(S_cas_internal,
"CAS: unable to set up cast socket\n");
return S_cas_internal;
}
if (autoBeaconAddr) {
ellConcat(&this->beaconAddrList, &BCastAddrList);
}
else {
ellFree(&BCastAddrList);
}
}
status = bind(this->sock, (struct sockaddr *)&serverAddr,
sizeof (serverAddr));
if (status<0) {
char buf[64];
int errnoCpy = SOCKERRNO;
ipAddrToA (&serverAddr, buf, sizeof(buf));
errPrintf (S_cas_bindFail, __FILE__, __LINE__,
("- bind UDP IP addr=%s failed because %s",
buf, SOCKERRSTR(errnoCpy)) );
socket_close (this->sock);
throw S_cas_bindFail;
}
if (addConfigBeaconAddr) {
//
// by default use EPICS_CA_ADDR_LIST for the
// beacon address list
//
const ENV_PARAM *pParam;
if (envGetConfigParamPtr(&EPICS_CAS_INTF_ADDR_LIST) ||
envGetConfigParamPtr(&EPICS_CAS_BEACON_ADDR_LIST)) {
pParam = &EPICS_CAS_BEACON_ADDR_LIST;
}
else {
pParam = &EPICS_CA_ADDR_LIST;
}
//
// add in the configured addresses
//
caAddConfiguredAddr(
&this->beaconAddrList,
pParam,
this->sock,
beaconPort);
}
//
// Solaris specific:
// If they are binding to a particular interface then
// we will also need to bind to the broadcast address
// for that interface (if it has one). This allows
// broadcast packets to be received, but we must reply
// through the "normal" UDP binding or the client will
// appear to receive replies from the broadcast address.
// Since it should never be valid to fill in the UDP
// source address as the broadcast address, then we must
// conclude that the Solaris implementation is broken.
//
// WIN32 specific:
// On windows this appears to only create problems because
// they correctly allow broadcast to be received when
// binding to a particular interface's IP address, and
// always fill in this interface's address as the reply
// address.
//
#if !defined(_WIN32) || 1
if (serverAddr.sin_addr.s_addr != htonl(INADDR_ANY)) {
/*
* some concern that vxWorks will run out of mBuf's
* if this change is made
*
* joh 11-10-98
*/
#if 0
{
/*
*
* this allows for faster connects by queuing
* additional incomming UDP search frames
*
* this allocates a 32k buffer
* (uses a power of two)
*/
int size = 1u<<15u;
status = setsockopt(
this->sock,
SOL_SOCKET,
SO_RCVBUF,
(char *)&size,
sizeof(size));
if (status<0) {
errMessage(S_cas_internal,
"CAS: unable to set cast socket size\n");
}
}
this->bcastRecvSock = casDGIntfIO::makeSockDG ();
if (this->bcastRecvSock==INVALID_SOCKET) {
socket_close (this->sock);
throw S_cas_internal;
}
status = bind (this->bcastRecvSock, (struct sockaddr *)&serverBCastAddr,
sizeof (serverAddr));
if (status<0) {
char buf[64];
int errnoCpy = SOCKERRNO;
ipAddrToA (&serverBCastAddr, buf, sizeof(buf));
errPrintf (S_cas_bindFail, __FILE__, __LINE__,
"- bind UDP IP addr=%s failed because %s",
buf, SOCKERRSTR(errnoCpy));
socket_close (this->sock);
socket_close (this->bcastRecvSock);
throw S_cas_bindFail;
}
}
else {
this->bcastRecvSock=INVALID_SOCKET;
}
#else
this->bcastRecvSock=INVALID_SOCKET;
#endif
/*
* release the port in case we exit early. Also if
* on a kernel with MULTICAST mods then we can have
* two UDP servers on the same port number (requires
* setting SO_REUSEADDR prior to the bind step below).
*/
status = setsockopt(
this->sock,
SOL_SOCKET,
SO_REUSEADDR,
(char *) &yes,
sizeof (yes));
if (status<0) {
errMessage(S_cas_internal,
"CAS: unable to set SO_REUSEADDR on UDP socket?\n");
}
//
// Fetch port configuration from EPICS environment variables
//
if (envGetConfigParamPtr(&EPICS_CAS_SERVER_PORT)) {
this->dgPort = caFetchPortConfig(&EPICS_CAS_SERVER_PORT,
CA_SERVER_PORT);
}
else {
this->dgPort = caFetchPortConfig(&EPICS_CA_SERVER_PORT,
CA_SERVER_PORT);
}
beaconPort = caFetchPortConfig(&EPICS_CA_REPEATER_PORT,
CA_REPEATER_PORT);
/*
* discover beacon addresses associated with this interface
*/
serverAddr = addr;
if (autoBeaconAddr || useBroadcastAddr) {
ellInit(&BCastAddrList);
caDiscoverInterfaces(
&BCastAddrList,
this->sock,
beaconPort,
serverAddr.sin_addr); /* match addr */
if (useBroadcastAddr) {
caAddrNode *pAddr;
if (ellCount(&BCastAddrList)!=1) {
return S_cas_noInterface;
}
pAddr = (caAddrNode *) ellFirst(&BCastAddrList);
serverAddr.sin_addr = pAddr->destAddr.in.sin_addr;
}
if (autoBeaconAddr) {
ellConcat(&this->beaconAddrList, &BCastAddrList);
}
else {
ellFree(&BCastAddrList);
}
}
serverAddr.sin_port = htons (this->dgPort);
status = bind(
this->sock,
(struct sockaddr *)&serverAddr,
sizeof (serverAddr));
if (status<0) {
char buf[64];
ipAddrToA (&serverAddr, buf, sizeof(buf));
errPrintf(S_cas_bindFail,
__FILE__, __LINE__, "- bind UDP IP addr=%s failed because %s",
buf, SOCKERRSTR);
return S_cas_bindFail;
}
if (addConfigBeaconAddr) {
/*
* by default use EPICS_CA_ADDR_LIST for the
* beacon address list
*/
const ENV_PARAM *pParam;
if (envGetConfigParamPtr(&EPICS_CAS_INTF_ADDR_LIST) ||
envGetConfigParamPtr(&EPICS_CAS_BEACON_ADDR_LIST)) {
pParam = &EPICS_CAS_BEACON_ADDR_LIST;
}
else {
pParam = &EPICS_CA_ADDR_LIST;
}
/*
* add in the configured addresses
*/
caAddConfiguredAddr(
&this->beaconAddrList,
pParam,
this->sock,
beaconPort);
}
this->connectWithThisPort = connectWithThisPortIn;
this->sockState=casOnLine;
return S_cas_success;
}
//
@@ -235,21 +203,17 @@ caStatus casDGIntfIO::init(const caNetAddr &addr, unsigned connectWithThisPortIn
//
casDGIntfIO::~casDGIntfIO()
{
if(this->sock!=INVALID_SOCKET){
socket_close(this->sock);
if (this->sock!=INVALID_SOCKET) {
socket_close(this->sock);
}
ellFree(&this->beaconAddrList);
bsdSockRelease();
}
//
// casDGIntfIO::clientHostName()
//
void casDGIntfIO::clientHostName (char *pBufIn, unsigned bufSizeIn) const
{
sockAddrToA (&this->lastRecvAddr, pBufIn, bufSizeIn);
if (this->bcastRecvSock!=INVALID_SOCKET) {
socket_close(this->bcastRecvSock);
}
ellFree(&this->beaconAddrList);
bsdSockRelease();
}
//
@@ -258,11 +222,6 @@ void casDGIntfIO::clientHostName (char *pBufIn, unsigned bufSizeIn) const
void casDGIntfIO::osdShow (unsigned level) const
{
printf ("casDGIntfIO at %p\n", this);
if (level>=1u) {
char buf[64];
this->clientHostName (buf, sizeof(buf));
printf ("Client Host=%s\n", buf);
}
}
//
@@ -270,72 +229,61 @@ void casDGIntfIO::osdShow (unsigned level) const
//
void casDGIntfIO::xSetNonBlocking()
{
int status;
osiSockIoctl_t yes = TRUE;
if (this->sockState!=casOnLine) {
return;
}
status = socket_ioctl(this->sock, FIONBIO, &yes);
if (status<0) {
ca_printf("%s:CAS: UDP non blocking IO set fail because \"%s\"\n",
__FILE__, SOCKERRSTR);
this->sockState = casOffLine;
}
int status;
osiSockIoctl_t yes = TRUE;
status = socket_ioctl(this->sock, FIONBIO, &yes);
if (status<0) {
ca_printf("%s:CAS: UDP non blocking IO set fail because \"%s\"\n",
__FILE__, SOCKERRSTR(SOCKERRNO));
}
}
//
// casDGIntfIO::osdRecv()
//
xRecvStatus casDGIntfIO::osdRecv(char *pBuf, bufSizeT size,
bufSizeT &actualSize, caNetAddr &fromOut)
inBuf::fillCondition casDGIntfIO::osdRecv(char *pBuf, bufSizeT size,
fillParameter parm, bufSizeT &actualSize, caNetAddr &fromOut)
{
int status;
int addrSize;
sockaddr addr;
SOCKET sockThisTime;
if (this->sockState!=casOnLine) {
return xRecvDisconnect;
}
if (parm==fpUseBroadcastInterface) {
sockThisTime = this->bcastRecvSock;
}
else {
sockThisTime = this->sock;
}
addrSize = sizeof (this->lastRecvAddr);
addrSize = sizeof (addr);
status = recvfrom (this->sock, pBuf, size, 0,
&this->lastRecvAddr, &addrSize);
if (status<0) {
if(SOCKERRNO == SOCK_EWOULDBLOCK){
actualSize = 0u;
return xRecvOK;
}
else {
ca_printf("CAS: UDP recv error was %s",
SOCKERRSTR);
actualSize = 0u;
return xRecvOK;
&addr, &addrSize);
if (status<=0) {
if (status<0) {
int errnoCpy = SOCKERRNO;
if( errnoCpy != SOCK_EWOULDBLOCK ){
ca_printf("CAS: UDP recv error was %s",
SOCKERRSTR(errnoCpy));
}
}
return casFillNone;
}
fromOut = this->lastRecvAddr;
actualSize = (bufSizeT) status;
return xRecvOK;
else {
fromOut = addr;
actualSize = (bufSizeT) status;
return casFillProgress;
}
}
//
// casDGIntfIO::osdSend()
//
xSendStatus casDGIntfIO::osdSend(const char *pBuf, bufSizeT size,
bufSizeT &actualSize, const caNetAddr &to)
outBuf::flushCondition casDGIntfIO::osdSend (const char *pBuf, bufSizeT size,
const caNetAddr &to)
{
int status;
int anerrno;
if (this->sockState!=casOnLine) {
return xSendDisconnect;
}
if (size==0u) {
actualSize = 0u;
return xSendOK;
}
//
// (char *) cast below is for brain dead wrs prototype
@@ -343,44 +291,61 @@ xSendStatus casDGIntfIO::osdSend(const char *pBuf, bufSizeT size,
struct sockaddr dest = to;
status = sendto (this->sock, (char *) pBuf, size, 0,
&dest, sizeof(dest));
if (status>0) {
if (size != (unsigned) status) {
ca_printf ("CAS: partial UDP msg discarded??\n");
}
}
else if (status==0) {
this->sockState = casOffLine;
ca_printf ("CAS: UDP send returns zero??\n");
return xSendDisconnect;
if (status>=0) {
assert ( size == (unsigned) status );
return outBuf::flushProgress;
}
else {
anerrno = SOCKERRNO;
if (anerrno != SOCK_EWOULDBLOCK) {
int errnoCpy = SOCKERRNO;
if (errnoCpy != SOCK_EWOULDBLOCK) {
char buf[64];
this->clientHostName(buf, sizeof(buf));
ca_printf(
sockAddrToA (&dest, buf, sizeof(buf));
ca_printf (
"CAS: UDP socket send to \"%s\" failed because \"%s\"\n",
buf, SOCKERRSTR);
buf, SOCKERRSTR(errnoCpy));
}
return outBuf::flushNone;
}
actualSize = size;
return xSendOK;
}
//
// casDGIntfIO::incommingBytesPresent()
//
// OK to return a size of one here when a datagram is present, and
// zero otherwise.
//
bufSizeT casDGIntfIO::incommingBytesPresent () const
{
int status;
osiSockIoctl_t nchars;
status = socket_ioctl (this->sock, FIONREAD, &nchars);
if (status<0) {
ca_printf ("CAS: FIONREAD failed because \"%s\"\n",
SOCKERRSTR(SOCKERRNO));
return 0u;
}
else if (nchars<0) {
return 0u;
}
else {
return (bufSizeT) nchars;
}
}
//
// casDGIntfIO::sendBeacon()
//
void casDGIntfIO::sendBeacon(char &msg, unsigned length, aitUint32 &m_ipa, aitUint16 &m_port)
void casDGIntfIO::sendBeaconIO (char &msg, unsigned length, aitUint32 &m_ipa, aitUint16 &m_port)
{
caAddrNode *pAddr;
int status;
if (this->sockState!=casOnLine) {
return;
}
//
// the broadcast bound socket is not used here because
// it will have the wrong source address.
//
for (pAddr = (caAddrNode *)ellFirst(&this->beaconAddrList);
pAddr; pAddr = (caAddrNode *)ellNext(&pAddr->node)) {
@@ -390,13 +355,13 @@ void casDGIntfIO::sendBeacon(char &msg, unsigned length, aitUint32 &m_ipa, aitUi
&pAddr->destAddr.sa, sizeof(pAddr->destAddr.sa));
if (status < 0) {
char buf[64];
int errnoCpy = SOCKERRNO;
ipAddrToA(&pAddr->destAddr.in, buf, sizeof(buf));
ca_printf(
"CAS:beacon error was \"%s\" dest=%s sock=%d\n",
SOCKERRSTR,
buf,
this->sock);
SOCKERRSTR(errnoCpy), buf, this->sock);
}
}
}
@@ -406,38 +371,34 @@ void casDGIntfIO::sendBeacon(char &msg, unsigned length, aitUint32 &m_ipa, aitUi
//
bufSizeT casDGIntfIO::optimumInBufferSize ()
{
#if 1
//
// must update client before the message size can be
// increased here
//
return ETHERNET_MAX_UDP;
//
// must update client before the message size can be
// increased here
//
return ETHERNET_MAX_UDP;
#else
int n;
int size;
int status;
if (this->sockState!=casOnLine) {
return ETHERNET_MAX_UDP;
}
/* fetch the TCP send buffer size */
n = sizeof(size);
status = getsockopt(
this->sock,
SOL_SOCKET,
SO_RCVBUF,
(char *)&size,
&n);
if(status < 0 || n != sizeof(size)){
size = ETEHRNET_MAX_UDP;
}
if (size<=0) {
size = ETHERNET_MAX_UDP;
}
return (bufSizeT) size;
int n;
int size;
int status;
/* fetch the TCP send buffer size */
n = sizeof(size);
status = getsockopt(
this->sock,
SOL_SOCKET,
SO_RCVBUF,
(char *)&size,
&n);
if(status < 0 || n != sizeof(size)){
size = ETEHRNET_MAX_UDP;
}
if (size<=0) {
size = ETHERNET_MAX_UDP;
}
return (bufSizeT) size;
#endif
}
@@ -446,82 +407,117 @@ bufSizeT casDGIntfIO::optimumInBufferSize ()
//
bufSizeT casDGIntfIO::optimumOutBufferSize ()
{
#if 1
//
// must update client before the message size can be
// increased here
//
return MAX_UDP;
//
// must update client before the message size can be
// increased here
//
return MAX_UDP;
#else
int n;
int size;
int status;
int n;
int size;
int status;
if (this->sockState!=casOnLine) {
return MAX_UDP;
}
/* fetch the TCP send buffer size */
n = sizeof(size);
status = getsockopt(
this->sock,
SOL_SOCKET,
SO_SNDBUF,
(char *)&size,
&n);
if(status < 0 || n != sizeof(size)){
size = MAX_UDP;
}
if (size<=0) {
size = MAX_UDP;
}
return (bufSizeT) size;
/* fetch the TCP send buffer size */
n = sizeof(size);
status = getsockopt(
this->sock,
SOL_SOCKET,
SO_SNDBUF,
(char *)&size,
&n);
if(status < 0 || n != sizeof(size)){
size = MAX_UDP;
}
if (size<=0) {
size = MAX_UDP;
}
return (bufSizeT) size;
#endif
}
//
// casDGIntfIO::state()
//
casIOState casDGIntfIO::state() const
{
return this->sockState;
}
//
// casDGIntfIO::getFD()
// casDGIntfIO::makeSockDG ()
//
int casDGIntfIO::getFD() const
SOCKET casDGIntfIO::makeSockDG ()
{
return this->sock;
}
int yes = TRUE;
int status;
SOCKET newSock;
//
// casDGIntfIO::serverPortNumber()
//
// the server's port number
// (to be used for connection requests)
//
unsigned casDGIntfIO::serverPortNumber()
{
return this->connectWithThisPort;
}
//
// this was moved from casIODIL.h to here because
// of problems inline functions and g++ -g 2.7.2
//
// casDGIntfIO::processDG()
//
void casDGIntfIO::processDG()
{
assert(this->pAltOutIO);
newSock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (newSock == INVALID_SOCKET) {
errMessage(S_cas_noMemory, "CAS: unable to create cast socket\n");
return INVALID_SOCKET;
}
status = setsockopt(
newSock,
SOL_SOCKET,
SO_BROADCAST,
(char *)&yes,
sizeof(yes));
if (status<0) {
socket_close (newSock);
errMessage(S_cas_internal,
"CAS: unable to set up cast socket\n");
return INVALID_SOCKET;
}
//
// some concern that vxWorks will run out of mBuf's
// if this change is made
//
// joh 11-10-98
//
#if 0
{
//
// process the request DG and send a response DG
// if it is required
//
this->client.processDG(*this,*this->pAltOutIO);
}
// this allows for faster connects by queuing
// additional incomming UDP search frames
//
// this allocates a 32k buffer
// (uses a power of two)
//
int size = 1u<<15u;
status = setsockopt(
newSock,
SOL_SOCKET,
SO_RCVBUF,
(char *)&size,
sizeof(size));
if (status<0) {
socket_close (newSock);
errMessage(S_cas_internal,
"CAS: unable to set cast socket size\n");
return INVALID_SOCKET;
}
}
#endif
//
// release the port in case we exit early. Also if
// on a kernel with MULTICAST mods then we can have
// two UDP servers on the same port number (requires
// setting SO_REUSEADDR prior to the bind step below).
//
status = setsockopt(
newSock,
SOL_SOCKET,
SO_REUSEADDR,
(char *) &yes,
sizeof (yes));
if (status<0) {
socket_close (newSock);
errMessage(S_cas_internal,
"CAS: unable to set SO_REUSEADDR on UDP socket?\n");
return INVALID_SOCKET;
}
return newSock;
}
+32 -66
View File
@@ -21,48 +21,38 @@ class casDGClient;
//
// casDGIntfIO
//
class casDGIntfIO {
class casDGIntfIO : public casDGClient {
public:
casDGIntfIO (casDGClient &clientIn);
caStatus init(const caNetAddr &addr, unsigned connectWithThisPort,
int autoBeaconAddr=TRUE, int addConfigBeaconAddr=FALSE,
int useBroadcastAddr=FALSE, casDGIntfIO *pAltOutIn=NULL);
casDGIntfIO (caServerI &serverIn, const caNetAddr &addr,
bool autoBeaconAddr=TRUE, bool addConfigBeaconAddr=FALSE);
virtual ~casDGIntfIO();
int getFD() const;
void xSetNonBlocking();
void sendBeacon(char &msg, bufSizeT length, aitUint32 &m_ipa, aitUint16 &m_port);
casIOState state() const;
void clientHostName (char *pBuf, unsigned bufSize) const;
xSendStatus osdSend (const char *pBuf, bufSizeT nBytesReq,
bufSizeT &nBytesActual, const caNetAddr &addr);
xRecvStatus osdRecv (char *pBuf, bufSizeT nBytesReq,
bufSizeT &nBytesActual, caNetAddr &addr);
int getFD () const;
int getBCastFD () const;
bool validBCastFD () const;
void xSetNonBlocking ();
void sendBeaconIO (char &msg, bufSizeT length, aitUint32 &m_ipa, aitUint16 &m_port);
casIOState state () const;
outBuf::flushCondition osdSend (const char *pBuf, bufSizeT nBytesReq,
const caNetAddr &addr);
inBuf::fillCondition osdRecv (char *pBuf, bufSizeT nBytesReq,
fillParameter parm, bufSizeT &nBytesActual, caNetAddr &addr);
void osdShow (unsigned level) const;
static bufSizeT optimumOutBufferSize ();
static bufSizeT optimumInBufferSize ();
//
// The server's port number
// (to be used for connection requests)
//
unsigned serverPortNumber();
virtual caStatus start()=0; // OS specific
void processDG();
bufSizeT incommingBytesPresent () const;
private:
ELLLIST beaconAddrList;
struct sockaddr lastRecvAddr;
casDGIntfIO *pAltOutIO;
casDGClient &client;
SOCKET sock;
casIOState sockState;
unsigned short connectWithThisPort;
SOCKET bcastRecvSock; // fix for solaris bug
unsigned short dgPort;
static SOCKET makeSockDG ();
};
struct ioArgsToNewStreamIO {
@@ -70,28 +60,12 @@ struct ioArgsToNewStreamIO {
SOCKET sock;
};
//
// casDGIO
//
class casDGIO : public casDGClient {
public:
casDGIO(caServerI &cas) :
casDGClient(cas) {}
~casDGIO();
//
// clientHostName()
//
void clientHostName (char *pBufIn, unsigned bufSizeIn) const;
};
//
// casStreamIO
//
class casStreamIO : public casStrmClient {
public:
casStreamIO(caServerI &cas, const ioArgsToNewStreamIO &args);
caStatus init();
~casStreamIO();
int getFD() const;
@@ -100,9 +74,9 @@ public:
casIOState state() const;
void clientHostName (char *pBuf, unsigned bufSize) const;
xSendStatus osdSend (const char *pBuf, bufSizeT nBytesReq,
outBuf::flushCondition osdSend (const char *pBuf, bufSizeT nBytesReq,
bufSizeT &nBytesActual);
xRecvStatus osdRecv (char *pBuf, bufSizeT nBytesReq,
inBuf::fillCondition osdRecv (char *pBuf, bufSizeT nBytesReq,
bufSizeT &nBytesActual);
xBlockingStatus blockingState() const;
@@ -113,18 +87,12 @@ public:
void osdShow (unsigned level) const;
//
// The server's port number
// (to be used for connection requests)
//
unsigned serverPortNumber();
const caNetAddr getAddr()
const caNetAddr getAddr() const
{
return caNetAddr(this->addr);
}
private:
casIOState sockState;
SOCKET sock;
struct sockaddr_in addr;
xBlockingStatus blockingFlag;
@@ -140,10 +108,7 @@ class casStreamOS;
//
class casIntfIO {
public:
casIntfIO();
//constructor does not return status
caStatus init(const caNetAddr &addr, casDGClient &dgClientIn,
int autoBeaconAddr, int addConfigBeaconAddr);
casIntfIO (const caNetAddr &addr);
virtual ~casIntfIO();
void show(unsigned level) const;
@@ -158,13 +123,10 @@ public:
// client can be created
//
casStreamOS *newStreamClient(caServerI &cas) const;
virtual casDGIntfIO *newDGIntfIO (casDGClient &dgClientIn) const = 0;
void requestBeacon();
caNetAddr serverAddress () const;
private:
casDGIntfIO *pNormalUDP; // attached to this intf's addr
casDGIntfIO *pBCastUDP; // attached to this intf's broadcast addr
SOCKET sock;
struct sockaddr_in addr;
};
@@ -174,8 +136,7 @@ private:
//
class caServerIO {
public:
caServerIO() {} // make hp compiler happy
caStatus init(caServerI &cas); //constructor does not return status
caServerIO ();
virtual ~caServerIO();
//
@@ -183,6 +144,8 @@ public:
//
void show (unsigned level) const;
void locateInterfaces ();
private:
//
@@ -193,6 +156,9 @@ private:
// static member func
//
static inline void staticInit();
virtual caStatus attachInterface (const caNetAddr &addr, bool autoBeaconAddr,
bool addConfigAddr) = 0;
};
+31 -3
View File
@@ -2,11 +2,39 @@
#ifndef casIODILh
#define casIODILh
#include "bsdSocketResource.h"
//
// Problems with g++ -g 2.7.2 and inline functions
// caused all functions in this file to be moved to
// casDGIntfIO.cc
// casDGIntfIO::getFD()
//
inline int casDGIntfIO::getFD() const
{
return this->sock;
}
//
// casDGIntfIO::getBCastFD()
//
inline int casDGIntfIO::getBCastFD() const
{
return this->bcastRecvSock;
}
//
// casDGIntfIO::getBCastFD()
//
inline bool casDGIntfIO::validBCastFD() const
{
return this->bcastRecvSock!=INVALID_SOCKET;
}
//
// casIntfIO::serverAddress ()
//
inline caNetAddr casIntfIO::serverAddress () const
{
return caNetAddr (this->addr);
}
#endif // casIODILh
+61 -128
View File
@@ -6,6 +6,9 @@
//
//
// $Log$
// Revision 1.7 1998/06/18 00:11:09 jhill
// use ipAddrToA
//
// Revision 1.6 1998/06/16 02:35:51 jhill
// use aToIPAddr and auto attach to winsock if its a static build
//
@@ -37,27 +40,16 @@ const unsigned caServerConnectPendQueueSize = 5u;
//
// casIntfIO::casIntfIO()
//
casIntfIO::casIntfIO() :
pNormalUDP(NULL),
pBCastUDP(NULL),
sock(INVALID_SOCKET)
{
memset(&addr, '\0', sizeof(addr));
}
//
// casIntfIO::init()
//
caStatus casIntfIO::init(const caNetAddr &addrIn, casDGClient &dgClientIn,
int autoBeaconAddr, int addConfigBeaconAddr)
casIntfIO::casIntfIO (const caNetAddr &addrIn) :
addr (addrIn.getSockIP()),
sock (INVALID_SOCKET)
{
int yes = TRUE;
int status;
caStatus stat;
int addrSize;
if (!bsdSockAttach()) {
return S_cas_internal;
throw S_cas_internal;
}
/*
@@ -65,8 +57,8 @@ caStatus casIntfIO::init(const caNetAddr &addrIn, casDGClient &dgClientIn,
*/
this->sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (this->sock==INVALID_SOCKET) {
printf("No socket error was %s\n", SOCKERRSTR);
return S_cas_noFD;
printf("No socket error was %s\n", SOCKERRSTR(SOCKERRNO));
throw S_cas_noFD;
}
/*
@@ -80,11 +72,11 @@ caStatus casIntfIO::init(const caNetAddr &addrIn, casDGClient &dgClientIn,
sizeof (yes));
if (status<0) {
ca_printf("CAS: server set SO_REUSEADDR failed? %s\n",
SOCKERRSTR);
return S_cas_internal;
SOCKERRSTR(SOCKERRNO));
socket_close (this->sock);
throw S_cas_internal;
}
this->addr = addrIn.getSockIP();
status = bind(this->sock,(sockaddr *) &this->addr,
sizeof(this->addr));
if (status<0) {
@@ -94,7 +86,6 @@ caStatus casIntfIO::init(const caNetAddr &addrIn, casDGClient &dgClientIn,
// (so the getsockname() call below will
// work correctly)
//
this->addr.sin_port = ntohs (0);
status = bind(
this->sock,
@@ -103,22 +94,26 @@ caStatus casIntfIO::init(const caNetAddr &addrIn, casDGClient &dgClientIn,
}
if (status<0) {
char buf[64];
int errnoCpy = SOCKERRNO;
ipAddrToA (&this->addr, buf, sizeof(buf));
errPrintf(S_cas_bindFail,
__FILE__, __LINE__,
"- bind TCP IP addr=%s failed because %s",
buf, SOCKERRSTR);
return S_cas_bindFail;
buf, SOCKERRSTR(errnoCpy));
socket_close (this->sock);
throw S_cas_bindFail;
}
}
addrSize = sizeof(this->addr);
status = getsockname(this->sock,
addrSize = sizeof (this->addr);
status = getsockname (this->sock,
(struct sockaddr *)&this->addr, &addrSize);
if (status) {
ca_printf("CAS: getsockname() error %s\n",
SOCKERRSTR);
return S_cas_internal;
SOCKERRSTR(SOCKERRNO));
socket_close (this->sock);
throw S_cas_internal;
}
//
@@ -129,57 +124,10 @@ caStatus casIntfIO::init(const caNetAddr &addrIn, casDGClient &dgClientIn,
status = listen(this->sock, caServerConnectPendQueueSize);
if(status < 0) {
ca_printf("CAS: listen() error %s\n", SOCKERRSTR);
return S_cas_internal;
ca_printf("CAS: listen() error %s\n", SOCKERRSTR(SOCKERRNO));
socket_close (this->sock);
throw S_cas_internal;
}
//
// set up a DG socket bound to the specified interface
// (or INADDR_ANY)
//
this->pNormalUDP = this->newDGIntfIO(dgClientIn);
if (!this->pNormalUDP) {
return S_cas_noMemory;
}
stat = this->pNormalUDP->init(this->addr, this->portNumber(),
autoBeaconAddr, addConfigBeaconAddr);
if (stat) {
return stat;
}
else {
this->pNormalUDP->start();
}
//
// If they are binding to a particular interface then
// we will also need to bind to the broadcast address
// for that interface (if it has one)
//
if (this->addr.sin_addr.s_addr != htonl(INADDR_ANY)) {
this->pBCastUDP = this->newDGIntfIO(dgClientIn);
if (this->pBCastUDP) {
stat = this->pBCastUDP->init(addr, this->portNumber(),
FALSE, FALSE, TRUE, this->pNormalUDP);
if (stat) {
if (stat==S_cas_noInterface) {
delete this->pBCastUDP;
this->pBCastUDP = NULL;
}
else {
errMessage(stat,
"server will not receive broadcasts");
}
}
else {
this->pBCastUDP->start();
}
}
else {
errMessage(S_cas_noMemory,
"failed to create broadcast socket");
}
}
return S_cas_success;
}
//
@@ -190,12 +138,6 @@ casIntfIO::~casIntfIO()
if (this->sock != INVALID_SOCKET) {
socket_close(this->sock);
}
if (this->pNormalUDP) {
delete this->pNormalUDP;
}
if (this->pBCastUDP) {
delete this->pBCastUDP;
}
bsdSockRelease();
}
@@ -205,36 +147,43 @@ casIntfIO::~casIntfIO()
//
casStreamOS *casIntfIO::newStreamClient(caServerI &cas) const
{
struct sockaddr newAddr;
SOCKET newSock;
int length;
casStreamOS *pOS;
length = sizeof(newAddr);
newSock = accept(this->sock, &newAddr, &length);
if (newSock==INVALID_SOCKET) {
if (SOCKERRNO!=SOCK_EWOULDBLOCK) {
ca_printf(
"CAS: %s accept error %s\n",
__FILE__,
SOCKERRSTR);
}
return NULL;
struct sockaddr newAddr;
SOCKET newSock;
int length;
casStreamOS *pOS;
length = sizeof(newAddr);
newSock = accept(this->sock, &newAddr, &length);
if (newSock==INVALID_SOCKET) {
int errnoCpy = SOCKERRNO;
if (errnoCpy!=SOCK_EWOULDBLOCK) {
ca_printf ("CAS: %s accept error %s\n",
__FILE__,SOCKERRSTR(errnoCpy));
}
else if (sizeof(newAddr)>(size_t)length) {
socket_close(newSock);
ca_printf("CAS: accept returned bad address len?\n");
return NULL;
return NULL;
}
else if (sizeof(newAddr)>(size_t)length) {
socket_close(newSock);
ca_printf("CAS: accept returned bad address len?\n");
return NULL;
}
ioArgsToNewStreamIO args;
args.addr = newAddr;
args.sock = newSock;
pOS = new casStreamOS(cas, args);
if (!pOS) {
socket_close(newSock);
}
else {
if ( cas.getDebugLevel()>0u) {
char pName[64u];
pOS->clientHostName (pName, sizeof (pName));
ca_printf("CAS: allocated client object for \"%s\"\n", pName);
}
ioArgsToNewStreamIO args;
args.addr = newAddr;
args.sock = newSock;
pOS = new casStreamOS(cas, args);
if (!pOS) {
socket_close(newSock);
}
return pOS;
}
return pOS;
}
//
@@ -249,7 +198,7 @@ void casIntfIO::setNonBlocking()
if (status<0) {
ca_printf(
"%s:CAS: server non blocking IO set fail because \"%s\"\n",
__FILE__, SOCKERRSTR);
__FILE__, SOCKERRSTR(SOCKERRNO));
}
}
@@ -279,20 +228,4 @@ unsigned casIntfIO::portNumber() const
return ntohs(this->addr.sin_port);
}
//
// casIntfIO::requestBeacon()
//
void casIntfIO::requestBeacon()
{
//
// the broadcast bound socket is not used here because
// it will have the wrong source address. This
// casDGIntfIO has a list of all beacon addresses
// that have been configured (no need to use
// this->pBCastUDP).
//
if (this->pNormalUDP) {
casDGClient::sendBeacon(*this->pNormalUDP);
}
}
+70 -139
View File
@@ -5,6 +5,9 @@
//
//
// $Log$
// Revision 1.18 1998/12/18 18:58:20 jhill
// fixed warning
//
// Revision 1.17 1998/11/11 01:31:59 jhill
// reduced socket buffer size
//
@@ -64,24 +67,13 @@
#include "server.h"
#include "bsdSocketResource.h"
//
// casStreamIO::casStreamIO()
//
casStreamIO::casStreamIO(caServerI &cas, const ioArgsToNewStreamIO &args) :
casStrmClient(cas),
sockState(casOffLine), sock(args.sock), addr(args.addr),
blockingFlag(xIsBlocking)
casStrmClient(cas), sock(args.sock), addr(args.addr), blockingFlag(xIsBlocking)
{
assert (sock>=0);
}
//
// casStreamIO::init()
//
caStatus casStreamIO::init()
{
int yes = TRUE;
int status;
@@ -98,8 +90,8 @@ caStatus casStreamIO::init()
if (status<0) {
ca_printf(
"CAS: %s TCP_NODELAY option set failed %s\n",
__FILE__, SOCKERRSTR);
return S_cas_internal;
__FILE__, SOCKERRSTR(SOCKERRNO));
throw S_cas_internal;
}
/*
@@ -115,8 +107,8 @@ caStatus casStreamIO::init()
if (status<0) {
ca_printf(
"CAS: %s SO_KEEPALIVE option set failed %s\n",
__FILE__, SOCKERRSTR);
return S_cas_internal;
__FILE__, SOCKERRSTR(SOCKERRNO));
throw S_cas_internal;
}
/*
@@ -141,7 +133,7 @@ caStatus casStreamIO::init()
sizeof(i));
if(status < 0){
ca_printf("CAS: SO_SNDBUF set failed\n");
return S_cas_internal;
throw S_cas_internal;
}
i = MAX_MSG_SIZE;
status = setsockopt(
@@ -152,16 +144,12 @@ caStatus casStreamIO::init()
sizeof(i));
if(status < 0){
ca_printf("CAS: SO_RCVBUF set failed\n");
return S_cas_internal;
throw S_cas_internal;
}
#endif
this->sockState = casOnLine;
return this->casStrmClient::init();
}
//
// casStreamIO::~casStreamIO()
//
@@ -172,95 +160,69 @@ casStreamIO::~casStreamIO()
}
}
//
// casStreamIO::osdSend()
//
xSendStatus casStreamIO::osdSend(const char *pInBuf, bufSizeT nBytesReq,
bufSizeT &nBytesActual)
outBuf::flushCondition casStreamIO::osdSend (const char *pInBuf, bufSizeT nBytesReq,
bufSizeT &nBytesActual)
{
int status;
int status;
status = send (this->sock, (char *) pInBuf, nBytesReq, 0);
if (status == 0) {
return outBuf::flushDisconnect;
}
else if (status<0) {
int anerrno = SOCKERRNO;
if (anerrno != SOCK_EWOULDBLOCK) {
char buf[64];
int errnoCpy = SOCKERRNO;
if (this->sockState!=casOnLine) {
return xSendDisconnect;
ipAddrToA (&this->addr, buf, sizeof(buf));
ca_printf(
"CAS: TCP socket send to \"%s\" failed because \"%s\"\n",
buf, SOCKERRSTR(errnoCpy));
}
if (nBytesReq<=0u) {
nBytesActual = 0u;
return xSendOK;
}
status = send (
this->sock,
(char *) pInBuf,
nBytesReq,
0);
if (status == 0) {
this->sockState = casOffLine;
return xSendDisconnect;
}
else if (status<0) {
int anerrno = SOCKERRNO;
if (anerrno != SOCK_EWOULDBLOCK) {
this->sockState = casOffLine;
}
nBytesActual = 0u;
return xSendOK;
}
nBytesActual = (bufSizeT) status;
return xSendOK;
return outBuf::flushNone;
}
nBytesActual = (bufSizeT) status;
return outBuf::flushProgress;
}
//
// casStreamIO::osdRecv()
//
xRecvStatus casStreamIO::osdRecv(char *pInBuf, bufSizeT nBytes,
inBuf::fillCondition casStreamIO::osdRecv (char *pInBuf, bufSizeT nBytes,
bufSizeT &nBytesActual)
{
int nchars;
int nchars;
if (this->sockState!= casOnLine) {
return xRecvDisconnect;
}
nchars = recv(this->sock, pInBuf, nBytes, 0);
nchars = recv (this->sock, pInBuf, nBytes, 0);
if (nchars==0) {
this->sockState = casOffLine;
return xRecvDisconnect;
return casFillDisconnect;
}
else if (nchars<0) {
int myerrno = SOCKERRNO;
char buf[64];
/*
* normal conn lost conditions
*/
switch(SOCKERRNO){
case SOCK_EWOULDBLOCK:
nBytesActual = 0u;
return xRecvOK;
case SOCK_ECONNABORTED:
case SOCK_ECONNRESET:
case SOCK_ETIMEDOUT:
break;
default:
ipAddrToA(&this->addr, buf, sizeof(buf));
if (myerrno==SOCK_EWOULDBLOCK) {
return casFillNone;
}
else {
ipAddrToA (&this->addr, buf, sizeof(buf));
ca_printf(
"CAS: client %s disconnected because \"%s\"\n",
buf, SOCKERRSTR);
break;
}
this->sockState = casOffLine;
return xRecvDisconnect;
buf, SOCKERRSTR(myerrno));
return casFillDisconnect;
}
}
nBytesActual = (bufSizeT) nchars;
return xRecvOK;
else {
nBytesActual = (bufSizeT) nchars;
return casFillProgress;
}
}
//
// casStreamIO::show()
//
@@ -276,7 +238,6 @@ void casStreamIO::osdShow (unsigned level) const
}
}
//
// casStreamIO::xSsetNonBlocking()
//
@@ -285,18 +246,14 @@ void casStreamIO::xSetNonBlocking()
int status;
osiSockIoctl_t yes = TRUE;
if (this->sockState!=casOnLine) {
return;
}
status = socket_ioctl(this->sock, FIONBIO, &yes);
if (status>=0) {
this->blockingFlag = xIsntBlocking;
}
else {
ca_printf("%s:CAS: TCP non blocking IO set fail because \"%s\"\n",
__FILE__, SOCKERRSTR);
this->sockState = casOffLine;
__FILE__, SOCKERRSTR(SOCKERRNO));
throw S_cas_internal;
}
}
@@ -308,45 +265,32 @@ xBlockingStatus casStreamIO::blockingState() const
return this->blockingFlag;
}
//
// casStreamIO::incommingBytesPresent()
//
bufSizeT casStreamIO::incommingBytesPresent() const
{
int status;
osiSockIoctl_t nchars;
status = socket_ioctl(this->sock, FIONREAD, &nchars);
if (status<0) {
char buf[64];
/*
* normal conn lost conditions
*/
switch(SOCKERRNO){
case SOCK_ECONNABORTED:
case SOCK_ECONNRESET:
case SOCK_ETIMEDOUT:
break;
default:
ipAddrToA(&this->addr, buf, sizeof(buf));
ca_printf(
"CAS: FIONREAD for %s failed because \"%s\"\n",
buf, SOCKERRSTR);
}
return 0u;
}
else if (nchars<0) {
return 0u;
}
else {
return (bufSizeT) nchars;
}
int status;
osiSockIoctl_t nchars;
status = socket_ioctl(this->sock, FIONREAD, &nchars);
if (status<0) {
char buf[64];
int errnoCpy = SOCKERRNO;
ipAddrToA (&this->addr, buf, sizeof(buf) );
ca_printf ("CAS: FIONREAD for %s failed because \"%s\"\n",
buf, SOCKERRSTR(errnoCpy));
return 0u;
}
else if (nchars<0) {
return 0u;
}
else {
return (bufSizeT) nchars;
}
}
//
// casStreamIO::clientHostName()
//
@@ -366,10 +310,6 @@ bufSizeT casStreamIO::optimumBufferSize ()
int size;
int status;
if (this->sockState!=casOnLine) {
return MAX_TCP;
}
/* fetch the TCP send buffer size */
n = sizeof(size);
status = getsockopt(
@@ -400,12 +340,3 @@ int casStreamIO::getFD() const
{
return this->sock;
}
//
// casStreamIO::state()
//
casIOState casStreamIO::state() const
{
return this->sockState;
}
+36 -51
View File
@@ -7,6 +7,9 @@
// Some BSD calls have crept in here
//
// $Log$
// Revision 1.5 1997/08/05 00:47:26 jhill
// fixed warnings
//
// Revision 1.4 1997/06/13 09:16:17 jhill
// connect proto changes
//
@@ -39,18 +42,18 @@ class caServerOS;
//
class casBeaconTimer : public osiTimer {
public:
casBeaconTimer (const osiTime &delay, caServerOS &osIn) :
os (osIn), osiTimer(delay) {}
void expire();
const osiTime delay();
osiBool again();
const char *name()
{
return "casBeaconTimer";
}
casBeaconTimer (const osiTime &delay, caServerOS &osIn) :
os (osIn), osiTimer(delay) {}
void expire();
const osiTime delay();
osiBool again();
const char *name()
{
return "casBeaconTimer";
}
private:
caServerOS &os;
int taskId;
caServerOS &os;
int taskId;
};
class casServerReg;
@@ -66,38 +69,20 @@ void caServerEntry(caServerI *pCAS);
// caServerOS
//
class caServerOS {
friend class casServerReg;
friend void caServerEntry(caServerI *pCAS);
friend class casServerReg;
friend void caServerEntry(caServerI *pCAS);
public:
caServerOS (caServerI &casIn) :
cas (casIn), pBTmr (NULL), tid(ERROR) {}
caStatus init ();
~caServerOS ();
caServerOS (caServerI &casIn) :
cas (casIn), pBTmr (NULL), tid(ERROR) {}
inline caServerI * operator -> ();
caStatus init ();
~caServerOS ();
inline caServerI * operator -> ();
private:
caServerI &cas;
casBeaconTimer *pBTmr;
};
//
// casDGIntfOS
//
class casDGIntfOS : public casDGIO {
public:
casDGIntfOS(casDGClient &client);
~casDGIntfOS();
caStatus start();
void show(unsigned level) const;
void recvCB();
void sendCB();
private:
casDGClient &client;
int tid;
// caServerI &cas;
casBeaconTimer *pBTmr;
};
//
@@ -106,19 +91,19 @@ private:
class casIntfOS : public casIntfIO, public tsDLNode<casIntfOS>
{
public:
casIntfOS (caServerI &casIn) :
cas (casIn), pRdReg (NULL) {}
caStatus init(const caNetAddr &addr, casDGClient &dgClientIn,
int autoBeaconAddr, int addConfigBeaconAddr);
~casIntfOS();
void recvCB ();
void sendCB () {}; // NOOP satifies template
casDGIO *newDGIO (casDGClient &dgClientIn) const;
casIntfOS (caServerI &casIn) :
cas (casIn), pRdReg (NULL) {}
caStatus init (caServerI &casIn, const caNetAddr &addr,
bool autoBeaconAddr, bool addConfigBeaconAddr);
~casIntfOS();
void recvCB ();
void sendCB () {}; // NOOP satifies template
casDGIO *newDGIO (casDGClient &dgClientIn) const;
private:
caServerI &cas;
int tid;
caServerI &cas;
int tid;
};
// no additions below this line
+18 -25
View File
@@ -4,6 +4,9 @@
//
//
// $Log$
// Revision 1.6 1998/09/24 20:53:54 jhill
// cosmetic
//
// Revision 1.5 1997/08/05 00:47:27 jhill
// fixed warnings
//
@@ -61,32 +64,22 @@ casStreamOS::casStreamOS(caServerI &cas, casMsgIO &ioIn) :
clientTId(NULL),
eventTId(NULL)
{
caStatus status;
this->eventSignalSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
if (this->eventSignalSem == NULL) {
throw S_cas_noMemory;
}
//
// init the base classes
//
status = this->casStrmClient::init();
if (status) {
throw status;
}
}
//
// casStreamOS::init()
//
caStatus casStreamOS::init()
{
caStatus status;
this->eventSignalSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
if (this->eventSignalSem == NULL) {
return S_cas_noMemory;
}
//
// init the base classes
//
status = this->casStrmClient::init();
if (status) {
return status;
}
return S_cas_success;
}
//
// casStreamOS::~casStreamOS()
//
@@ -211,7 +204,7 @@ casProcCond casStreamOS::processInput()
//
int casStrmServer (casStreamOS *pStrmOS)
{
casFillCondition fillCond;
inBuf::fillCondition fillCond;
casProcCond procCond;
//