From 95881525e5af771c45a14f50e86e68ee5840586a Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Fri, 27 Apr 2012 13:25:16 -0400 Subject: [PATCH] Add sync plugin that uses the db state --- src/ioc/db/Makefile | 1 + src/ioc/db/filters/filters.dbd | 1 + src/ioc/db/filters/sync.c | 170 +++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+) create mode 100644 src/ioc/db/filters/sync.c diff --git a/src/ioc/db/Makefile b/src/ioc/db/Makefile index c18b605b4..4db814b4a 100644 --- a/src/ioc/db/Makefile +++ b/src/ioc/db/Makefile @@ -91,4 +91,5 @@ dbCore_SRCS += dbState.c dbCore_SRCS += ts.c dbCore_SRCS += dbnd.c dbCore_SRCS += arr.c +dbCore_SRCS += sync.c diff --git a/src/ioc/db/filters/filters.dbd b/src/ioc/db/filters/filters.dbd index 48cd94cd3..7fb0c5133 100644 --- a/src/ioc/db/filters/filters.dbd +++ b/src/ioc/db/filters/filters.dbd @@ -1,3 +1,4 @@ registrar(tsInitialize) registrar(dbndInitialize) registrar(arrInitialize) +registrar(syncInitialize) diff --git a/src/ioc/db/filters/sync.c b/src/ioc/db/filters/sync.c new file mode 100644 index 000000000..33b059151 --- /dev/null +++ b/src/ioc/db/filters/sync.c @@ -0,0 +1,170 @@ +/*************************************************************************\ +* Copyright (c) 2010 Brookhaven National Laboratory. +* Copyright (c) 2010 Helmholtz-Zentrum Berlin +* fuer Materialien und Energie GmbH. +* EPICS BASE is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ + +/* + * Author: Ralph Lange + */ + +#include + +#include "epicsExport.h" +#include "freeList.h" +#include "db_field_log.h" +#include "chfPlugin.h" +#include "dbState.h" + +#define STATE_NAME_LENGTH 20 + +static const +chfPluginEnumType modeEnum[] = { {"before", 0}, {"first", 1}, + {"last", 2}, {"after", 3}, + {"while", 4}, {"unless", 5}, + {NULL,0} }; +typedef enum syncMode { + syncModeBefore=0, + syncModeFirst=1, + syncModeLast=2, + syncModeAfter=3, + syncModeWhile=4, + syncModeUnless=5 +} syncMode; + +typedef struct myStruct { + syncMode mode; + char state[STATE_NAME_LENGTH]; + dbStateId id; + db_field_log *lastfl; + int laststate:1; +} myStruct; + +static void *myStructFreeList; + +static const +chfPluginArgDef opts[] = { + chfEnum (myStruct, mode, "m", 1, 1, modeEnum), + chfString (myStruct, state, "s", 1, 0), + chfPluginArgEnd +}; + +static void * allocPvt(void) +{ + myStruct *my = (myStruct*) freeListCalloc(myStructFreeList); + return (void *) my; +} + +static void freePvt(void *pvt) +{ + freeListFree(myStructFreeList, pvt); +} + +static int parse_ok(void *pvt) +{ + myStruct *my = (myStruct*) pvt; + + if (!(my->id = dbStateFind(my->state))) + return -1; + + return 0; +} + +static db_field_log* filter(void* pvt, dbChannel *chan, db_field_log *pfl) { + if (pfl->ctx == dbfl_context_read) + return pfl; + + db_field_log *passfl = NULL; + myStruct *my = (myStruct*) pvt; + int actstate = dbStateGet(my->id); + + switch (my->mode) { + case syncModeBefore: + if (actstate && !my->laststate) { + passfl = my->lastfl; + my->lastfl = NULL; + } + break; + case syncModeFirst: + if (actstate && !my->laststate) { + passfl = pfl; + pfl = NULL; + } + break; + case syncModeLast: + if (!actstate && my->laststate) { + passfl = my->lastfl; + my->lastfl = NULL; + } + break; + case syncModeAfter: + if (!actstate && my->laststate) { + passfl = pfl; + pfl = NULL; + } + break; + case syncModeWhile: + if (actstate) { + passfl = pfl; + } + goto no_shift; + case syncModeUnless: + if (!actstate) { + passfl = pfl; + } + goto no_shift; + } + + if (my->lastfl) + db_delete_field_log(my->lastfl); + my->lastfl = pfl; + my->laststate = actstate; + + no_shift: + return passfl; +} + +static void channelRegisterPre(dbChannel *chan, void *pvt, + chPostEventFunc **cb_out, void **arg_out, db_field_log *probe) +{ + *cb_out = filter; + *arg_out = pvt; +} + +static void channel_report(dbChannel *chan, void *pvt, int level, const unsigned short indent) +{ + myStruct *my = (myStruct*) pvt; + printf("%*s plugin sync, mode=%s, state=%s\n", indent, "", + chfPluginEnumString(modeEnum, my->mode, "n/a"), my->state); +} + +static chfPluginIf pif = { + allocPvt, + freePvt, + + NULL, /* parse_error, */ + parse_ok, + + NULL, /* channel_open, */ + channelRegisterPre, + NULL, /* channelRegisterPost, */ + channel_report, + NULL /* channel_close */ +}; + +static void syncInitialize(void) +{ + static int firstTime = 1; + + if (!firstTime) return; + firstTime = 0; + + if (!myStructFreeList) + freeListInitPvt(&myStructFreeList, sizeof(myStruct), 64); + + chfPluginRegister("sync", &pif, opts); +} + +epicsExportRegistrar(syncInitialize);