- 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:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user