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
<2010>
2011
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
<2010>
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
|