o changed UDP to non-blocking IO
o cleaned up (consolodated) UDP interface class structure
This commit is contained in:
@@ -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")
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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()
|
||||
{
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 "?";
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 ®, 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();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -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 ®, 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 ®, 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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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();
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,14 +4,5 @@
|
||||
|
||||
#include "inBufIL.h"
|
||||
|
||||
//
|
||||
// dgInBuf::clear()
|
||||
//
|
||||
inline void dgInBuf::clear()
|
||||
{
|
||||
this->from.clear();
|
||||
this->inBuf::clear();
|
||||
}
|
||||
|
||||
#endif // dgInBufILh
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user