use destroyInProgress flag now functional nativeCount()

This commit is contained in:
Jeff Hill
1996-12-06 22:36:30 +00:00
parent 7f8be4b3a1
commit 8431539f23
7 changed files with 273 additions and 45 deletions
+22 -1
View File
@@ -29,6 +29,9 @@
*
* History
* $Log$
* 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
*
@@ -56,6 +59,13 @@
#include "dbMapper.h"
//
// casPVI::getCAS()
//
inline caServerI &casPVI::getCAS()
{
return this->cas;
}
//
// casPVI::interfaceObjectPointer()
@@ -175,7 +185,7 @@ inline void casPVI::deleteSignal()
//
localCASRef.osiLock();
if (this->chanList.count()==0u) {
if (this->chanList.count()==0u && !this->destroyInProgress) {
(*this)->destroy();
//
// !! dont access self after destroy !!
@@ -230,6 +240,17 @@ inline void casPVI::postEvent (const casEventMask &select, gdd &event)
this->unlock();
}
//
// CA only does 1D arrays for now
//
inline aitIndex casPVI::nativeCount()
{
if ((*this)->maxDimension()==0u) {
return 1u; // scaler
}
return (*this)->maxBound(0u);
}
#endif // casPVIIL_h
+51
View File
@@ -0,0 +1,51 @@
/*
* $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$
*
*
*/
#include <server.h>
#include <casPVIIL.h>
//
// casPVListChan::~casPVListChan()
//
casPVListChan::~casPVListChan()
{
this->pv.removeChannel(*this);
//
// delete signal to PV occurs in
// casChannelI::~casChannelI
//
}
+3 -12
View File
@@ -29,6 +29,9 @@
*
* History
* $Log$
* Revision 1.1.1.1 1996/06/20 00:28:16 jhill
* ca server installation
*
*
*/
@@ -46,17 +49,5 @@ inline casPVListChan::casPVListChan
this->pv.installChannel(*this);
}
//
// casPVListChan::~casPVListChan()
//
inline casPVListChan::~casPVListChan()
{
this->pv.removeChannel(*this);
//
// delete signal to PV occurs in
// casChannelI::~casChannelI
//
}
#endif // casPVListChanIL_h
+130 -27
View File
@@ -29,6 +29,9 @@
*
* History
* $Log$
* 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
*
@@ -150,7 +153,7 @@ inline caStatus casStrmClient::createChannel (const char *pName)
// copied (not referenced) so we are ok if they wrap
// pName through into retVal
//
status = createChanResponse (*this->ctx.getMsg(), retVal);
status = this->createChanResponse (*this->ctx.getMsg(), retVal);
}
return status;
}
@@ -1311,9 +1314,13 @@ caStatus casStrmClient::readSyncAction()
/*
* caStatus casStrmClient::accessRightsResponse()
*/
//
// casStrmClient::accessRightsResponse()
//
// NOTE:
// Do not change the size of this response without making
// parallel changes in createChanResp
//
caStatus casStrmClient::accessRightsResponse(casChannelI *pciu)
{
caHdr *reply;
@@ -1575,6 +1582,7 @@ caStatus createDBRDD (unsigned dbrType, aitIndex dbrCount, gdd *&pDescRet)
aitUint32 valIndex;
aitUint32 gddStatus;
aitUint16 appType;
gdd *pVal;
appType = gddDbrToAit[dbrType].app;
@@ -1586,40 +1594,92 @@ caStatus createDBRDD (unsigned dbrType, aitIndex dbrCount, gdd *&pDescRet)
return S_cas_noMemory;
}
//
// set bounds for the value member
//
if (dbrCount != 1u) {
if (pDescRet->isContainer()) {
gddContainer *pCont = (gddContainer *) pDescRet;
gdd *pVal;
if (pDescRet->isContainer()) {
gddContainer *pCont = (gddContainer *) pDescRet;
gddStatus =
//
// All DBR types have a value member
//
gddStatus =
gddApplicationTypeTable::app_table.mapAppToIndex
(appType, gddAppType_value, valIndex);
if (gddStatus) {
pDescRet->unreference();
pDescRet = NULL;
return S_cas_badType;
}
pVal = pCont->getDD(valIndex);
assert (pVal);
gddStatus = pVal->setBound (0, 0u, dbrCount);
assert (gddStatus==0);
if (gddStatus) {
pDescRet->unreference();
pDescRet = NULL;
return S_cas_internal;
}
else if (pDescRet->isAtomic()) {
gddAtomic *pAtomic = (gddAtomic *) pDescRet;
gddStatus = pAtomic->setBound(0, 0u, dbrCount);
assert (gddStatus==0);
pVal = pCont->getDD(valIndex);
if (!pVal) {
pDescRet->unreference();
pDescRet = NULL;
return S_cas_internal;
}
}
else {
pVal = pDescRet;
}
if (pVal->isScalar()) {
if (dbrCount<=1u) {
return S_cas_success;
}
//
// scaler and managed (and need to set the bounds)
// => out of luck (cant modify bounds)
//
if (pDescRet->isManaged()) {
pDescRet->unreference();
pDescRet = NULL;
return S_cas_internal;
}
//
// convert to atomic
//
pVal->setDimension(1);
pVal->setBound(0, 0u, dbrCount);
}
else if (pVal->isAtomic()) {
const gddBounds* pB = pVal->getBounds();
aitIndex bound = dbrCount;
unsigned dim;
int modAllowed;
if (pDescRet->isManaged() || pDescRet->isFlat()) {
modAllowed = FALSE;
}
else {
assert (dbrCount==1u);
modAllowed = TRUE;
}
for (dim=0u; dim<(unsigned)pVal->dimension(); dim++) {
if (pB->first()!=0u && pB->size()!=bound) {
if (modAllowed) {
pVal->setBound(dim, 0u, bound);
}
else {
pDescRet->unreference();
pDescRet = NULL;
return S_cas_internal;
}
}
bound = 0u;
}
}
else {
//
// the GDD is container or isnt any of the normal types
//
pDescRet->unreference();
pDescRet = NULL;
return S_cas_internal;
}
return S_cas_success;
}
//
// casStrmClient::userName()
@@ -1648,6 +1708,7 @@ caStatus casStrmClient::createChanResponse(const caHdr &msg,
casChannelI *pChanI;
casPVI *pPV;
caHdr *claim_reply;
caHdr *dummy;
unsigned dbrType;
caStatus status;
@@ -1665,7 +1726,13 @@ caStatus casStrmClient::createChanResponse(const caHdr &msg,
return this->channelCreateFailed(&msg, S_cas_badParameter);
}
status = allocMsg (0u, &claim_reply);
//
// NOTE:
// We are allocating enough space for both the claim
// response and the access response so that we know for
// certain that they will both be sent together.
//
status = this->allocMsg (sizeof(caHdr), &dummy);
if (status) {
return status;
}
@@ -1698,6 +1765,19 @@ caStatus casStrmClient::createChanResponse(const caHdr &msg,
pChanI = (casChannelI *) pChan;
//
// NOTE:
// We are certain that the request will complete
// here because we allocated enough space for this
// and the claim response above.
//
status = casStrmClient::accessRightsResponse(pChanI);
if (status) {
errMessage(status, "incompplete channel create?");
pChanI->clientDestroy();
return this->channelCreateFailed(&msg, status);
}
status = pPV->bestDBRType(dbrType);
if (status) {
errMessage(status, "best external dbr type fetch failed");
@@ -1705,12 +1785,35 @@ caStatus casStrmClient::createChanResponse(const caHdr &msg,
return this->channelCreateFailed(&msg, status);
}
//
// NOTE:
// We are allocated enough space for both the claim
// response and the access response so that we know for
// certain that they will both be sent together.
// Nevertheles, some (old) clients do not receive
// an access rights response so we allocate again
// here to be certain that we are at the correct place in
// the protocol buffer.
//
status = this->allocMsg (sizeof(caHdr), &claim_reply,
FALSE /* dont lock the out buffer again*/);
//
// 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);
*claim_reply = nill_msg;
claim_reply->m_cmmd = CA_PROTO_CLAIM_CIU;
claim_reply->m_type = dbrType;
claim_reply->m_count = pPV->nativeCount();
claim_reply->m_cid = msg.m_cid;
claim_reply->m_available = pChanI->getSID();
//
// Unlock the buffer (and convert it to network format
//
this->commitMsg();
return status;
+50 -2
View File
@@ -30,6 +30,9 @@
* Modification Log:
* -----------------
* $Log$
* Revision 1.9 1996/11/22 19:52:24 jhill
* doc
*
* Revision 1.8 1996/11/22 19:22:53 jhill
* doc
*
@@ -375,7 +378,7 @@ public:
// where no clients are attached.
// 2) once for all PVs that exist when the server is deleted
//
// the default destroy() executes "delete this"
// the default (base) "destroy()" executes "delete this"
//
virtual void destroy ();
@@ -383,7 +386,52 @@ public:
// tbe best type for clients to use when accessing the
// value of the PV
//
virtual aitEnum bestExternalType ();
virtual aitEnum bestExternalType () const;
//
// Returns the maximum bounding box for all present and
// future data stored within the PV.
//
// The routine "dimension()" returns the maximum
// number of dimensions in the hypercube (0=scaler,
// 1=array, 2=plane, 3=cube ...}.
//
// The routine "maxBound(dimension)" returns the
// maximum length of a particular dimension of the
// hypercube as follows:
//
// dim equal to 0 1 3 ...
// -------------------------------------------
// hypercube
// type
// ---------
//
// array array
// length
//
// plane x y
//
// cube x y z
//
// .
// .
// .
//
// The default (base) "dimension()" returns zero (scaler).
// The default (base) "maxBound()" returns scaler bounds
// for all dimensions.
//
// Clients will see that the PV's data is scaler if
// these routines are not supplied in the derived class.
//
// If the "dimension" argument to maxBounds() is set to
// zero then the bound on the first dimension is being
// fetched. If the "dimension" argument to maxBound() is
// set to one then the bound on the second dimension
// are being fetched...
//
virtual unsigned maxDimension() const; // return zero if scaler
virtual aitIndex maxBound (unsigned dimension) const;
//
// Server tool calls this function to post a PV event.
+13 -2
View File
@@ -29,6 +29,9 @@
*
* History
* $Log$
* 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
*
@@ -91,7 +94,8 @@ outBuf::~outBuf()
//
caStatus outBuf::allocMsg (
bufSizeT extsize, // extension size
caHdr **ppMsg
caHdr **ppMsg,
int lockRequired
)
{
bufSizeT msgsize;
@@ -106,7 +110,14 @@ caHdr **ppMsg
stackNeeded = this->bufSize - msgsize;
this->mutex.osiLock();
//
// 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) {
+4 -1
View File
@@ -29,6 +29,9 @@
*
* History
* $Log$
* Revision 1.12 1996/11/02 00:54:31 jhill
* many improvements
*
* Revision 1.11 1996/09/16 18:24:09 jhill
* vxWorks port changes
*
@@ -353,7 +356,7 @@ public:
// allocate message buffer space
// (leaves message buffer locked)
//
caStatus allocMsg (unsigned extsize, caHdr **ppMsg);
caStatus allocMsg (unsigned extsize, caHdr **ppMsg, int lockRequired=1);
//
// commits message allocated with allocMsg()