- 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;
}
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;
}

10
ascon.h
View File

@ -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

View File

@ -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);
}

View File

@ -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

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 \
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 \

1
ofac.c
View File

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

View File

@ -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;
}
}

View File

@ -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