- Connections write timeouts were incorrectly handled in asynnetc. Fixed.

- Implemented the desired run/drive behaviour: drive waits for what it started
  run starts, and success waits for everything to finish. This required
  changes to a lot of files.
- Fixed a bug in remob which supressed required messages
This commit is contained in:
koennecke
2009-04-17 12:52:01 +00:00
parent 50b0a5c4a7
commit 99d2485d22
39 changed files with 422 additions and 200 deletions

View File

@@ -304,7 +304,9 @@ static int SctMatch(void *data1, void *data2)
return a->node == b->node && strcasecmp(a->name, b->name) == 0;
}
/*
* This routine is running the script chain
*/
static char *SctActionHandler(void *actionData, char *lastReply,
int commError)
{
@@ -335,18 +337,41 @@ static char *SctActionHandler(void *actionData, char *lastReply,
} else {
con = controller->conn;
}
/*
* If this is a followup call, the I/O system will have set the
* property result to the data from the device. Read this now and
* print it if diagnostics is required.
*/
SetProp(node, controller->node, "result", lastReply);
script = NULL;
if (!commError && controller->verbose && lastReply != NULL
&& *lastReply != '\0') {
SCPrintf(con, eLog, "reply : %s", lastReply);
}
/*
* When this is a followup, we use the content of the
* state field as the property storing the next script to
* run. If this is the start of a chain this is set to the
* data->name which is either read or write
*/
state = GetProp(node, controller->node, "state");
if (state == NULL || strcasecmp(state, "idle") == 0) {
state = data->name;
SetProp(node, controller->node, "state", state);
}
/*
* Sometimes one wishes to call multiple scripts in succession
* before returning into I/O. Such scripts then do not set the
* send property. The loop is taking care of this. Not more
* then 10 scripts can be changed in this way.
*/
for (i = 0; i < 10; i++) {
/*
* read the script to invoke from the property living
* in state
*/
script = GetProp(node, controller->node, state);
if (script == NULL)
script = state;
@@ -357,12 +382,18 @@ static char *SctActionHandler(void *actionData, char *lastReply,
script = errorScript;
commError = 0;
}
/*
* Set the context and invoke the script
*/
script = strdup(script);
sct->sendNode = node;
sct->sendCalled = 0;
ret = SctCallInContext(con, script, node, controller, &result);
sct->sendNode = NULL;
if (ret == 0) {
/*
* an error occurred in the script: complain bitterly
*/
snprintf(eprop, sizeof eprop, "error_during_%s", data->name);
emsg = GetHdbProp(node, eprop);
if (emsg == NULL || con != controller->conn) {
@@ -392,13 +423,24 @@ static char *SctActionHandler(void *actionData, char *lastReply,
free(script);
goto finish;
}
/*
* The script executed OK.
* The next state is the result
*/
state = result;
/*
* if the new state is idle, clean everything up
* and terminate the script chain
*/
if (strcasecmp(state, "idle") == 0 || strcasecmp(state, "unpoll") == 0) {
/*
* send an O.k. if there was no othe rreply on write's
*/
if (queueData == data && !data->answered) {
if (queueData->inMacro == 0) {
iMacro = SCinMacro(con);
con->iMacro = 0;
SCWrite(con, "o.k.", eWarning);
SCWrite(con, "o.k.", eValue);
SCsetMacro(con, iMacro);
}
}
@@ -418,9 +460,16 @@ static char *SctActionHandler(void *actionData, char *lastReply,
free(script);
goto finish;
}
/*
* set the state property to the next state for
* the next invocation of this routine
*/
SetProp(node, controller->node, "state", state);
free(script);
script = NULL;
/*
* If there is data to send, check it and do so
*/
if (sct->sendCalled) {
send = GetProp(node, controller->node, "send");
if (send == NULL)
@@ -470,6 +519,10 @@ static int SctMatchNode(void *vNode, void *vData)
return node == d->node;
}
/*
* This is the read callback for nodes particpating in the
* scriptcontext system
*/
static hdbCallbackReturn SctMainCallback(Hdb * node, void *userData,
hdbMessage * msg)
{
@@ -530,7 +583,10 @@ static hdbCallbackReturn SctMainCallback(Hdb * node, void *userData,
return hdbContinue;
}
/*
* This is the callback registered for nodes which
* are written too.
*/
static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData,
hdbMessage * msg)
{
@@ -602,6 +658,9 @@ static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData,
prio = WritePRIO;
}
/*
* check for duplicate sets on a node.
*/
if (data->conCtx != NULL) {
if (data->inMacro == 0) {
GetHdbPath(node, path, sizeof path);
@@ -610,6 +669,11 @@ static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData,
"%s target changed to %s before completion", path,
GetCharArray(text));
}
/*
* the node has already been queued for execution. But as we never
* know if the script chain is already running, the only clean
* solution is to requeue the node.
*/
SCDeleteConnection(data->conCtx);
}
DeleteDynString(text);
@@ -624,11 +688,11 @@ static hdbCallbackReturn SctActionCallback(Hdb * node, void *userData,
mm = GetHdbUpdateMessage(msg);
if (mm != NULL) {
if (queueData != NULL && queueData->conCtx != NULL && !data->answered) {
if (queueData != NULL && queueData->conCtx != NULL && queueData->answered != 1) {
/* update called from a write action */
text = formatValue(*(mm->v), node);
if (queueData->inMacro == 0 && queueData->node == node) {
data->answered = 1;
queueData->answered = 1;
iMacro = SCinMacro(queueData->conCtx);
SCsetMacro(queueData->conCtx, 0);
sicsCommand = GetHdbProp(node, "sicscommand");
@@ -915,7 +979,8 @@ void SctQueueNode(SctController * controller, Hdb * node,
data->node = node;
data->name = strdup(action);
data->conCtx = NULL;
data->answered = 1;
if (!DevQueue(data->controller->devser, data, prio,
SctWriteHandler, SctMatch, SctKillData)) {
if (data->name != NULL) {