From 9b5f866c6d8b5cbd80d79ab0d7ce5b85d706c608 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 9 Jan 2011 17:44:53 +0000 Subject: [PATCH] realtime: movpos: need to cope with reentrant calls to method_change_done, since FSQ does it --- hostside/movpos.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/hostside/movpos.c b/hostside/movpos.c index bfb29a4..4bbc7f7 100644 --- a/hostside/movpos.c +++ b/hostside/movpos.c @@ -18,6 +18,7 @@ typedef struct MovPosChange { Segment *move; /* everything beyond here is private for indep */ MovPosComb actual, target; + int refcount; int n_changes; Change *changes[]; } Indep; @@ -35,9 +36,9 @@ static void method_change_done(Method *m, Change *chg); * has been done. The method-independent code will take care of * updating move->movposcomb. etc. * - * REENTRANCY: must NOT be called from within a call to the method's - * execute() (and of course cannot legally be called from within - * prepare, consider, check or dispose). + * REENTRANCY: May be called from within a call to the method's + * execute(). Of course cannot legally be called from within + * prepare, consider, check or dispose. */ @@ -604,7 +605,6 @@ typedef struct NomoveChange { typedef struct { Method m; - unsigned eventqueued:1; NomoveChange *queuehead; /* contains confirmations only */ } NomoveMethod; @@ -646,10 +646,8 @@ static void nomove_remove(Method *mm, Change *remvchg) { static ErrorCode nomove_check(Method *mm) { return 0; } -static void *nomove_execute_now(oop_source *source, struct timeval tv, - void *meth_v) { - NomoveMethod *meth= meth_v; - meth->eventqueued= 0; +static void nomove_execute(Method *mm) { + NomoveMethod *meth= (void*)mm; NomoveChange *done; while ((done= meth->queuehead)) { @@ -661,15 +659,6 @@ static void *nomove_execute_now(oop_source *source, struct timeval tv, DLIST1_REMOVE(meth->queuehead, done, inqueue); nomove_dispose(&meth->m, &done->h); } - return OOP_CONTINUE; -} - -static void nomove_execute(Method *mm) { - NomoveMethod *meth= (void*)mm; - if (!meth->eventqueued) { - meth->eventqueued= 1; - events->on_time(events, OOP_TIME_NOW, nomove_execute_now, meth); - } } static Method nomove_method= { @@ -731,7 +720,8 @@ static void method_change_done(Method *m, Change *chg) { return; } - indep_indep_done(indep); + if (!indep->refcount) + indep_indep_done(indep); } static void indep_indep_done(Indep *indep) { @@ -853,6 +843,7 @@ static ErrorCode indep_prepare(Segment *move, MovPosComb target, indep->actual= startpoint; indep->target= target; indep->n_changes= n_meths; + indep->refcount= 0; memset(indep->changes, 0, sizeof(Change*) * n_meths); } DPRINTF2("\n"); @@ -1111,9 +1102,12 @@ ErrorCode movpos_change(Segment *move, MovPosComb target, move->motion= inst; move->moving= 1; + inst->refcount++; /* prevents method_change_done from destroying it */ + ouposn_moving(inst); indep_check_execute(); + inst->refcount--; if (!inst->n_changes) /* oh! */ indep_indep_done(inst); -- 2.30.2