diff --git a/ascon.c b/ascon.c index 0e66da8c..d5d5f96a 100644 --- a/ascon.c +++ b/ascon.c @@ -447,9 +447,9 @@ int AsconStdHandler(Ascon * a) return 1; } if(a->lineCount == 0){ - a->noResponse = 1; + a->noResponse = 1; } else { - a->noResponse = 0; + a->noResponse = 0; } break; /* go to the base handler */ case AsconReading: @@ -834,3 +834,9 @@ char *AsconHostport(Ascon *a) return a->hostport; } +double AsconGetSetTimeout(Ascon *a, double timeout, int setmode) { + if (setmode) { + a->timeout = timeout; + } + return a->timeout; +} diff --git a/ascon.h b/ascon.h index 3a46deec..1065e23e 100644 --- a/ascon.h +++ b/ascon.h @@ -107,4 +107,14 @@ int AsconLastState(Ascon *a); * \return the host and port */ char *AsconHostport(Ascon *a); + +/** + * \brief set or get timeout + * \param a the Ascon + * \param timeout the timeout to set + * \param setmode 0: get, 1: set + * \return the timeout value + */ +double AsconGetSetTimeout(Ascon *a, double timeout, int setmode); + #endif diff --git a/devser.c b/devser.c index e4df4b31..506a168e 100644 --- a/devser.c +++ b/devser.c @@ -23,7 +23,9 @@ struct DevSer { DevAction *toKill; /* list of actions to be killed */ int steps; AsconStatus status; - double startTime; /* fields for statistics */ + + /* fields for statistics: */ + double startTime; double comCount; long nComCount; int comMaxState; @@ -595,3 +597,7 @@ char *DevStatus(DevSer *devser) { } return str; } + +double DevGetSetTimeout(DevSer *devser, double timeout, int setmode) { + return AsconGetSetTimeout(devser->ascon, timeout, setmode); +} diff --git a/devser.h b/devser.h index 9f77b784..b91e8f51 100644 --- a/devser.h +++ b/devser.h @@ -198,4 +198,13 @@ char *DevHostport(DevSer *devser); */ char *DevStatus(DevSer *devser); +/** + * \brief set or get timeout + * \param devser The device serializer to change + * \param timeout the timeout to set + * \param setmode 0: get, 1: set + * \return the timeout value + */ +double DevGetSetTimeout(DevSer *devser, double timeout, int setmode); + #endif diff --git a/make_gen b/make_gen index 70253df2..7c710e42 100644 --- a/make_gen +++ b/make_gen @@ -35,7 +35,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \ savehdb.o statusfile.o sicshdbfactory.o proxy.o devser.o \ moregress.o multicounter.o regresscter.o histregress.o \ sicshdbadapter.o polldriv.o sicspoll.o statemon.o hmslave.o \ - nwatch.o asyncqueue.o asyncprotocol.o sicsobj.o frame.o\ + nwatch.o asyncqueue.o asyncprotocol.o sicsobj.o frame.o syncedprot.o\ nxcopy.o nxinterhelper.o nxinter_wrap.o nxstack.o arrayutil.o \ sctdriveadapter.o sctdriveobj.o reflist.o singlex.o fourmess.o \ sgclib.o sgfind.o sgio.o sgsi.o sghkl.o singlediff.o singlebi.o \ diff --git a/ofac.c b/ofac.c index 25fec993..760a7695 100644 --- a/ofac.c +++ b/ofac.c @@ -42,6 +42,7 @@ static void InitGeneral(void) INIT(HelpInit); INIT(AddTestProt); INIT(AddGenBinProtocoll); + INIT(AddSyncedProt); INIT(MakeTrace); INIT(SiteInit); /* site specific initializations */ } diff --git a/scriptcontext.c b/scriptcontext.c index 1a8d5b18..f3a7b62d 100644 --- a/scriptcontext.c +++ b/scriptcontext.c @@ -13,9 +13,9 @@ #include "devser.h" #include "ascon.h" #include "macro.h" +#include "syncedprot.h" #include "scriptcontext.h" - typedef struct ContextItem { struct ContextItem *next; Hdb *node; @@ -46,6 +46,7 @@ typedef struct SctData { int answered; int inMacro; Hdb *node; + long syncid; } SctData; /* data for updatescript */ @@ -54,6 +55,7 @@ typedef struct SctUpdatescript { SctController *controller; } SctUpdatescript; + static ScriptContext *sct = NULL; static SctData *queueData = NULL; @@ -335,7 +337,7 @@ int SctCallInContext(SConnection * con, char *script, Hdb * node, char *result = NULL; int iRet = 1; int verbose = controller->verbose; - + PushContext(node, controller); if (verbose) { SCPrintf(con, eLog, "%6.3f script: %s", secondsOfMinute(), script); @@ -428,7 +430,7 @@ static char *SctActionHandler(void *actionData, char *lastReply, script = NULL; if (!commError && controller->verbose && lastReply != NULL && *lastReply != '\0') { - SCPrintf(con, eLog, "%6.3f reply : %s\n", secondsOfMinute(), lastReply); + SCPrintf(con, eLog, "%6.3f reply : %s\n", secondsOfMinute(), lastReply); } if(!commError && controller->fd != NULL && lastReply != NULL && *lastReply != '\0'){ fprintf(controller->fd, "%6.3f reply : %s\n", secondsOfMinute(), lastReply); @@ -480,7 +482,9 @@ static char *SctActionHandler(void *actionData, char *lastReply, script = strdup(script); sct->sendNode = node; sct->sendCalled = 0; + SyncedBegin(data->syncid); ret = SctCallInContext(con, script, node, controller, &result); + SyncedEnd(data->syncid); sct->sendNode = NULL; if (ret == 0) { /* @@ -652,6 +656,17 @@ static char * SctDataInfo(void *d) return strdup(text); } +static void SctEndData(void *d) +{ + /* no kill, only decrement sync counter */ + SctData *data = d; + + if (data->syncid > 0) { + SyncedDecr(data->syncid); + data->syncid = SYNCED_NO_ID; + } +} + /* * This is the callback for all nodes participating in the * scriptcontext system @@ -766,7 +781,7 @@ static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData, SetHdbProperty(node, "target", GetCharArray(text)); SetHdbProperty(node, "requested", GetCharArray(text)); - /* call check script, if available */ + /* call check script, if available */ script = GetProp(node, data->controller->node, "check"); if (script != NULL) { if (SctCallInContext(con, script, node, data->controller, &error) == @@ -814,9 +829,10 @@ static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData, data->answered = 0; data->inMacro = SCinMacro(con); tracePar(node->name,"Queued %s to %s",node->name, GetCharArray(text)); + data->syncid = SyncedIncr(0); DevQueue(data->controller->devser, data, prio, - SctWriteHandler, SctMatch, NULL, SctDataInfo); - /* no kill function in DevQueue: data is owned by the node (callback list) */ + SctWriteHandler, SctMatch, SctEndData, SctDataInfo); + /* kill function SctEndData does not kill, data is owned by the node (callback list) */ DeleteDynString(text); return hdbContinue; } @@ -885,6 +901,11 @@ static void SctKillData(void *d) { SctData *data = d; + if (data->syncid > 0) { + SyncedDecr(data->syncid); + data->syncid = SYNCED_NO_ID; + } + if (data->name) { free(data->name); data->name = NULL; @@ -909,7 +930,7 @@ int SctAddPollNode(SctController * controller, Hdb * node, double interval, { SctData *data; hdbCallback *cb; - + if (!FindHdbCallbackData(node, controller)) { cb = MakeHipadabaCallback(SctMainCallback, controller, NULL); assert(cb); @@ -924,9 +945,13 @@ int SctAddPollNode(SctController * controller, Hdb * node, double interval, data->conCtx = NULL; /* we might need a dummy connection here */ data->name = strdup(action); - return DevSchedule(controller->devser, data, prio, interval, - SctActionHandler, SctMatch, SctKillData, SctDataInfo); - + data->syncid = SyncedIncr(0); + if (DevSchedule(controller->devser, data, prio, interval, + SctActionHandler, SctMatch, SctKillData, SctDataInfo)) { + return 1; + } else { + return 0; + } } static int SctPollCmd(pSICSOBJ ccmd, SConnection * con, @@ -1118,6 +1143,8 @@ void SctQueueNode(SctController * controller, Hdb * node, data->conCtx = NULL; data->answered = 1; + data->syncid = SyncedIncr(0); + if (DevQueue(data->controller->devser, data, prio, SctWriteHandler, SctMatch, SctKillData, SctDataInfo)) { if (con != NULL) { @@ -1452,21 +1479,16 @@ static int SctTransactCmd(pSICSOBJ ccmd, SConnection * con, st->command = strdup(par[0]->value.v.text); st->controller = c; st->sent = 0; - + st->reply = NULL; + DevQueue(c->devser, st, WritePRIO, TransactionHandler, SctTransactMatch, NULL, NULL); while (st->sent != 2) { TaskYield(pServ->pTasker); - /* - * This is definitly shit: it will free the st pointer, - * which makes memory corruption when the queued task finally - * runs. I have commented it out for now. See if this test - * is needed at all. Other options include: - * - dequeuing the transaction from the DevQueue - * - writing an error message and return. This causes a little - * memory leak but as interrupts are not frequent this may be OK + /* not yet tested: if (SCGetInterrupt(con) != eContinue) { - break; + DevUnschedule(c->devser, st, TransactionHandler, SctTransactMatch); + break; } */ } @@ -1587,6 +1609,19 @@ static int SctHostport(pSICSOBJ ccmd, SConnection * con, return 1; } +static int SctTimeout(pSICSOBJ ccmd, SConnection * con, + Hdb * cmdNode, Hdb * par[], int nPar) +{ + SctController *c; + char *result; + hdbValue *v = &cmdNode->child->value; + + c = (SctController *) ccmd->pPrivate; + v->v.doubleValue = DevGetSetTimeout(c->devser, v->v.doubleValue, nPar); + SCPrintf(con, eValue, "%.6g", v->v.doubleValue); + return 1; +} + static int SctStatus(pSICSOBJ ccmd, SConnection * con, Hdb * cmdNode, Hdb * par[], int nPar) { @@ -1739,6 +1774,7 @@ static int SctMakeController(SConnection * con, SicsInterp * sics, controller->devser = DevMake(con, argc - 2, argv + 2); if (!controller->devser) return 0; + SetHdbProperty(controller->node, "controllerName", objName); SetHdbProperty(controller->node, "sicsdev", objName); @@ -1818,6 +1854,13 @@ static int SctMakeController(SConnection * con, SicsInterp * sics, cmd = AddSICSHdbPar(controller->node, "status", usSpy, MakeSICSFunc(SctStatus)); + cmd = AddSICSHdbPar(controller->node, + "timeout", usSpy, MakeSICSFunc(SctTimeout)); + AddSICSHdbPar(cmd, "value", usUser, MakeHdbFloat(-1.0)); + + /* get the actual timeout value */ + SctTimeout(ccmd, con, cmd, &par, 0); + cb = MakeHipadabaCallback(SctDebugCallback, controller, NULL); if (cb) AppendHipadabaCallback(par, cb); @@ -1861,19 +1904,3 @@ int SctVerbose(SctController * c) return c->verbose; } -int SctIsPending(SctController *controller, Hdb * node, char *name, int kind) -{ - void *currentAction; - - SctData data; - data.node = node; - data.name = name; - switch (kind) { - case 0: - return DevIsPending(controller->devser, &data, SctWriteHandler, SctMatch); - case 1: - return DevIsPending(controller->devser, &data, SctActionHandler, SctMatch); - default: - return 0; - } -} diff --git a/scriptcontext.h b/scriptcontext.h index 16da7595..5e71c0a3 100644 --- a/scriptcontext.h +++ b/scriptcontext.h @@ -36,14 +36,4 @@ int SctCallInContext(SConnection * con, char *script, Hdb * node, */ int SctVerbose(SctController * c); - -/** - * check if the specified action is pending - * \param controller the SctController - * \param node the node - * \param name the action - * \param kind 0 for queued action, 1 for polled action - * \return 1 for pending, 0 for not pending - */ -int SctIsPending(SctController *controller, Hdb * node, char *name, int kind); #endif