Il 19/09/2012 12:06, Avi Kivity ha scritto:
>> > (The hunch is that ts could be deleted exactly at the moment the
>> > callback is unlocked. This can be solved with ref/unref on the opaque
>> > value, as you mention below).
> Are you saying that this works as is or not? It does seem broken wrt
> deletion; after qemu_del_timer() completes the caller expects the
> callback not to be called.
Ouch, then I think the only solution is to remove this invariant if you
add fine-grained locking and re-check the enable conditions in the timer
callback.
If you allow calling del_timer to be called with the device lock held,
you cannot fixing without deadlocking. If you don't, the caller of
del_timer cannot set any expectation because the timer could be run in
the window between dropping the device lock and calling del_timer
Paolo
> This isn't trivial to guarantee, we need something like
>
> dispatch_timer():
> pending += 1
> timer.ref()
> drop lock
> timer.cb()
> take lock
> timer.unref()
> pending -= 1
> notify
>
> del_timer():
> take lock
> timer.unlink()
> while pending:
> wait for notification
> drop lock
>
> but, if del_timer is called with the device lock held, we deadlock. ugh.
Wait for notification should be a cond_wait that drops the lock.
Alternatively:
dispatch_timer():
drop lock
if timer has expired:
timer.cb()
take lock
notify
del_timer():
take lock
timer.unlink()
drop lock