Hi,

I'm currently trying something with timeouts but I run into some problems:

I've got some functions that are to be called when a specific timeout
is no longer scheduled (i. e. has run through).  If the other timeout
is still scheduled (checked with AG_TimeoutIsScheduled), the function
execution is deferred by some ival to try again later.

Under some conditions this mechanism locks up, however. Even though
the one function does not reverse depend on the other. (A depends on
B's timeout, but B doesn't depend on A).

This scheduling order doesn't cause a lockup but the callbacks are
called in the wrong order:

AG_ScheduleTimeout(NULL, pTimeoutA, 1);

This is the list of ticks of the currently scheduled timeouts in the
queue afterwards (to->ticks of each timeout):
(4442776)

AG_ScheduleTimeout(NULL, pTimeoutB, 2000);

The new list of ticks of the scheduled timeouts: (4449696 4442776)  As
you can see, the timeout that should be executed later is on the head
of the tailqueue.

My trace reads that the callback for timeoutB is called before that of
timeoutA, even though timeoutA was both scheduled earlier and has the
smaller ival.

Now the combination that locks up, scheduling the other way around:

AG_ScheduleTimeout(NULL, pTimeoutB, 2000);
AG_ScheduleTimeout(NULL, pTimeoutA, 1);

ticks in the timeout tailqueue: (6049273 6051271). This time the order
is correct or better still correct.  The first value belongs to
timeoutA.

The function for timeoutA is called first and rescheduled until the
2000 ticks are over, because A depends on B.  But even when the 2000
have passed, timeoutA is always rescheduled on the head of the
tailqueue (pushed to its head).  That means after 2000 ticks the ticks
of the timeout on the head of the queue are greater than the following
ones, again.

AG_ProcessEvents now checks for the first timeout, which is timeoutA,
and runs it's function.  Because timeoutB is still scheduled, timeoutA
is rescheduled  but is added on the head of the timeout tailqueue
again by AG_ScheduleTimeout.  AG_ProcessEvents does now its goto pop;
and checks the first timeout from the queue, which is timeoutA again
but this time with its ticks in the future.  That's why timeoutB's
function is never called and timeoutA waits forever.

I can't imagine that AG_ScheduleTimeout works correctly here when it
always adds at the head of the timeout queue regardless of the ticks
differences.  But maybe I got the interface wrong... in the latter
case, can you give me any hints please, what I could do instead?

I'm afraid that it's not useful to post my code, since it's Lisp code
that calls Agar's functions and the timeout checking and rescheduling
is somewhat spread, it would need a while to explain what every macro
and function involved does.  But so far I assume that to be correct, I
really wonder about the timeout tailqueue and the order of it's
elements.

Jakob
_______________________________________________
Agar mailing list
[email protected]
http://libagar.org/lists.html

Reply via email to