- ascon.c: bug fix

- binprot.c: enhancements
- devser.c, scriptcontext.c: introduced specifiaction of start time in poll
This commit is contained in:
2017-04-07 10:10:10 +02:00
parent c4cee85b57
commit 10cb44df85
5 changed files with 286 additions and 100 deletions

View File

@ -76,26 +76,17 @@ static void DevFreeActionList(DevAction * actions)
}
}
static double nextTime(double due,
double lastInterval,
double now,
double interval) {
double base;
/* nextTime gives the next possible time according to the
* following rules:
* (1) result > now
* (2) result is a multiple of interval
* (3) result >= due OR result >= due - lastInterval + interval
*/
if (interval > lastInterval) {
base = due - lastInterval * 0.01;
} else {
base = due - lastInterval + interval * 0.99;
}
if (now > base) {
base = now;
}
return (floor(base / interval) + 1) * interval;
static double nextDue(double due, double now, double interval) {
/* calculate next due value. the phase is rounded to usec in order to
prevent phase drifts by summed rounding errors
*/
double p; /* phase */
if (interval <= 0) return now;
if (now < due) return due;
p = round(fmod(due, interval)*1e6)/1e6;
return p + interval * floor((due-p)/interval + (now-due)/interval + 1.000001);
}
@ -124,7 +115,7 @@ static DevAction *DevNextAction(DevSer * devser)
action->timeDue = now;
} else {
/* increase timeDue according to interval */
action->timeDue = nextTime(0, 0, now, action->interval);
action->timeDue = nextDue(action->timeDue, now, action->interval);
}
prio = action->prio;
@ -243,9 +234,9 @@ int DevQueueTask(void *ds)
action = DevNextAction(devser);
}
StartAscon(devser);
devser->status = AsconTask(devser->ascon);
while (action != NULL) {
StartAscon(devser);
devser->status = AsconTask(devser->ascon);
AsconLog(devser);
if (devser->status >= AsconFailure) {
replyData = AsconGetError(devser->ascon);
@ -272,7 +263,11 @@ int DevQueueTask(void *ds)
}
sendData = action->hdl(action->data, replyData, (devser->status != AsconReady));
if (sendData != NULL) {
AsconWrite(devser->ascon, sendData, 0);
devser->status = AsconWrite(devser->ascon, sendData, 0);
if (devser->status >= AsconFailure) {
replyData = AsconGetError(devser->ascon);
continue;
}
LogStart(devser);
return 1;
}
@ -284,6 +279,8 @@ int DevQueueTask(void *ds)
devser->current = NULL;
}
action = DevNextAction(devser);
StartAscon(devser);
devser->status = AsconTask(devser->ascon);
}
return 1;
}
@ -391,8 +388,8 @@ int DevUnschedule(DevSer * devser, void *callData,
return cnt;
}
int DevSchedule(DevSer * devser, void *actionData,
DevPrio prio, double interval,
int DevScheduleS(DevSer * devser, void *actionData,
DevPrio prio, double interval, double start,
DevActionHandler * hdl, DevActionMatch * matchFunc,
DevKillActionData * killFunc, DevInfoFunc * infoFunc)
{
@ -454,6 +451,7 @@ int DevSchedule(DevSer * devser, void *actionData,
action->kill = killFunc;
action->infoFunc = infoFunc;
action->timeDue = 0;
action->interval = 0;
ret = 1;
}
@ -468,22 +466,31 @@ int DevSchedule(DevSer * devser, void *actionData,
if (interval < 0) { /* case "queued" */
action->interval = -1.0;
} else { /* case "scheduled" */
if (action->timeDue == 0) { /* not yet scheduled: do it immediately */
action->timeDue = DoubleTime();
} else { /* calculate next time */
action->timeDue = nextTime(action->timeDue, action->interval,
DoubleTime(), interval);
}
/* nextDue calculates the next due date after the last call
however, it returns the 'start' value
- when this is a new action and start > 0
- when the presumed last call time is bigger the 'start' value
*/
action->timeDue = nextDue(start, action->timeDue - action->interval, interval);
action->interval = interval;
}
return ret; /* when 0, actionData was killed */
}
int DevSchedule(DevSer * devser, void *actionData,
DevPrio prio, double interval,
DevActionHandler * hdl, DevActionMatch * matchFunc,
DevKillActionData * killFunc, DevInfoFunc * infoFunc)
{
return DevScheduleS(devser, actionData, prio, interval, 0.0,
hdl, matchFunc, killFunc, infoFunc);
}
int DevQueue(DevSer * devser, void *actionData, DevPrio prio,
DevActionHandler * hdl, DevActionMatch * matchFunc,
DevKillActionData * killFunc, DevInfoFunc *infoFunc)
{
return DevSchedule(devser, actionData, prio, -1.0, hdl
return DevScheduleS(devser, actionData, prio, -1.0, 0.0, hdl
, matchFunc, killFunc, infoFunc);
}
@ -559,7 +566,7 @@ char * DevList(DevSer * devser) {
DynStringConcat(result, str);
free(str);
} else {
snprintf(text, sizeof text, "%8.8lx", (unsigned long)action->data);
snprintf(text, sizeof text, "%p", action->data);
DynStringConcat(result, text);
}
DynStringConcat(result, "\n");