Subject: |
[Merge] lp:~michael-abbott/epics-base/dynamic-array into lp:epics-base |
From: |
Michael Abbott <[email protected]> |
To: |
[email protected] |
Date: |
Fri, 04 Jun 2010 11:46:22 -0000 |
Michael Abbott has proposed merging lp:~michael-abbott/epics-base/dynamic-array into lp:epics-base.
Requested reviews:
EPICS Core Developers (epics-core)
This is the dynamic array functionality already described in an earlier e-mail to epics-core.
I hope I'm doing this right. Hugely underwhelmed by bzr+launchpad so far...
--
https://code.launchpad.net/~michael-abbott/epics-base/dynamic-array/+merge/26796
Your team EPICS Core Developers is requested to review the proposed merge of lp:~michael-abbott/epics-base/dynamic-array into lp:epics-base.
=== modified file '.bzrignore'
--- .bzrignore 2009-12-23 21:06:44 +0000
+++ .bzrignore 2010-06-04 11:46:21 +0000
@@ -1,3 +1,5 @@
+./.git
+./.gitignore
./bin
./lib
./db
=== modified file 'src/ca/caProto.h'
--- src/ca/caProto.h 2004-10-04 18:55:40 +0000
+++ src/ca/caProto.h 2010-06-04 11:46:21 +0000
@@ -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
/*
=== modified file 'src/ca/db_access.h'
--- src/ca/db_access.h 2009-08-14 00:29:56 +0000
+++ src/ca/db_access.h 2010-06-04 11:46:21 +0000
@@ -524,16 +524,16 @@
dbr_double_t value; /* current value */
};
-#ifndef db_accessHFORdb_accessC
#define dbr_size_n(TYPE,COUNT)\
((unsigned)((COUNT)<=0?dbr_size[TYPE]:dbr_size[TYPE]+((COUNT)-1)*dbr_value_size[TYPE]))
/* size for each type - array indexed by the DBR_ type code */
-epicsShareExtern const unsigned short dbr_size[LAST_BUFFER_TYPE+1];
+epicsShareExtern const unsigned short dbr_size[];
/* size for each type's value - array indexed by the DBR_ type code */
-epicsShareExtern const unsigned short dbr_value_size[LAST_BUFFER_TYPE+1];
+epicsShareExtern const unsigned short dbr_value_size[];
+#ifndef db_accessHFORdb_accessC
/* class for each type's value */
enum dbr_value_class {
dbr_class_int,
=== modified file 'src/ca/nciu.cpp'
--- src/ca/nciu.cpp 2009-08-24 17:03:17 +0000
+++ src/ca/nciu.cpp 2010-06-04 11:46:21 +0000
@@ -291,9 +291,6 @@
if ( countIn > this->count ) {
throw cacChannel::outOfBounds ();
}
- if ( countIn == 0 ) {
- countIn = this->count;
- }
//
// fail out if their arguments are invalid
=== modified file 'src/ca/nciu.h'
--- src/ca/nciu.h 2008-07-28 16:19:50 +0000
+++ src/ca/nciu.h 2010-06-04 11:46:21 +0000
@@ -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 @@
void disconnectAllIO (
epicsGuard < epicsMutex > &, epicsGuard < epicsMutex > & );
bool connected ( epicsGuard < epicsMutex > & ) const;
+ unsigned getcount() const { return count; }
private:
tsDLList < class baseNMIU > eventq;
=== modified file 'src/ca/netIO.h'
--- src/ca/netIO.h 2004-10-04 18:55:40 +0000
+++ src/ca/netIO.h 2010-06-04 11:46:21 +0000
@@ -83,7 +83,7 @@
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 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 {
=== modified file 'src/ca/oldChannelNotify.cpp'
--- src/ca/oldChannelNotify.cpp 2007-01-11 21:45:58 +0000
+++ src/ca/oldChannelNotify.cpp 2010-06-04 11:46:21 +0000
@@ -280,6 +280,9 @@
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 );
=== modified file 'src/ca/tcpiiu.cpp'
--- src/ca/tcpiiu.cpp 2009-09-11 00:49:02 +0000
+++ src/ca/tcpiiu.cpp 2010-06-04 11:46:21 +0000
@@ -1443,6 +1443,8 @@
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 @@
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 @@
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 @@
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 ();
=== modified file 'src/catools/caget.c'
--- src/catools/caget.c 2009-12-15 22:05:55 +0000
+++ src/catools/caget.c 2010-06-04 11:46:21 +0000
@@ -127,6 +127,7 @@
ppv->value = calloc(1, dbr_size_n(args.type, args.count));
memcpy(ppv->value, args.dbr, dbr_size_n(args.type, args.count));
ppv->onceConnected = 1;
+ ppv->nElems = args.count;
nRead++;
}
}
@@ -183,11 +184,9 @@
}
}
/* Adjust array count */
- if (reqElems == 0 || pvs[n].nElems < reqElems){
- pvs[n].reqElems = pvs[n].nElems; /* Use full number of points */
- } else {
- pvs[n].reqElems = reqElems; /* Limit to specified number */
- }
+ if (reqElems > pvs[n].nElems)
+ reqElems = pvs[n].nElems;
+ pvs[n].reqElems = reqElems;
/* Issue CA request */
/* ---------------- */
@@ -205,13 +204,13 @@
(void*)&pvs[n]);
} else {
/* Allocate value structure */
- pvs[n].value = calloc(1, dbr_size_n(pvs[n].dbrType, pvs[n].reqElems));
+ pvs[n].value = calloc(1, dbr_size_n(pvs[n].dbrType, pvs[n].nElems));
if(!pvs[n].value) {
fprintf(stderr,"Allocation failed\n");
return 1;
}
result = ca_array_get(pvs[n].dbrType,
- pvs[n].reqElems,
+ pvs[n].nElems,
pvs[n].chid,
pvs[n].value);
}
@@ -253,10 +252,13 @@
/* -------------- */
for (n = 0; n < nPvs; n++) {
+ /* Truncate the data printed to what was requested. */
+ if (pvs[n].reqElems != 0 && pvs[n].nElems > pvs[n].reqElems)
+ pvs[n].nElems = pvs[n].reqElems;
switch (format) {
case plain: /* Emulate old caget behaviour */
- if (pvs[n].reqElems <= 1 && fieldSeparator == ' ') printf("%-30s", pvs[n].name);
+ if (pvs[n].nElems <= 1 && fieldSeparator == ' ') printf("%-30s", pvs[n].name);
else printf("%s", pvs[n].name);
printf("%c", fieldSeparator);
case terse:
@@ -270,7 +272,7 @@
printf("*** no data available (timeout)\n");
else
{
- if (charArrAsStr && dbr_type_is_CHAR(pvs[n].dbrType) && (reqElems || pvs[n].reqElems > 1)) {
+ if (charArrAsStr && dbr_type_is_CHAR(pvs[n].dbrType) && (reqElems || pvs[n].nElems > 1)) {
dbr_char_t *s = (dbr_char_t*) dbr_value_ptr(pvs[n].value, pvs[n].dbrType);
int dlen = epicsStrnEscapedFromRawSize((char*)s, strlen((char*)s));
char *d = calloc(dlen+1, sizeof(char));
@@ -282,8 +284,8 @@
fprintf(stderr,"Failed to allocate space for escaped string\n");
}
} else {
- if (reqElems || pvs[n].nElems > 1) printf("%lu%c", pvs[n].reqElems, fieldSeparator);
- for (i=0; i<pvs[n].reqElems; ++i) {
+ if (reqElems || pvs[n].nElems > 1) printf("%lu%c", pvs[n].nElems, fieldSeparator);
+ for (i=0; i<pvs[n].nElems; ++i) {
if (i) printf ("%c", fieldSeparator);
printf("%s", val2str(pvs[n].value, pvs[n].dbrType, i));
}
@@ -315,8 +317,8 @@
else {
printf(" Element count: %lu\n"
" Value: ",
- pvs[n].reqElems);
- if (charArrAsStr && dbr_type_is_CHAR(pvs[n].dbrType) && (reqElems || pvs[n].reqElems > 1)) {
+ pvs[n].nElems);
+ if (charArrAsStr && dbr_type_is_CHAR(pvs[n].dbrType) && (reqElems || pvs[n].nElems > 1)) {
dbr_char_t *s = (dbr_char_t*) dbr_value_ptr(pvs[n].value, pvs[n].dbrType);
int dlen = epicsStrnEscapedFromRawSize((char*)s, strlen((char*)s));
char *d = calloc(dlen+1, sizeof(char));
@@ -328,7 +330,7 @@
fprintf(stderr,"Failed to allocate space for escaped string\n");
}
} else {
- for (i=0; i<pvs[n].reqElems; ++i) {
+ for (i=0; i<pvs[n].nElems; ++i) {
if (i) printf ("%c", fieldSeparator);
printf("%s", val2str(pvs[n].value, pvs[n].dbrType, i));
}
=== modified file 'src/catools/camonitor.c'
--- src/catools/camonitor.c 2009-12-15 22:05:55 +0000
+++ src/catools/camonitor.c 2010-06-04 11:46:21 +0000
@@ -107,6 +107,7 @@
if (args.status == ECA_NORMAL)
{
pv->dbrType = args.type;
+ pv->nElems = args.count;
memcpy(pv->value, args.dbr, dbr_size_n(args.type, args.count));
print_time_val_sts(pv, reqElems);
@@ -150,11 +151,9 @@
ppv->dbrType = DBR_TIME_STRING;
}
/* Adjust array count */
- if (reqElems == 0 || ppv->nElems < reqElems){
- ppv->reqElems = ppv->nElems; /* Use full number of points */
- } else {
- ppv->reqElems = reqElems; /* Limit to specified number */
- }
+ if (reqElems > ppv->nElems)
+ reqElems = ppv->nElems;
+ ppv->reqElems = reqElems;
ppv->onceConnected = 1;
nConn++;
@@ -163,7 +162,7 @@
/* install monitor once with first connect */
if ( ! ppv->value ) {
/* Allocate value structure */
- ppv->value = calloc(1, dbr_size_n(ppv->dbrType, ppv->reqElems));
+ ppv->value = calloc(1, dbr_size_n(ppv->dbrType, ppv->nElems));
if ( ppv->value ) {
ppv->status = ca_create_subscription(ppv->dbrType,
ppv->reqElems,
=== modified file 'src/catools/tool_lib.c'
--- src/catools/tool_lib.c 2009-12-15 22:05:55 +0000
+++ src/catools/tool_lib.c 2010-06-04 11:46:21 +0000
@@ -455,8 +455,8 @@
printf("Failed to allocate for print_time_val_sts\n"); \
} \
} else { \
- if (reqElems || pv->nElems > 1) printf("%c%lu", fieldSeparator, pv->reqElems); \
- for (i=0; i<pv->reqElems; ++i) { \
+ if (reqElems || pv->nElems > 1) printf("%c%lu", fieldSeparator, pv->nElems); \
+ for (i=0; i<pv->nElems; ++i) { \
printf("%c%s", fieldSeparator, val2str(value, TYPE_ENUM, i)); \
} \
} \
@@ -492,7 +492,7 @@
tsInitS = 1;
}
- if (pv->reqElems <= 1 && fieldSeparator == ' ') printf("%-30s", pv->name);
+ if (pv->nElems <= 1 && fieldSeparator == ' ') printf("%-30s", pv->name);
else printf("%s", pv->name);
printf("%c", fieldSeparator);
if (!pv->onceConnected)
=== modified file 'src/catools/tool_lib.h'
--- src/catools/tool_lib.h 2009-12-15 22:05:55 +0000
+++ src/catools/tool_lib.h 2010-06-04 11:46:21 +0000
@@ -64,8 +64,8 @@
chid chid;
long dbfType;
long dbrType;
- unsigned long nElems;
- unsigned long reqElems;
+ unsigned long nElems; // True length of data in value
+ unsigned long reqElems; // Requested length of data
int status;
void* value;
epicsTimeStamp tsPreviousC;
=== modified file 'src/db/db_access.c'
--- src/db/db_access.c 2009-03-10 18:51:03 +0000
+++ src/db/db_access.c 2010-06-04 11:46:21 +0000
@@ -149,10 +149,29 @@
int epicsShareAPI db_get_field(struct dbAddr *paddr,
int buffer_type, void *pbuffer, int no_elements, void *pfl)
{
+ long nRequest = no_elements;
+ int result = db_get_field_and_count(
+ paddr, buffer_type, pbuffer, &nRequest, pfl);
+ if (nRequest < no_elements)
+ /* If the database request returned fewer elements than requested then
+ * fill out the remainder of the array with zeros. */
+ memset(
+ (char *)pbuffer + dbr_size_n(buffer_type, nRequest), 0,
+ (no_elements - nRequest) * dbr_value_size[buffer_type]);
+ return result;
+}
+
+/* Performs the work of the public db_get_field API, but also returns the number
+ * of elements actually copied to the buffer. The caller is responsible for
+ * zeroing the remaining part of the buffer. */
+int epicsShareAPI db_get_field_and_count(
+ struct dbAddr *paddr, int buffer_type,
+ void *pbuffer, long *nRequest, void *pfl)
+{
long status;
long options;
- long nRequest;
long i;
+ long zero = 0;
/* The order of the DBR* elements in the "new" structures below is
* very important and must correspond to the order of processing
@@ -161,82 +180,26 @@
switch(buffer_type) {
case(oldDBR_STRING):
- {
- DBSTRING *pvalue = (DBSTRING *)pbuffer;
-
- options = 0;
- nRequest = no_elements;
- status = dbGetField(paddr, DBR_STRING, pbuffer, &options, &nRequest,
- pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i][0] = 0;
- }
+ status = dbGetField(paddr, DBR_STRING, pbuffer, &zero, nRequest, pfl);
break;
/* case(oldDBR_INT): */
case(oldDBR_SHORT):
- {
- dbr_short_t *pvalue = (dbr_short_t *)pbuffer;
-
- options = 0;
- nRequest = no_elements;
- status = dbGetField(paddr, DBR_SHORT, pbuffer, &options, &nRequest,
- pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
- }
+ status = dbGetField(paddr, DBR_SHORT, pbuffer, &zero, nRequest, pfl);
break;
case(oldDBR_FLOAT):
- {
- dbr_float_t *pvalue = (dbr_float_t *)pbuffer;
-
- options = 0;
- nRequest = no_elements;
- status = dbGetField(paddr, DBR_FLOAT, pbuffer, &options, &nRequest,
- pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
- }
+ status = dbGetField(paddr, DBR_FLOAT, pbuffer, &zero, nRequest, pfl);
break;
case(oldDBR_ENUM):
- {
- dbr_enum_t *pvalue = (dbr_enum_t *)pbuffer;
-
- options = 0;
- nRequest = no_elements;
- status = dbGetField(paddr, DBR_ENUM, pbuffer, &options, &nRequest,
- pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
- }
+ status = dbGetField(paddr, DBR_ENUM, pbuffer, &zero, nRequest, pfl);
break;
case(oldDBR_CHAR):
- {
- dbr_char_t *pvalue = (dbr_char_t *)pbuffer;
-
- options = 0;
- nRequest = no_elements;
- status = dbGetField(paddr, DBR_CHAR, pbuffer, &options, &nRequest,
- pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
- }
+ status = dbGetField(paddr, DBR_CHAR, pbuffer, &zero, nRequest, pfl);
break;
case(oldDBR_LONG):
- {
- dbr_long_t *pvalue = (dbr_long_t *)pbuffer;
-
- options = 0;
- nRequest = no_elements;
- status = dbGetField(paddr, DBR_LONG, pbuffer, &options, &nRequest,
- pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
- }
+ status = dbGetField(paddr, DBR_LONG, pbuffer, &zero, nRequest, pfl);
break;
case(oldDBR_DOUBLE):
- {
- dbr_double_t *pvalue = (dbr_double_t *)pbuffer;
-
- options = 0;
- nRequest = no_elements;
- status = dbGetField(paddr, DBR_DOUBLE, pbuffer, &options, &nRequest,
- pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
- }
+ status = dbGetField(paddr, DBR_DOUBLE, pbuffer, &zero, nRequest, pfl);
break;
case(oldDBR_STS_STRING):
@@ -247,19 +210,13 @@
struct {
DBRstatus
} new;
- DBSTRING *pvalue = (DBSTRING *)pold->value;
options = DBR_STATUS;
- nRequest = 0;
- status = dbGetField(paddr, DBR_STRING, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_STRING, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
- options = 0;
- nRequest = no_elements;
- status = dbGetField(paddr, DBR_STRING, pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i][0] = 0;
+ status = dbGetField(paddr, DBR_STRING, pold->value, &zero,
+ nRequest, pfl);
}
break;
/* case(oldDBR_STS_INT): */
@@ -269,19 +226,13 @@
struct {
DBRstatus
} new;
- dbr_short_t *pvalue = &pold->value;
options = DBR_STATUS;
- nRequest = 0;
- status = dbGetField(paddr, DBR_SHORT, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_SHORT, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
- options = 0;
- nRequest = no_elements;
- status = dbGetField(paddr, DBR_SHORT, &pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
+ status = dbGetField(paddr, DBR_SHORT, &pold->value, &zero,
+ nRequest, pfl);
}
break;
case(oldDBR_STS_FLOAT):
@@ -290,19 +241,13 @@
struct {
DBRstatus
} new;
- dbr_float_t *pvalue = &pold->value;
options = DBR_STATUS;
- nRequest = 0;
- status = dbGetField(paddr, DBR_FLOAT, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_FLOAT, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
- options = 0;
- nRequest = no_elements;
- status = dbGetField(paddr, DBR_FLOAT, &pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
+ status = dbGetField(paddr, DBR_FLOAT, &pold->value, &zero,
+ nRequest, pfl);
}
break;
case(oldDBR_STS_ENUM):
@@ -311,19 +256,13 @@
struct {
DBRstatus
} new;
- dbr_enum_t *pvalue = &pold->value;
options = DBR_STATUS;
- nRequest = 0;
- status = dbGetField(paddr, DBR_ENUM, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_ENUM, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
- options = 0;
- nRequest = no_elements;
- status = dbGetField(paddr, DBR_ENUM, &pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
+ status = dbGetField(paddr, DBR_ENUM, &pold->value, &zero,
+ nRequest, pfl);
}
break;
case(oldDBR_STS_CHAR):
@@ -332,19 +271,13 @@
struct {
DBRstatus
} new;
- dbr_char_t *pvalue = &pold->value;
options = DBR_STATUS;
- nRequest = 0;
- status = dbGetField(paddr, DBR_UCHAR, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_UCHAR, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
- options = 0;
- nRequest = no_elements;
- status = dbGetField(paddr, DBR_UCHAR, &pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
+ status = dbGetField(paddr, DBR_UCHAR, &pold->value, &zero,
+ nRequest, pfl);
}
break;
case(oldDBR_STS_LONG):
@@ -353,19 +286,13 @@
struct {
DBRstatus
} new;
- dbr_long_t *pvalue = &pold->value;
options = DBR_STATUS;
- nRequest = 0;
- status = dbGetField(paddr, DBR_LONG, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_LONG, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
- options = 0;
- nRequest = no_elements;
- status = dbGetField(paddr, DBR_LONG, &pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
+ status = dbGetField(paddr, DBR_LONG, &pold->value, &zero,
+ nRequest, pfl);
}
break;
case(oldDBR_STS_DOUBLE):
@@ -374,19 +301,14 @@
struct {
DBRstatus
} new;
- dbr_double_t *pvalue = &pold->value;
options = DBR_STATUS;
- nRequest = 0;
- status = dbGetField(paddr, DBR_DOUBLE, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_DOUBLE, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
options = 0;
- nRequest = no_elements;
status = dbGetField(paddr, DBR_DOUBLE, &pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
+ nRequest, pfl);
}
break;
@@ -397,20 +319,15 @@
DBRstatus
DBRtime
} new;
- DBSTRING *pvalue = (DBSTRING *)(pold->value);
options = DBR_STATUS | DBR_TIME;
- nRequest = 0;
- status = dbGetField(paddr, DBR_STRING, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_STRING, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
pold->stamp = new.time; /* structure copy */
options = 0;
- nRequest = no_elements;
- status = dbGetField(paddr, DBR_STRING, pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i][0] = 0;
+ status = dbGetField(paddr, DBR_STRING, pold->value, &options,
+ nRequest, pfl);
}
break;
/* case(oldDBR_TIME_INT): */
@@ -421,20 +338,15 @@
DBRstatus
DBRtime
} new;
- dbr_short_t *pvalue = &pold->value;
options = DBR_STATUS | DBR_TIME;
- nRequest = 0;
- status = dbGetField(paddr, DBR_SHORT, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_SHORT, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
pold->stamp = new.time; /* structure copy */
options = 0;
- nRequest = no_elements;
status = dbGetField(paddr, DBR_SHORT, &pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
+ nRequest, pfl);
}
break;
case(oldDBR_TIME_FLOAT):
@@ -444,20 +356,15 @@
DBRstatus
DBRtime
} new;
- dbr_float_t *pvalue = &pold->value;
options = DBR_STATUS | DBR_TIME;
- nRequest = 0;
- status = dbGetField(paddr, DBR_FLOAT, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_FLOAT, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
pold->stamp = new.time; /* structure copy */
options = 0;
- nRequest = no_elements;
status = dbGetField(paddr, DBR_FLOAT, &pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
+ nRequest, pfl);
}
break;
case(oldDBR_TIME_ENUM):
@@ -467,20 +374,15 @@
DBRstatus
DBRtime
} new;
- dbr_enum_t *pvalue = &pold->value;
options = DBR_STATUS | DBR_TIME;
- nRequest = 0;
- status = dbGetField(paddr, DBR_ENUM, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_ENUM, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
pold->stamp = new.time; /* structure copy */
options = 0;
- nRequest = no_elements;
status = dbGetField(paddr, DBR_ENUM, &pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
+ nRequest, pfl);
}
break;
case(oldDBR_TIME_CHAR):
@@ -490,20 +392,15 @@
DBRstatus
DBRtime
} new;
- dbr_char_t *pvalue = &pold->value;
options = DBR_STATUS | DBR_TIME;
- nRequest = 0;
- status = dbGetField(paddr, DBR_CHAR, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_CHAR, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
pold->stamp = new.time; /* structure copy */
options = 0;
- nRequest = no_elements;
status = dbGetField(paddr, DBR_CHAR, &pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
+ nRequest, pfl);
}
break;
case(oldDBR_TIME_LONG):
@@ -513,20 +410,15 @@
DBRstatus
DBRtime
} new;
- dbr_long_t *pvalue = &pold->value;
options = DBR_STATUS | DBR_TIME;
- nRequest = 0;
- status = dbGetField(paddr, DBR_LONG, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_LONG, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
pold->stamp = new.time; /* structure copy */
options = 0;
- nRequest = no_elements;
status = dbGetField(paddr, DBR_LONG, &pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
+ nRequest, pfl);
}
break;
case(oldDBR_TIME_DOUBLE):
@@ -536,20 +428,15 @@
DBRstatus
DBRtime
} new;
- dbr_double_t *pvalue = &pold->value;
options = DBR_STATUS | DBR_TIME;
- nRequest = 0;
- status = dbGetField(paddr, DBR_DOUBLE, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_DOUBLE, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
pold->stamp = new.time; /* structure copy */
options = 0;
- nRequest = no_elements;
status = dbGetField(paddr, DBR_DOUBLE, &pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
+ nRequest, pfl);
}
break;
@@ -564,12 +451,9 @@
DBRgrLong
DBRalLong
} new;
- dbr_short_t *pvalue = &pold->value;
options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_AL_LONG;
- nRequest = 0;
- status = dbGetField(paddr, DBR_SHORT, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_SHORT, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
strncpy(pold->units, new.units, MAX_UNITS_SIZE);
@@ -581,10 +465,8 @@
pold->lower_warning_limit = new.lower_warning_limit;
pold->lower_alarm_limit = new.lower_alarm_limit;
options = 0;
- nRequest = no_elements;
status = dbGetField(paddr, DBR_SHORT, &pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
+ nRequest, pfl);
}
break;
case(oldDBR_GR_FLOAT):
@@ -597,13 +479,10 @@
DBRgrDouble
DBRalDouble
} new;
- dbr_float_t *pvalue = &pold->value;
options = DBR_STATUS | DBR_UNITS | DBR_PRECISION | DBR_GR_DOUBLE |
DBR_AL_DOUBLE;
- nRequest = 0;
- status = dbGetField(paddr, DBR_FLOAT, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_FLOAT, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
pold->precision = new.precision.dp;
@@ -616,10 +495,8 @@
pold->upper_warning_limit = epicsConvertDoubleToFloat(new.upper_warning_limit);
pold->lower_warning_limit = epicsConvertDoubleToFloat(new.lower_warning_limit);
options = 0;
- nRequest = no_elements;
status = dbGetField(paddr, DBR_FLOAT, &pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
+ nRequest, pfl);
}
break;
/* case(oldDBR_GR_ENUM): see oldDBR_CTRL_ENUM */
@@ -632,12 +509,9 @@
DBRgrLong
DBRalLong
} new;
- dbr_char_t *pvalue = &pold->value;
options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_AL_LONG;
- nRequest = 0;
- status = dbGetField(paddr, DBR_UCHAR, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_UCHAR, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
strncpy(pold->units, new.units, MAX_UNITS_SIZE);
@@ -649,10 +523,8 @@
pold->lower_warning_limit = new.lower_warning_limit;
pold->lower_alarm_limit = new.lower_alarm_limit;
options = 0;
- nRequest = no_elements;
status = dbGetField(paddr, DBR_UCHAR, &pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
+ nRequest, pfl);
}
break;
case(oldDBR_GR_LONG):
@@ -664,12 +536,9 @@
DBRgrLong
DBRalLong
} new;
- dbr_long_t *pvalue = &pold->value;
options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_AL_LONG;
- nRequest = 0;
- status = dbGetField(paddr, DBR_LONG, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_LONG, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
strncpy(pold->units, new.units, MAX_UNITS_SIZE);
@@ -681,10 +550,8 @@
pold->lower_warning_limit = new.lower_warning_limit;
pold->lower_alarm_limit = new.lower_alarm_limit;
options = 0;
- nRequest = no_elements;
status = dbGetField(paddr, DBR_LONG, &pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
+ nRequest, pfl);
}
break;
case(oldDBR_GR_DOUBLE):
@@ -697,13 +564,10 @@
DBRgrDouble
DBRalDouble
} new;
- dbr_double_t *pvalue = &pold->value;
options = DBR_STATUS | DBR_UNITS | DBR_PRECISION | DBR_GR_DOUBLE |
DBR_AL_DOUBLE;
- nRequest = 0;
- status = dbGetField(paddr, DBR_DOUBLE, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_DOUBLE, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
pold->precision = new.precision.dp;
@@ -716,10 +580,8 @@
pold->lower_warning_limit = new.lower_warning_limit;
pold->lower_alarm_limit = new.lower_alarm_limit;
options = 0;
- nRequest = no_elements;
status = dbGetField(paddr, DBR_DOUBLE, &pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
+ nRequest, pfl);
}
break;
@@ -734,13 +596,10 @@
DBRctrlLong
DBRalLong
} new;
- dbr_short_t *pvalue = &pold->value;
options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_CTRL_LONG |
DBR_AL_LONG;
- nRequest = 0;
- status = dbGetField(paddr, DBR_SHORT, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_SHORT, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
strncpy(pold->units, new.units, MAX_UNITS_SIZE);
@@ -754,10 +613,8 @@
pold->upper_ctrl_limit = new.upper_ctrl_limit;
pold->lower_ctrl_limit = new.lower_ctrl_limit;
options = 0;
- nRequest = no_elements;
status = dbGetField(paddr, DBR_SHORT, &pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
+ nRequest, pfl);
}
break;
case(oldDBR_CTRL_FLOAT):
@@ -771,13 +628,10 @@
DBRctrlDouble
DBRalDouble
} new;
- dbr_float_t *pvalue = &pold->value;
options = DBR_STATUS | DBR_UNITS | DBR_PRECISION | DBR_GR_DOUBLE |
DBR_CTRL_DOUBLE | DBR_AL_DOUBLE;
- nRequest = 0;
- status = dbGetField(paddr, DBR_FLOAT, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_FLOAT, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
pold->precision = new.precision.dp;
@@ -792,10 +646,8 @@
pold->upper_ctrl_limit = epicsConvertDoubleToFloat(new.upper_ctrl_limit);
pold->lower_ctrl_limit = epicsConvertDoubleToFloat(new.lower_ctrl_limit);
options = 0;
- nRequest = no_elements;
status = dbGetField(paddr, DBR_FLOAT, &pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
+ nRequest, pfl);
}
break;
case(oldDBR_GR_ENUM):
@@ -807,14 +659,11 @@
DBRenumStrs
} new;
short no_str;
- dbr_enum_t *pvalue = &pold->value;
memset(pold, '\0', sizeof(struct dbr_ctrl_enum));
/* first get status and severity */
options = DBR_STATUS | DBR_ENUM_STRS;
- nRequest = 0;
- status = dbGetField(paddr, DBR_ENUM, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_ENUM, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
no_str = new.no_str;
@@ -824,10 +673,8 @@
strncpy(pold->strs[i], new.strs[i], sizeof(pold->strs[i]));
/*now get values*/
options = 0;
- nRequest = no_elements;
status = dbGetField(paddr, DBR_ENUM, &pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
+ nRequest, pfl);
}
break;
case(oldDBR_CTRL_CHAR):
@@ -840,13 +687,10 @@
DBRctrlLong
DBRalLong
} new;
- dbr_char_t *pvalue = &pold->value;
options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_CTRL_LONG |
DBR_AL_LONG;
- nRequest = 0;
- status = dbGetField(paddr, DBR_UCHAR, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_UCHAR, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
strncpy(pold->units, new.units, MAX_UNITS_SIZE);
@@ -860,10 +704,8 @@
pold->upper_ctrl_limit = new.upper_ctrl_limit;
pold->lower_ctrl_limit = new.lower_ctrl_limit;
options = 0;
- nRequest = no_elements;
status = dbGetField(paddr, DBR_UCHAR, &pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
+ nRequest, pfl);
}
break;
case(oldDBR_CTRL_LONG):
@@ -876,13 +718,10 @@
DBRctrlLong
DBRalLong
} new;
- dbr_long_t *pvalue = &pold->value;
options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_CTRL_LONG |
DBR_AL_LONG;
- nRequest = 0;
- status = dbGetField(paddr, DBR_LONG, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_LONG, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
strncpy(pold->units, new.units, MAX_UNITS_SIZE);
@@ -896,10 +735,8 @@
pold->upper_ctrl_limit = new.upper_ctrl_limit;
pold->lower_ctrl_limit = new.lower_ctrl_limit;
options = 0;
- nRequest = no_elements;
status = dbGetField(paddr, DBR_LONG, &pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
+ nRequest, pfl);
}
break;
case(oldDBR_CTRL_DOUBLE):
@@ -913,13 +750,10 @@
DBRctrlDouble
DBRalDouble
} new;
- dbr_double_t *pvalue = &pold->value;
options = DBR_STATUS | DBR_UNITS | DBR_PRECISION | DBR_GR_DOUBLE |
DBR_CTRL_DOUBLE | DBR_AL_DOUBLE;
- nRequest = 0;
- status = dbGetField(paddr, DBR_DOUBLE, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_DOUBLE, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
pold->precision = new.precision.dp;
@@ -934,10 +768,8 @@
pold->upper_ctrl_limit = new.upper_ctrl_limit;
pold->lower_ctrl_limit = new.lower_ctrl_limit;
options = 0;
- nRequest = no_elements;
status = dbGetField(paddr, DBR_DOUBLE, &pold->value, &options,
- &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i] = 0;
+ nRequest, pfl);
}
break;
@@ -947,21 +779,16 @@
struct {
DBRstatus
} new;
- DBSTRING *pvalue = (DBSTRING *)(pold->value);
options = DBR_STATUS;
- nRequest = 0;
- status = dbGetField(paddr, DBR_STRING, &new, &options, &nRequest,
- pfl);
+ status = dbGetField(paddr, DBR_STRING, &new, &options, &zero, pfl);
pold->status = new.status;
pold->severity = new.severity;
pold->ackt = new.ackt;
pold->acks = new.acks;
options = 0;
- nRequest = no_elements;
status = dbGetField(paddr, DBR_STRING, pold->value,
- &options, &nRequest, pfl);
- for (i = nRequest; i < no_elements; i++) pvalue[i][0] = 0;
+ &options, nRequest, pfl);
}
break;
=== modified file 'src/db/db_access_routines.h'
--- src/db/db_access_routines.h 2002-07-12 21:35:43 +0000
+++ src/db/db_access_routines.h 2010-06-04 11:46:21 +0000
@@ -39,6 +39,9 @@
DBADDR *paddr, int src_type,const void *psrc, int no_elements);
epicsShareFunc int epicsShareAPI db_get_field(
DBADDR *paddr, int dest_type,void *pdest, int no_elements, void *pfl);
+epicsShareFunc int db_get_field_and_count(
+ struct dbAddr *paddr, int buffer_type,
+ void *pbuffer, long *nRequest, void *pfl);
#ifdef __cplusplus
=== modified file 'src/rsrv/camessage.c'
--- src/rsrv/camessage.c 2009-07-09 16:37:24 +0000
+++ src/rsrv/camessage.c 2010-06-04 11:46:21 +0000
@@ -530,12 +530,21 @@
cid = pciu->cid;
}
- status = cas_copy_in_header ( pClient, pevext->msg.m_cmmd, pevext->size,
- pevext->msg.m_dataType, pevext->msg.m_count, cid, pevext->msg.m_available,
+ /* If the client has requested a zero element count we interpret this as a
+ * request for all avaiable elements. In this case we initialise the
+ * header with the maximum element size specified by the database. */
+ int autosize = pevext->msg.m_count == 0;
+ long item_count =
+ autosize ? paddr->no_elements : pevext->msg.m_count;
+ ca_uint32_t payload_size = dbr_size_n(pevext->msg.m_dataType, item_count);
+ status = cas_copy_in_header(
+ pClient, pevext->msg.m_cmmd, payload_size,
+ pevext->msg.m_dataType, item_count, cid, pevext->msg.m_available,
&pPayload );
if ( status != ECA_NORMAL ) {
send_err ( &pevext->msg, status, pClient,
- "server unable to load read (or subscription update) response into protocol buffer PV=\"%s\" max bytes=%u",
+ "server unable to load read (or subscription update) response "
+ "into protocol buffer PV=\"%s\" max bytes=%u",
RECORD_NAME ( paddr ), rsrvSizeofLargeBufTCP );
if ( ! eventsRemaining )
cas_send_bs_msg ( pClient, FALSE );
@@ -554,8 +563,8 @@
return;
}
- status = db_get_field ( paddr, pevext->msg.m_dataType,
- pPayload, pevext->msg.m_count, pfl);
+ status = db_get_field_and_count(
+ paddr, pevext->msg.m_dataType, pPayload, &item_count, pfl);
if ( status < 0 ) {
/*
* I cant wait to redesign this protocol from scratch!
@@ -569,58 +578,52 @@
send_err ( &pevext->msg, ECA_GETFAIL, pClient, RECORD_NAME ( paddr ) );
}
else {
- /*
- * New clients recv the status of the
- * operation directly to the
+ /* New clients recv the status of the operation directly to the
* event/put/get callback.
*
- * Fetched value is set to zero in case they
- * use it even when the status indicates
- * failure.
+ * Fetched value is set to zero in case they use it even when the
+ * status indicates failure -- unless the client selected autosizing
+ * data, in which case they'd better know what they're doing!
*
- * The m_cid field in the protocol
- * header is abused to carry the status
- */
- memset ( pPayload, 0, pevext->size );
+ * The m_cid field in the protocol header is abused to carry the
+ * status */
+ if (autosize) {
+ payload_size = dbr_size_n(pevext->msg.m_dataType, 0);
+ cas_set_header_count(pClient, 0);
+ }
+ memset ( pPayload, 0, payload_size );
cas_set_header_cid ( pClient, ECA_GETFAIL );
- cas_commit_msg ( pClient, pevext->size );
+ cas_commit_msg ( pClient, payload_size );
}
}
else {
- ca_uint32_t payloadSize = pevext->size;
int cacStatus = caNetConvert (
pevext->msg.m_dataType, pPayload, pPayload,
- TRUE /* host -> net format */, pevext->msg.m_count );
- if ( cacStatus == ECA_NORMAL ) {
- /*
- * force string message size to be the true size rounded to even
- * boundary
- */
- if ( pevext->msg.m_dataType == DBR_STRING
- && pevext->msg.m_count == 1 ) {
- char * pStr = (char *) pPayload;
- size_t strcnt = strlen ( pStr );
- if ( strcnt < payloadSize ) {
- payloadSize = ( ca_uint32_t ) ( strcnt + 1u );
- }
- else {
- pStr[payloadSize-1] = '\0';
- errlogPrintf (
- "caserver: read_reply: detected DBR_STRING w/o nill termination "
- "in response from db_get_field, pPayload = \"%s\"\n",
- pStr );
- }
+ TRUE /* host -> net format */, item_count );
+ if ( cacStatus == ECA_NORMAL ) {
+ ca_uint32_t data_size =
+ dbr_size_n(pevext->msg.m_dataType, item_count);
+ if (autosize) {
+ payload_size = data_size;
+ cas_set_header_count(pClient, item_count);
}
+ else
+ memset(
+ (char *) pPayload + data_size, 0, payload_size - data_size);
}
else {
- memset ( pPayload, 0, payloadSize );
+ if (autosize) {
+ payload_size = dbr_size_n(pevext->msg.m_dataType, 0);
+ cas_set_header_count(pClient, 0);
+ }
+ memset ( pPayload, 0, payload_size );
cas_set_header_cid ( pClient, cacStatus );
- }
- cas_commit_msg ( pClient, payloadSize );
+ }
+ cas_commit_msg ( pClient, payload_size );
}
/*
- * Ensures timely response for events, but does que
+ * Ensures timely response for events, but does queue
* them up like db requests when the OPI does not keep up.
*/
if ( ! eventsRemaining )
=== modified file 'src/rsrv/caserverio.c'
--- src/rsrv/caserverio.c 2006-11-20 16:10:02 +0000
+++ src/rsrv/caserverio.c 2010-06-04 11:46:21 +0000
@@ -33,6 +33,10 @@
#define epicsExportSharedSymbols
#include "server.h"
+/* As an optimisation, any message allocated with a large header is resized to
+ * use a small header if the payload size is below this threshold. */
+#define SMALL_MESSAGE_THRESHOLD 65
+
/*
* cas_send_bs_msg()
*
@@ -292,32 +296,25 @@
}
}
- if ( alignedPayloadSize < 0xffff && nElem < 0xffff ) {
- caHdr *pMsg = ( caHdr * ) &pclient->send.buf[pclient->send.stk];
- pMsg->m_cmmd = htons ( response );
- pMsg->m_postsize = htons ( ( ( ca_uint16_t ) alignedPayloadSize ) );
- pMsg->m_dataType = htons ( dataType );
- pMsg->m_count = htons ( ( ( ca_uint16_t ) nElem ) );
- pMsg->m_cid = htonl ( cid );
- pMsg->m_available = htonl ( responseSpecific );
- if ( ppPayload ) {
- *ppPayload = ( void * ) ( pMsg + 1 );
- }
+ caHdr *pMsg = (caHdr *) &pclient->send.buf[pclient->send.stk];
+ pMsg->m_cmmd = htons(response);
+ pMsg->m_dataType = htons(dataType);
+ pMsg->m_cid = htonl(cid);
+ pMsg->m_available = htonl(responseSpecific);
+ if (alignedPayloadSize < 0xffff && nElem < 0xffff) {
+ pMsg->m_postsize = htons(((ca_uint16_t) alignedPayloadSize));
+ pMsg->m_count = htons(((ca_uint16_t) nElem));
+ if (ppPayload)
+ *ppPayload = (void *) (pMsg + 1);
}
else {
- caHdr *pMsg = ( caHdr * ) &pclient->send.buf[pclient->send.stk];
- ca_uint32_t *pW32 = ( ca_uint32_t * ) ( pMsg + 1 );
- pMsg->m_cmmd = htons ( response );
- pMsg->m_postsize = htons ( 0xffff );
- pMsg->m_dataType = htons ( dataType );
- pMsg->m_count = htons ( 0u );
- pMsg->m_cid = htonl ( cid );
- pMsg->m_available = htonl ( responseSpecific );
- pW32[0] = htonl ( alignedPayloadSize );
- pW32[1] = htonl ( nElem );
- if ( ppPayload ) {
- *ppPayload = ( void * ) ( pW32 + 2 );
- }
+ ca_uint32_t *pW32 = (ca_uint32_t *) (pMsg + 1);
+ pMsg->m_postsize = htons(0xffff);
+ pMsg->m_count = htons(0u);
+ pW32[0] = htonl(alignedPayloadSize);
+ pW32[1] = htonl(nElem);
+ if (ppPayload)
+ *ppPayload = (void *) (pW32 + 2);
}
/* zero out pad bytes */
@@ -336,6 +333,20 @@
pMsg->m_cid = htonl ( cid );
}
+void cas_set_header_count (struct client *pClient, ca_uint32_t count)
+{
+ caHdr *pMsg = (caHdr *) &pClient->send.buf[pClient->send.stk];
+ if (pMsg->m_postsize == htons(0xffff)) {
+ assert(pMsg->m_count == 0);
+ ca_uint32_t *pLW = (ca_uint32_t *) (pMsg + 1);
+ pLW[1] = htonl(count);
+ }
+ else {
+ assert(count < 65536);
+ pMsg->m_count = htons((ca_uint16_t) count);
+ }
+}
+
void cas_commit_msg ( struct client *pClient, ca_uint32_t size )
{
caHdr * pMsg = ( caHdr * ) &pClient->send.buf[pClient->send.stk];
@@ -343,8 +354,19 @@
if ( pMsg->m_postsize == htons ( 0xffff ) ) {
ca_uint32_t * pLW = ( ca_uint32_t * ) ( pMsg + 1 );
assert ( size <= ntohl ( *pLW ) );
- pLW[0] = htonl ( size );
- size += sizeof ( caHdr ) + 2 * sizeof ( *pLW );
+ if (size < SMALL_MESSAGE_THRESHOLD) {
+ /* If the message is sufficiently small it can be worth converting a
+ * large message header into a small header. This saves us all of 8
+ * bytes over the wire, so it's not such a big deal. */
+ pMsg->m_postsize = htons((ca_uint16_t) size);
+ pMsg->m_count = htons((ca_uint16_t) ntohl(pLW[1]));
+ memmove(pLW, pLW + 2, size);
+ size += sizeof(caHdr);
+ }
+ else {
+ pLW[0] = htonl ( size );
+ size += sizeof ( caHdr ) + 2 * sizeof ( *pLW );
+ }
}
else {
assert ( size <= ntohs ( pMsg->m_postsize ) );
=== modified file 'src/rsrv/server.h'
--- src/rsrv/server.h 2009-07-09 16:37:24 +0000
+++ src/rsrv/server.h 2010-06-04 11:46:21 +0000
@@ -29,7 +29,7 @@
#include "asLib.h"
#include "dbAddr.h"
#include "dbNotify.h"
-#define CA_MINOR_PROTOCOL_REVISION 11
+#define CA_MINOR_PROTOCOL_REVISION 12
#include "caProto.h"
#include "ellLib.h"
#include "epicsTime.h"
@@ -228,6 +228,7 @@
ca_uint16_t dataType, ca_uint32_t nElem, ca_uint32_t cid,
ca_uint32_t responseSpecific, void **pPayload );
void cas_set_header_cid ( struct client *pClient, ca_uint32_t );
+void cas_set_header_count (struct client *pClient, ca_uint32_t count);
void cas_commit_msg ( struct client *pClient, ca_uint32_t size );
#endif /*INCLserverh*/
- Replies:
- Re: [Merge] lp:~michael-abbott/epics-base/dynamic-array into lp:epics-base Michael Abbott
- Re: [Merge] lp:~michael-abbott/epics-base/dynamic-array into lp:epics-base Michael Abbott
- Re: [Merge] lp:~michael-abbott/epics-base/dynamic-array into lp:epics-base Jeff Hill
- Re: [Merge] lp:~michael-abbott/epics-base/dynamic-array into lp:epics-base Michael Abbott
- Navigate by Date:
- Prev:
RE: Hacking rsrv/camessage.c michael.abbott
- Next:
Re: [Merge] lp:~michael-abbott/epics-base/dynamic-array into lp:epics-base 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 3/4] Add autosizing array support for caget and camonitor. Michael Abbott
- Next:
Re: [Merge] lp:~michael-abbott/epics-base/dynamic-array into lp:epics-base 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
|