diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 9bffde2c2..bb62368fc 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -15,6 +15,22 @@ EPICS Base 3.15.0.x releases are not intended for use in production systems.
Array data can now be moved, without copying, into and out of the VAL field +of the waveform, aai, and aao record types by replacing the pointer in BPTR. +The basic rules which device support must follow are:
+ +The new header file epicsSpin.h adds a portable spin-locks API which is diff --git a/src/ioc/db/dbAccess.c b/src/ioc/db/dbAccess.c index 82aa18c11..c4661d9e1 100644 --- a/src/ioc/db/dbAccess.c +++ b/src/ioc/db/dbAccess.c @@ -780,6 +780,7 @@ long dbGet(DBADDR *paddr, short dbrType, void *pbuffer, long *options, long *nRequest, void *pflin) { char *pbuf = pbuffer; + void *pfieldsave; db_field_log *pfl = (db_field_log *)pflin; short field_type; long no_elements; @@ -815,6 +816,13 @@ long dbGet(DBADDR *paddr, short dbrType, return S_db_badDbrtype; } + /* For array field, the rset function + * get_array_info() is allowed to modify + * paddr->pfield. So we store the original + * value and restore it later. + */ + pfieldsave = paddr->pfield; + /* check for array */ if ((!pfl || pfl->type == dbfl_type_rec) && paddr->special == SPC_DBADDR && @@ -860,7 +868,8 @@ long dbGet(DBADDR *paddr, short dbrType, sprintf(message, "dbGet: Missing conversion for [%d][%d]\n", field_type, dbrType); recGblDbaddrError(S_db_badDbrtype, paddr, message); - return S_db_badDbrtype; + status = S_db_badDbrtype; + goto done; } /* convert database field and place it in the buffer */ if (n <= 0) { @@ -880,6 +889,8 @@ long dbGet(DBADDR *paddr, short dbrType, status = convert(&localAddr, pbuf, n, no_elements, offset); } } +done: + paddr->pfield = pfieldsave; return status; } diff --git a/src/std/filters/arr.c b/src/std/filters/arr.c index 201118d24..f2f5f82f1 100644 --- a/src/std/filters/arr.c +++ b/src/std/filters/arr.c @@ -104,7 +104,9 @@ static db_field_log* filter(void* pvt, dbChannel *chan, db_field_log *pfl) { if (chan->addr.special == SPC_DBADDR && nSource > 1 && (prset = dbGetRset(&chan->addr)) && - prset->get_array_info) { + prset->get_array_info) + { + void *pfieldsave = chan->addr.pfield; prec = dbChannelRecord(chan); dbScanLock(prec); prset->get_array_info(&chan->addr, &nSource, &offset); @@ -126,6 +128,7 @@ static db_field_log* filter(void* pvt, dbChannel *chan, db_field_log *pfl) { pfl->u.r.field = pdst; } dbScanUnlock(prec); + chan->addr.pfield = pfieldsave; } /* Extract from buffer */ diff --git a/src/std/rec/aaiRecord.c b/src/std/rec/aaiRecord.c index 428916de9..96e0960ce 100644 --- a/src/std/rec/aaiRecord.c +++ b/src/std/rec/aaiRecord.c @@ -183,7 +183,6 @@ static long cvt_dbaddr(DBADDR *paddr) { aaiRecord *prec = (aaiRecord *)paddr->precord; - paddr->pfield = prec->bptr; paddr->no_elements = prec->nelm; paddr->field_type = prec->ftvl; paddr->field_size = dbValueSize(prec->ftvl); @@ -195,6 +194,7 @@ static long get_array_info(DBADDR *paddr, long *no_elements, long *offset) { aaiRecord *prec = (aaiRecord *)paddr->precord; + paddr->pfield = prec->bptr; *no_elements = prec->nord; *offset = 0; return 0; @@ -308,7 +308,7 @@ static void monitor(aaiRecord *prec) } if (monitor_mask) - db_post_events(prec, prec->bptr, monitor_mask); + db_post_events(prec, &prec->val, monitor_mask); } static long readValue(aaiRecord *prec) diff --git a/src/std/rec/aaoRecord.c b/src/std/rec/aaoRecord.c index 46c837310..ca26aac52 100644 --- a/src/std/rec/aaoRecord.c +++ b/src/std/rec/aaoRecord.c @@ -183,7 +183,6 @@ static long cvt_dbaddr(DBADDR *paddr) { aaoRecord *prec = (aaoRecord *)paddr->precord; - paddr->pfield = prec->bptr; paddr->no_elements = prec->nelm; paddr->field_type = prec->ftvl; paddr->field_size = dbValueSize(prec->ftvl); @@ -195,6 +194,7 @@ static long get_array_info(DBADDR *paddr, long *no_elements, long *offset) { aaoRecord *prec = (aaoRecord *)paddr->precord; + paddr->pfield = prec->bptr; *no_elements = prec->nord; *offset = 0; return 0; @@ -308,7 +308,7 @@ static void monitor(aaoRecord *prec) } if (monitor_mask) - db_post_events(prec, prec->bptr, monitor_mask); + db_post_events(prec, &prec->val, monitor_mask); } static long writeValue(aaoRecord *prec) diff --git a/src/std/rec/waveformRecord.c b/src/std/rec/waveformRecord.c index 76e06a681..0818fa983 100644 --- a/src/std/rec/waveformRecord.c +++ b/src/std/rec/waveformRecord.c @@ -163,7 +163,6 @@ static long cvt_dbaddr(DBADDR *paddr) { waveformRecord *prec = (waveformRecord *) paddr->precord; - paddr->pfield = prec->bptr; paddr->no_elements = prec->nelm; paddr->field_type = prec->ftvl; paddr->field_size = dbValueSize(prec->ftvl); @@ -176,6 +175,7 @@ static long get_array_info(DBADDR *paddr, long *no_elements, long *offset) { waveformRecord *prec = (waveformRecord *) paddr->precord; + paddr->pfield = prec->bptr; *no_elements = prec->nord; *offset = 0; @@ -300,7 +300,7 @@ static void monitor(waveformRecord *prec) } if (monitor_mask) { - db_post_events(prec, prec->bptr, monitor_mask); + db_post_events(prec, &prec->val, monitor_mask); } }