- added scriptcontext.h
- killing a node using sct should now be safe - sctdrive adapter object might be dynamic - default for the checkstatus script: returning the status property - introduced <sctcon> unpoll - changed <sctcon> queuecon to <sctcon> send - some more improvements in sct
This commit is contained in:
92
devser.c
92
devser.c
@ -26,8 +26,8 @@ struct DevSer {
|
||||
DevAction *actions; /* the action queue */
|
||||
SchedHeader *headers;
|
||||
ErrMsg *errmsg;
|
||||
int killMe;
|
||||
int steps;
|
||||
int stopTask;
|
||||
};
|
||||
|
||||
static char *devPrio[NumberOfPRIO] = {
|
||||
@ -59,10 +59,14 @@ static void DevFreeActionList(DevAction *actions) {
|
||||
}
|
||||
}
|
||||
|
||||
static void DevKillTask(void *devser) {
|
||||
if(devser != NULL){
|
||||
DevKill(devser);
|
||||
}
|
||||
static void DevKillTask(void *ds) {
|
||||
DevSer *devser = ds;
|
||||
|
||||
if (devser->stopTask) {
|
||||
free(devser);
|
||||
} else {
|
||||
devser->stopTask = 1;
|
||||
}
|
||||
}
|
||||
|
||||
DevAction *DevNextAction(DevSer *devser) {
|
||||
@ -83,8 +87,12 @@ DevAction *DevNextAction(DevSer *devser) {
|
||||
if (header->followingAction == NULL) {
|
||||
if (now >= header->timeDue) {
|
||||
header->followingAction = header->actions;
|
||||
header->timeDue = (floor(now / header->interval) + 1)
|
||||
* header->interval;
|
||||
if (header->interval <= 0) {
|
||||
header->timeDue = now;
|
||||
} else {
|
||||
header->timeDue = (floor(now / header->interval) + 1)
|
||||
* header->interval;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (header->followingAction != NULL) {
|
||||
@ -110,7 +118,7 @@ int DevQueueTask(void *ds) {
|
||||
char *replyData;
|
||||
|
||||
if (devser->steps == 0) return 1;
|
||||
if (devser->killMe) {
|
||||
if (devser->stopTask) {
|
||||
return 0;
|
||||
}
|
||||
action = devser->current;
|
||||
@ -128,9 +136,9 @@ int DevQueueTask(void *ds) {
|
||||
devser->steps--;
|
||||
}
|
||||
if(status == AsconFailure){
|
||||
replyData = devser->errmsg->text;
|
||||
replyData = devser->errmsg->text;
|
||||
} else {
|
||||
replyData = AsconRead(devser->asyncConn);
|
||||
replyData = AsconRead(devser->asyncConn);
|
||||
}
|
||||
sendData = action->hdl(action->data, replyData);
|
||||
if (sendData != NULL) {
|
||||
@ -163,7 +171,7 @@ DevSer *DevMake(SConnection *con, int argc, char *argv[]) {
|
||||
devser->killCurrent = 0;
|
||||
devser->actions = NULL;
|
||||
devser->headers = NULL;
|
||||
devser->killMe = 0;
|
||||
devser->stopTask = 0;
|
||||
devser->steps = -1; /* no debugging by default */
|
||||
TaskRegister(pServ->pTasker, DevQueueTask, NULL, DevKillTask, devser, 0);
|
||||
return devser;
|
||||
@ -200,7 +208,11 @@ void DevKill(DevSer *devser) {
|
||||
DevFreeActionList(victim->actions);
|
||||
free(victim);
|
||||
}
|
||||
devser->killMe = 1;
|
||||
if (devser->stopTask) {
|
||||
free(devser);
|
||||
} else {
|
||||
devser->stopTask = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void DevQueue(DevSer *devser, void *actionData, DevPrio prio,
|
||||
@ -213,7 +225,7 @@ void DevQueue(DevSer *devser, void *actionData, DevPrio prio,
|
||||
if (prio >= NumberOfPRIO) prio = NumberOfPRIO - 1;
|
||||
ptr2Last = &devser->actions;
|
||||
for (action = devser->actions; action != NULL && action->prio >= prio; action = action->next) {
|
||||
if (matchFunc(actionData, action->data) && action->hdl == hdl) {
|
||||
if (action->hdl == hdl && matchFunc(actionData, action->data)) {
|
||||
return; /* there is already an identic action */
|
||||
}
|
||||
ptr2Last = &action->next;
|
||||
@ -234,11 +246,15 @@ int DevUnschedule(DevSer *devser, void *actionData,
|
||||
for (header = devser->headers; header != NULL; header = header->next) {
|
||||
ptr2Last = &header->actions;
|
||||
for (action = header->actions; action != NULL; action = *ptr2Last) {
|
||||
if (matchFunc(actionData, action->data) && action->hdl == hdl) {
|
||||
if (action->hdl == hdl && matchFunc(actionData, action->data)) {
|
||||
if (action == header->followingAction) {
|
||||
/* advance followingAction if equal*/
|
||||
header->followingAction = action->next;
|
||||
}
|
||||
if (action == devser->current) {
|
||||
devser->current = NULL;
|
||||
devser->killCurrent = 0; /* should already be 0 */
|
||||
}
|
||||
cnt++;
|
||||
/* remove from list */
|
||||
*ptr2Last = action->next;
|
||||
@ -252,20 +268,21 @@ int DevUnschedule(DevSer *devser, void *actionData,
|
||||
return cnt;
|
||||
}
|
||||
|
||||
void DevSchedule(DevSer *devser, void *actionData,
|
||||
DevPrio prio, double interval,
|
||||
DevActionHandler hdl, DevActionMatch *matchFunc,
|
||||
DevKillActionData *killFunc) {
|
||||
int DevSchedule(DevSer *devser, void *actionData,
|
||||
DevPrio prio, double interval,
|
||||
DevActionHandler hdl, DevActionMatch *matchFunc,
|
||||
DevKillActionData *killFunc) {
|
||||
SchedHeader *header = NULL;
|
||||
SchedHeader **ptr2LastHeader = NULL;
|
||||
SchedHeader *newHeader;
|
||||
DevAction *action = NULL;
|
||||
DevAction **ptr2Last = NULL;
|
||||
DevAction *newAction;
|
||||
int ret;
|
||||
|
||||
if (prio <= NullPRIO) prio = NullPRIO + 1;
|
||||
if (prio >= NumberOfPRIO) prio = NumberOfPRIO - 1;
|
||||
DevUnschedule(devser, actionData, hdl, matchFunc);
|
||||
ret = DevUnschedule(devser, actionData, hdl, matchFunc);
|
||||
|
||||
newAction = DevNewAction(actionData, hdl, killFunc, prio);
|
||||
/* find matching header */
|
||||
@ -279,7 +296,7 @@ void DevSchedule(DevSer *devser, void *actionData,
|
||||
}
|
||||
*ptr2Last = newAction;
|
||||
assert(newAction->next == NULL);
|
||||
return;
|
||||
return ret;
|
||||
} else if (header->prio < newAction->prio ||
|
||||
(header->prio == newAction->prio
|
||||
&& header->interval > interval)) {
|
||||
@ -304,5 +321,38 @@ void DevSchedule(DevSer *devser, void *actionData,
|
||||
newHeader->next = header;
|
||||
newHeader->timeDue = DoubleTime() + interval;
|
||||
*ptr2LastHeader = newHeader;
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int DevRemoveAction(DevSer *devser, void *actionData) {
|
||||
SchedHeader *header = NULL;
|
||||
DevAction **ptr2Last = NULL;
|
||||
DevAction *action = NULL;
|
||||
int cnt=0;
|
||||
|
||||
/* Remove current action, if matched. If a reply is pending, the next action will
|
||||
get the reply. But as in the inital state no reply is expected, this should not harm. */
|
||||
action = devser->current;
|
||||
if (action != NULL && actionData == action->data) {
|
||||
if (devser->killCurrent) {
|
||||
if (action->kill != NULL) action->kill(action->data);
|
||||
devser->killCurrent = 0;
|
||||
free(action);
|
||||
}
|
||||
devser->current = NULL;
|
||||
}
|
||||
/* remove from queue */
|
||||
ptr2Last = &devser->actions;
|
||||
for (action = devser->actions; action != NULL; action = action->next) {
|
||||
if (actionData == action->data) {
|
||||
cnt++;
|
||||
/* remove from list */
|
||||
*ptr2Last = action->next;
|
||||
if (action->kill != NULL) action->kill(action->data);
|
||||
free(action);
|
||||
} else {
|
||||
ptr2Last = &action->next;
|
||||
}
|
||||
}
|
||||
return cnt++;
|
||||
}
|
||||
|
Reference in New Issue
Block a user