- added command to change timeout of a scriptcontext controller

- created syncedprot
This commit is contained in:
zolliker
2012-08-21 06:44:29 +00:00
parent d70dffa00b
commit caf31b36cc
8 changed files with 99 additions and 50 deletions

10
ascon.c
View File

@ -447,9 +447,9 @@ int AsconStdHandler(Ascon * a)
return 1; return 1;
} }
if(a->lineCount == 0){ if(a->lineCount == 0){
a->noResponse = 1; a->noResponse = 1;
} else { } else {
a->noResponse = 0; a->noResponse = 0;
} }
break; /* go to the base handler */ break; /* go to the base handler */
case AsconReading: case AsconReading:
@ -834,3 +834,9 @@ char *AsconHostport(Ascon *a)
return a->hostport; return a->hostport;
} }
double AsconGetSetTimeout(Ascon *a, double timeout, int setmode) {
if (setmode) {
a->timeout = timeout;
}
return a->timeout;
}

10
ascon.h
View File

@ -107,4 +107,14 @@ int AsconLastState(Ascon *a);
* \return the host and port * \return the host and port
*/ */
char *AsconHostport(Ascon *a); 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 #endif

View File

@ -23,7 +23,9 @@ struct DevSer {
DevAction *toKill; /* list of actions to be killed */ DevAction *toKill; /* list of actions to be killed */
int steps; int steps;
AsconStatus status; AsconStatus status;
double startTime; /* fields for statistics */
/* fields for statistics: */
double startTime;
double comCount; double comCount;
long nComCount; long nComCount;
int comMaxState; int comMaxState;
@ -595,3 +597,7 @@ char *DevStatus(DevSer *devser) {
} }
return str; return str;
} }
double DevGetSetTimeout(DevSer *devser, double timeout, int setmode) {
return AsconGetSetTimeout(devser->ascon, timeout, setmode);
}

View File

@ -198,4 +198,13 @@ char *DevHostport(DevSer *devser);
*/ */
char *DevStatus(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 #endif

View File

@ -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 \ savehdb.o statusfile.o sicshdbfactory.o proxy.o devser.o \
moregress.o multicounter.o regresscter.o histregress.o \ moregress.o multicounter.o regresscter.o histregress.o \
sicshdbadapter.o polldriv.o sicspoll.o statemon.o hmslave.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 \ nxcopy.o nxinterhelper.o nxinter_wrap.o nxstack.o arrayutil.o \
sctdriveadapter.o sctdriveobj.o reflist.o singlex.o fourmess.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 \ sgclib.o sgfind.o sgio.o sgsi.o sghkl.o singlediff.o singlebi.o \

1
ofac.c
View File

@ -42,6 +42,7 @@ static void InitGeneral(void)
INIT(HelpInit); INIT(HelpInit);
INIT(AddTestProt); INIT(AddTestProt);
INIT(AddGenBinProtocoll); INIT(AddGenBinProtocoll);
INIT(AddSyncedProt);
INIT(MakeTrace); INIT(MakeTrace);
INIT(SiteInit); /* site specific initializations */ INIT(SiteInit); /* site specific initializations */
} }

View File

@ -13,9 +13,9 @@
#include "devser.h" #include "devser.h"
#include "ascon.h" #include "ascon.h"
#include "macro.h" #include "macro.h"
#include "syncedprot.h"
#include "scriptcontext.h" #include "scriptcontext.h"
typedef struct ContextItem { typedef struct ContextItem {
struct ContextItem *next; struct ContextItem *next;
Hdb *node; Hdb *node;
@ -46,6 +46,7 @@ typedef struct SctData {
int answered; int answered;
int inMacro; int inMacro;
Hdb *node; Hdb *node;
long syncid;
} SctData; } SctData;
/* data for updatescript */ /* data for updatescript */
@ -54,6 +55,7 @@ typedef struct SctUpdatescript {
SctController *controller; SctController *controller;
} SctUpdatescript; } SctUpdatescript;
static ScriptContext *sct = NULL; static ScriptContext *sct = NULL;
static SctData *queueData = NULL; static SctData *queueData = NULL;
@ -335,7 +337,7 @@ int SctCallInContext(SConnection * con, char *script, Hdb * node,
char *result = NULL; char *result = NULL;
int iRet = 1; int iRet = 1;
int verbose = controller->verbose; int verbose = controller->verbose;
PushContext(node, controller); PushContext(node, controller);
if (verbose) { if (verbose) {
SCPrintf(con, eLog, "%6.3f script: %s", secondsOfMinute(), script); SCPrintf(con, eLog, "%6.3f script: %s", secondsOfMinute(), script);
@ -428,7 +430,7 @@ static char *SctActionHandler(void *actionData, char *lastReply,
script = NULL; script = NULL;
if (!commError && controller->verbose && lastReply != NULL if (!commError && controller->verbose && lastReply != NULL
&& *lastReply != '\0') { && *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'){ if(!commError && controller->fd != NULL && lastReply != NULL && *lastReply != '\0'){
fprintf(controller->fd, "%6.3f reply : %s\n", secondsOfMinute(), lastReply); fprintf(controller->fd, "%6.3f reply : %s\n", secondsOfMinute(), lastReply);
@ -480,7 +482,9 @@ static char *SctActionHandler(void *actionData, char *lastReply,
script = strdup(script); script = strdup(script);
sct->sendNode = node; sct->sendNode = node;
sct->sendCalled = 0; sct->sendCalled = 0;
SyncedBegin(data->syncid);
ret = SctCallInContext(con, script, node, controller, &result); ret = SctCallInContext(con, script, node, controller, &result);
SyncedEnd(data->syncid);
sct->sendNode = NULL; sct->sendNode = NULL;
if (ret == 0) { if (ret == 0) {
/* /*
@ -652,6 +656,17 @@ static char * SctDataInfo(void *d)
return strdup(text); 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 * This is the callback for all nodes participating in the
* scriptcontext system * scriptcontext system
@ -766,7 +781,7 @@ static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData,
SetHdbProperty(node, "target", GetCharArray(text)); SetHdbProperty(node, "target", GetCharArray(text));
SetHdbProperty(node, "requested", GetCharArray(text)); SetHdbProperty(node, "requested", GetCharArray(text));
/* call check script, if available */ /* call check script, if available */
script = GetProp(node, data->controller->node, "check"); script = GetProp(node, data->controller->node, "check");
if (script != NULL) { if (script != NULL) {
if (SctCallInContext(con, script, node, data->controller, &error) == if (SctCallInContext(con, script, node, data->controller, &error) ==
@ -814,9 +829,10 @@ static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData,
data->answered = 0; data->answered = 0;
data->inMacro = SCinMacro(con); data->inMacro = SCinMacro(con);
tracePar(node->name,"Queued %s to %s",node->name, GetCharArray(text)); tracePar(node->name,"Queued %s to %s",node->name, GetCharArray(text));
data->syncid = SyncedIncr(0);
DevQueue(data->controller->devser, data, prio, DevQueue(data->controller->devser, data, prio,
SctWriteHandler, SctMatch, NULL, SctDataInfo); SctWriteHandler, SctMatch, SctEndData, SctDataInfo);
/* no kill function in DevQueue: data is owned by the node (callback list) */ /* kill function SctEndData does not kill, data is owned by the node (callback list) */
DeleteDynString(text); DeleteDynString(text);
return hdbContinue; return hdbContinue;
} }
@ -885,6 +901,11 @@ static void SctKillData(void *d)
{ {
SctData *data = d; SctData *data = d;
if (data->syncid > 0) {
SyncedDecr(data->syncid);
data->syncid = SYNCED_NO_ID;
}
if (data->name) { if (data->name) {
free(data->name); free(data->name);
data->name = NULL; data->name = NULL;
@ -909,7 +930,7 @@ int SctAddPollNode(SctController * controller, Hdb * node, double interval,
{ {
SctData *data; SctData *data;
hdbCallback *cb; hdbCallback *cb;
if (!FindHdbCallbackData(node, controller)) { if (!FindHdbCallbackData(node, controller)) {
cb = MakeHipadabaCallback(SctMainCallback, controller, NULL); cb = MakeHipadabaCallback(SctMainCallback, controller, NULL);
assert(cb); 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->conCtx = NULL; /* we might need a dummy connection here */
data->name = strdup(action); data->name = strdup(action);
return DevSchedule(controller->devser, data, prio, interval, data->syncid = SyncedIncr(0);
SctActionHandler, SctMatch, SctKillData, SctDataInfo); if (DevSchedule(controller->devser, data, prio, interval,
SctActionHandler, SctMatch, SctKillData, SctDataInfo)) {
return 1;
} else {
return 0;
}
} }
static int SctPollCmd(pSICSOBJ ccmd, SConnection * con, static int SctPollCmd(pSICSOBJ ccmd, SConnection * con,
@ -1118,6 +1143,8 @@ void SctQueueNode(SctController * controller, Hdb * node,
data->conCtx = NULL; data->conCtx = NULL;
data->answered = 1; data->answered = 1;
data->syncid = SyncedIncr(0);
if (DevQueue(data->controller->devser, data, prio, if (DevQueue(data->controller->devser, data, prio,
SctWriteHandler, SctMatch, SctKillData, SctDataInfo)) { SctWriteHandler, SctMatch, SctKillData, SctDataInfo)) {
if (con != NULL) { if (con != NULL) {
@ -1452,21 +1479,16 @@ static int SctTransactCmd(pSICSOBJ ccmd, SConnection * con,
st->command = strdup(par[0]->value.v.text); st->command = strdup(par[0]->value.v.text);
st->controller = c; st->controller = c;
st->sent = 0; st->sent = 0;
st->reply = NULL;
DevQueue(c->devser, st, WritePRIO, DevQueue(c->devser, st, WritePRIO,
TransactionHandler, SctTransactMatch, NULL, NULL); TransactionHandler, SctTransactMatch, NULL, NULL);
while (st->sent != 2) { while (st->sent != 2) {
TaskYield(pServ->pTasker); TaskYield(pServ->pTasker);
/* /* not yet tested:
* 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
if (SCGetInterrupt(con) != eContinue) { 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; 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, static int SctStatus(pSICSOBJ ccmd, SConnection * con,
Hdb * cmdNode, Hdb * par[], int nPar) 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); controller->devser = DevMake(con, argc - 2, argv + 2);
if (!controller->devser) if (!controller->devser)
return 0; return 0;
SetHdbProperty(controller->node, "controllerName", objName); SetHdbProperty(controller->node, "controllerName", objName);
SetHdbProperty(controller->node, "sicsdev", objName); SetHdbProperty(controller->node, "sicsdev", objName);
@ -1818,6 +1854,13 @@ static int SctMakeController(SConnection * con, SicsInterp * sics,
cmd = AddSICSHdbPar(controller->node, cmd = AddSICSHdbPar(controller->node,
"status", usSpy, MakeSICSFunc(SctStatus)); "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); cb = MakeHipadabaCallback(SctDebugCallback, controller, NULL);
if (cb) if (cb)
AppendHipadabaCallback(par, cb); AppendHipadabaCallback(par, cb);
@ -1861,19 +1904,3 @@ int SctVerbose(SctController * c)
return c->verbose; 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;
}
}

View File

@ -36,14 +36,4 @@ int SctCallInContext(SConnection * con, char *script, Hdb * node,
*/ */
int SctVerbose(SctController * c); 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 #endif