EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  2005  2006  2007  2008  2009  <20102011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 2002  2003  2004  2005  2006  2007  2008  2009  <20102011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: [PATCH 1/4] Client side support for automatic resizing arrays.
From: Michael Abbott <[email protected]>
To: undisclosed-recipients:;
Date: Wed, 2 Jun 2010 09:46:35 +0100
In this commit the channel access client is modified to allow a zero
size request in a caget or camonitor call.  This is passed through to
the corresponding CA_PROTO_READ_NOTIFY or CA_PROTO_EVENT__ADD message,
but only if the minor version of the protocol is >=12.

This commit also adds a new protocol test, CA_V412(), which detects a
server which claims to understand the new zero length request.

Finally, this commit prepares for a subtle change in the CA protocol.
A request for a zero length subscription or data request, which will
only be made for protocol version 4.12 and above, is interpreted as a
request for autosized data, where the intrinsic dynamic length of the
requested waveform should be returned.

With the synchronous ca_array_get() call there is no mechanism available
to pass back the size of the retrieved data if it is different from
the requested count, so the simplest thing is to ensure we don't
request autosizing data through this api.

Signed-off-by: Michael Abbott <[email protected]>
---
 src/ca/caProto.h            |    3 +++
 src/ca/nciu.cpp             |    3 ---
 src/ca/nciu.h               |    3 ++-
 src/ca/netIO.h              |    6 +++---
 src/ca/oldChannelNotify.cpp |    3 +++
 src/ca/tcpiiu.cpp           |   11 ++++++++---
 6 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/src/ca/caProto.h b/src/ca/caProto.h
index 0f364b9..26ab3c9 100644
--- a/src/ca/caProto.h
+++ b/src/ca/caProto.h
@@ -40,6 +40,7 @@
 #   define CA_V49(MINOR) ((MINOR)>=9u)    /* large arrays, dispatch priorities */
 #   define CA_V410(MINOR) ((MINOR)>=10u)  /* beacon counter */
 #   define CA_V411(MINOR) ((MINOR)>=11u)  /* sequence numbers in UDP version command */
+#   define CA_V412(MINOR) ((MINOR)>=12u)  /* Allow zero length in requests. */
 #elif CA_MAJOR_PROTOCOL_REVISION > 4u
 #   define CA_V41(MINOR) ( 1u )
 #   define CA_V42(MINOR) ( 1u )
@@ -52,6 +53,7 @@
 #   define CA_V49(MINOR) ( 1u )
 #   define CA_V410(MINOR) ( 1u )
 #   define CA_V411(MINOR) ( 1u )
+#   define CA_V412(MINOR) ( 1u )
 #else
 #   define CA_V41(MINOR) ( 0u )
 #   define CA_V42(MINOR) ( 0u )
@@ -64,6 +66,7 @@
 #   define CA_V49(MINOR) ( 0u )
 #   define CA_V410(MINOR) ( 0u )
 #   define CA_V411(MINOR) ( 0u )
+#   define CA_V412(MINOR) ( 0u )
 #endif 
 
 /*
diff --git a/src/ca/nciu.cpp b/src/ca/nciu.cpp
index f611728..c5ae941 100644
--- a/src/ca/nciu.cpp
+++ b/src/ca/nciu.cpp
@@ -291,9 +291,6 @@ cacChannel::ioStatus nciu::read (
     if ( countIn > this->count ) {
         throw cacChannel::outOfBounds ();
     }
-    if ( countIn == 0 ) {
-        countIn = this->count;
-    }
 
     //
     // fail out if their arguments are invalid
diff --git a/src/ca/nciu.h b/src/ca/nciu.h
index 481111c..f05a13b 100644
--- a/src/ca/nciu.h
+++ b/src/ca/nciu.h
@@ -41,7 +41,7 @@
 #   include "shareLib.h"
 #endif
 
-#define CA_MINOR_PROTOCOL_REVISION 11
+#define CA_MINOR_PROTOCOL_REVISION 12
 #include "caProto.h"
 
 #include "cacIO.h"
@@ -205,6 +205,7 @@ public:
     void disconnectAllIO ( 
         epicsGuard < epicsMutex > &, epicsGuard < epicsMutex > & );
     bool connected ( epicsGuard < epicsMutex > & ) const; 
+    unsigned getcount() const { return count; }
 
 private:
     tsDLList < class baseNMIU > eventq;
diff --git a/src/ca/netIO.h b/src/ca/netIO.h
index b694bc1..5727342 100644
--- a/src/ca/netIO.h
+++ b/src/ca/netIO.h
@@ -83,7 +83,7 @@ public:
     void show ( 
         epicsGuard < epicsMutex > &, unsigned level ) const;
     arrayElementCount getCount (
-        epicsGuard < epicsMutex > & ) const;
+        epicsGuard < epicsMutex > &, bool allow_zero ) const;
     unsigned getType (
         epicsGuard < epicsMutex > & ) const;
     unsigned getMask (
@@ -242,11 +242,11 @@ inline netSubscription * netSubscription::factory (
 }
 
 inline arrayElementCount netSubscription::getCount (
-    epicsGuard < epicsMutex > & guard ) const // X aCC 361
+    epicsGuard < epicsMutex > & guard, bool allow_zero ) const // X aCC 361
 {
     //guard.assertIdenticalMutex ( this->mutex );
     arrayElementCount nativeCount = this->privateChanForIO.nativeElementCount ( guard );
-    if ( this->count == 0u || this->count > nativeCount ) {
+    if ( (this->count == 0u && !allow_zero) || this->count > nativeCount ) {
         return nativeCount;
     }
     else {
diff --git a/src/ca/oldChannelNotify.cpp b/src/ca/oldChannelNotify.cpp
index 48ddde1..8865f8d 100644
--- a/src/ca/oldChannelNotify.cpp
+++ b/src/ca/oldChannelNotify.cpp
@@ -280,6 +280,9 @@ int epicsShareAPI ca_array_get ( chtype type,
         if ( type < 0 ) {
             return ECA_BADTYPE;
         }
+        if ( count == 0 )
+            return ECA_BADCOUNT;
+
         unsigned tmpType = static_cast < unsigned > ( type );
         epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );
         pChan->eliminateExcessiveSendBacklog ( guard );
diff --git a/src/ca/tcpiiu.cpp b/src/ca/tcpiiu.cpp
index 1592b38..36d92d4 100644
--- a/src/ca/tcpiiu.cpp
+++ b/src/ca/tcpiiu.cpp
@@ -1443,6 +1443,8 @@ void tcpiiu::readNotifyRequest ( epicsGuard < epicsMutex > & guard, // X aCC 431
     if ( nElem > maxElem ) {
         throw cacChannel::msgBodyCacheTooSmall ();
     }
+    if (nElem == 0 && !CA_V412(this->minorProtocolVersion))
+       nElem = chan.getcount();
     comQueSendMsgMinder minder ( this->sendQue, guard );
     this->sendQue.insertRequestHeader ( 
         CA_PROTO_READ_NOTIFY, 0u, 
@@ -1538,7 +1540,8 @@ void tcpiiu::subscriptionRequest (
     if ( mask > 0xffff ) {
         throw cacChannel::badEventSelection ();
     }
-    arrayElementCount nElem = subscr.getCount ( guard );
+    arrayElementCount nElem = subscr.getCount (
+        guard, CA_V412(this->minorProtocolVersion) );
     arrayElementCount maxBytes;
     if ( CA_V49 ( this->minorProtocolVersion ) ) {
         maxBytes = this->cacRef.largeBufferSizeTCP ();
@@ -1584,7 +1587,8 @@ void tcpiiu::subscriptionUpdateRequest (
     if ( this->state != iiucs_connected ) {
         return;
     }
-    arrayElementCount nElem = subscr.getCount ( guard );
+    arrayElementCount nElem = subscr.getCount (
+        guard, CA_V412(this->minorProtocolVersion) );
     arrayElementCount maxBytes;
     if ( CA_V49 ( this->minorProtocolVersion ) ) {
         maxBytes = this->cacRef.largeBufferSizeTCP ();
@@ -1622,7 +1626,8 @@ void tcpiiu::subscriptionCancelRequest ( epicsGuard < epicsMutex > & guard, // X
     this->sendQue.insertRequestHeader ( 
         CA_PROTO_EVENT_CANCEL, 0u, 
         static_cast < ca_uint16_t > ( subscr.getType ( guard ) ), 
-        static_cast < ca_uint16_t > ( subscr.getCount ( guard ) ), 
+        static_cast < ca_uint16_t > ( subscr.getCount (
+            guard, CA_V412(this->minorProtocolVersion) ) ),
         chan.getSID(guard), subscr.getId(), 
         CA_V49 ( this->minorProtocolVersion ) );
     minder.commit ();
-- 
1.6.6.1


References:
[PATCH 0/4] Adding dynamic arrays to EPICS Channel Access Michael Abbott

Navigate by Date:
Prev: Hacking rsrv/camessage.c Michael Abbott
Next: [PATCH 2/4] Update rsrv to support V4.12 protocol extension. Michael Abbott
Index: 2002  2003  2004  2005  2006  2007  2008  2009  <20102011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: [PATCH 0/4] Adding dynamic arrays to EPICS Channel Access Michael Abbott
Next: [PATCH 2/4] Update rsrv to support V4.12 protocol extension. Michael Abbott
Index: 2002  2003  2004  2005  2006  2007  2008  2009  <20102011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 02 Feb 2012 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·