- ascon.c: bug fix
- binprot.c: enhancements - devser.c, scriptcontext.c: introduced specifiaction of start time in poll
This commit is contained in:
75
devser.c
75
devser.c
@ -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");
|
||||
|
Reference in New Issue
Block a user