Add function to dbChannel.c to create a db_field_log copy of array/string data

This commit is contained in:
Ralph Lange
2012-04-27 13:22:00 -04:00
committed by Michael Davidsaver
parent e67ef8a005
commit d2abc71527
4 changed files with 48 additions and 55 deletions

View File

@@ -22,6 +22,7 @@
#include "dbBase.h"
#include "dbEvent.h"
#include "link.h"
#include <freeList.h>
#include "dbAccessDefs.h"
#include "dbLock.h"
#include "dbStaticLib.h"
@@ -43,6 +44,16 @@ typedef struct parseContext {
#define CALLIF(rtn) !rtn ? parse_stop : rtn
static void *dbchStringFreeList;
void dbChannelInit (void)
{
if (!dbchStringFreeList) {
freeListInitPvt(&dbchStringFreeList,
sizeof(epicsOldString), 128);
}
}
static void chf_value(parseContext *parser, parse_result *presult)
{
chFilter *filter = parser->filter;
@@ -676,6 +687,38 @@ void dbChannelDelete(dbChannel *chan)
free(chan); // FIXME: Use free-list
}
static void freeArray(db_field_log *pfl) {
if (pfl->field_type == DBF_STRING && pfl->no_elements == 1) {
freeListFree(dbchStringFreeList, pfl->u.r.field);
} else {
free(pfl->u.r.field);
}
}
void dbChannelMakeArrayCopy(void *pvt, db_field_log *pfl, dbChannel *chan)
{
void *p;
if (!pfl->type == dbfl_type_rec) return;
struct dbCommon *prec = dbChannelRecord(chan);
pfl->type = dbfl_type_ref;
pfl->stat = prec->stat;
pfl->sevr = prec->sevr;
pfl->time = prec->time;
pfl->field_type = chan->addr.field_type;
pfl->no_elements = chan->addr.no_elements;
pfl->field_size = chan->addr.field_size;
pfl->u.r.dtor = freeArray;
pfl->u.r.pvt = pvt;
if (pfl->field_type == DBF_STRING && pfl->no_elements == 1) {
p = freeListCalloc(dbchStringFreeList);
} else {
p = calloc(pfl->no_elements, pfl->field_size);
}
if (p) dbGet(&chan->addr, mapDBFToDBR[pfl->field_type], p, NULL, &pfl->no_elements, NULL);
pfl->u.r.field = p;
}
/* FIXME: Do these belong in a different file? */

View File

@@ -137,6 +137,7 @@ struct chFilter {
struct dbCommon;
struct dbFldDes;
epicsShareFunc void dbChannelInit (void);
epicsShareFunc long dbChannelTest(const char *name);
epicsShareFunc dbChannel * dbChannelCreate(const char *name);
epicsShareFunc long dbChannelOpen(dbChannel *chan);
@@ -171,6 +172,7 @@ epicsShareFunc void dbRegisterFilter(const char *key, const chFilterIf *fif, voi
epicsShareFunc db_field_log* dbChannelRunPreChain(dbChannel *chan, db_field_log *pLogIn);
epicsShareFunc db_field_log* dbChannelRunPostChain(dbChannel *chan, db_field_log *pLogIn);
epicsShareFunc const chFilterPlugin * dbFindFilter(const char *key, size_t len);
epicsShareFunc void dbChannelMakeArrayCopy(void *pvt, db_field_log *pfl, dbChannel *chan);
#ifdef __cplusplus
}

View File

@@ -11,43 +11,10 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <epicsExport.h>
#include <freeList.h>
#include <chfPlugin.h>
#include <db_field_log.h>
#include <dbAccessDefs.h>
#include <dbCommon.h>
static short mapDBFToDBR[DBF_NTYPES] = {
/* DBF_STRING => */ DBR_STRING,
/* DBF_CHAR => */ DBR_CHAR,
/* DBF_UCHAR => */ DBR_UCHAR,
/* DBF_SHORT => */ DBR_SHORT,
/* DBF_USHORT => */ DBR_USHORT,
/* DBF_LONG => */ DBR_LONG,
/* DBF_ULONG => */ DBR_ULONG,
/* DBF_FLOAT => */ DBR_FLOAT,
/* DBF_DOUBLE => */ DBR_DOUBLE,
/* DBF_ENUM, => */ DBR_ENUM,
/* DBF_MENU, => */ DBR_ENUM,
/* DBF_DEVICE => */ DBR_ENUM,
/* DBF_INLINK => */ DBR_STRING,
/* DBF_OUTLINK => */ DBR_STRING,
/* DBF_FWDLINK => */ DBR_STRING,
/* DBF_NOACCESS => */ DBR_NOACCESS
};
static void *tsStringFreeList;
void freeArray(db_field_log *pfl) {
if (pfl->field_type == DBF_STRING && pfl->no_elements == 1) {
freeListFree(tsStringFreeList, pfl->u.r.field);
} else {
free(pfl->u.r.field);
}
}
static db_field_log* tsFilter(void* pvt, dbChannel *chan, db_field_log *pfl) {
epicsTimeStamp now;
@@ -55,23 +22,7 @@ static db_field_log* tsFilter(void* pvt, dbChannel *chan, db_field_log *pfl) {
/* If string or array, must make a copy (to ensure coherence between time and data) */
if (pfl->type == dbfl_type_rec) {
void *p;
struct dbCommon *prec = dbChannelRecord(chan);
pfl->type = dbfl_type_ref;
pfl->stat = prec->stat;
pfl->sevr = prec->sevr;
pfl->field_type = chan->addr.field_type;
pfl->no_elements = chan->addr.no_elements;
pfl->field_size = chan->addr.field_size;
pfl->u.r.dtor = freeArray;
pfl->u.r.pvt = pvt;
if (pfl->field_type == DBF_STRING && pfl->no_elements == 1) {
p = freeListCalloc(tsStringFreeList);
} else {
p = calloc(pfl->no_elements, pfl->field_size);
}
if (p) dbGet(&chan->addr, mapDBFToDBR[pfl->field_type], p, NULL, &pfl->no_elements, NULL);
pfl->u.r.field = p;
dbChannelMakeArrayCopy(pvt, pfl, chan);
}
pfl->time = now;
@@ -112,11 +63,6 @@ static void tsInitialize(void)
if(!firstTime) return;
firstTime = 0;
if (!tsStringFreeList) {
freeListInitPvt(&tsStringFreeList,
sizeof(epicsOldString), 64);
}
chfPluginRegister("ts", &tsPif, NULL);
}

View File

@@ -58,6 +58,7 @@
#include "initHooks.h"
#include "epicsExit.h"
#include "epicsSignal.h"
#include "dbChannel.h"
#define epicsExportSharedSymbols
#include "epicsRelease.h"
@@ -460,6 +461,7 @@ static void doInitRecord1(dbRecordType *pdbRecordType, dbCommon *precord,
static void initDatabase(void)
{
dbChannelInit();
iterateRecords(doInitRecord0, NULL);
iterateRecords(doResolveLinks, NULL);
iterateRecords(doInitRecord1, NULL);