Jason Tackaberry wrote:
> On Thu, 2005-08-11 at 18:34 +0200, Dirk Meyer wrote:
>> Yes and no. I have a OneShotTimer. Whatever I return in the callback
>> function, __call__ for a OneShotTimer return False. So now I'm in the
>> callback, the timer is already unregistered (because it is a
>> OneShotTimer). A see 'I need to start the timer again right now' and
>> do a TheSameOneShotTimer.start(). This should work, but it doesn't
>> because a OneShotTimer always returns False and it is unregistered by
>> NotifierCallback. 
>
> Hmm.  Does it really work that way?  Actually, because
> OneShotTimer.__call__ explicitly unregisters itself, isn't the return
> value of this function irrelevant?  We kind of handle things ourselves,
> rather than let pynotifier unregister us.

Notifier is not the problem. The problem is NotifierCallback which
will call self.unregister if the function returns true. The __call__
functions will be called in the follwing order:

OneShotTimer.__call__.unregister
OneShotTimer.__call__.super
NotifierCallback.__call__.function
if function returns false, unregister

> So we have OneShotTimer, derived from Timer, derived from
> NotifierCallback.  OneShotTimer.__call__() unregisters itself and then
> calls NotifierCallback.__call__ (because Timer.__call__ isn't
> implemented).  NotifierCallback.__call__() calls Callback.__call__(),
> which ultimately calls the user callback.
>
> NotifierCallback.__call__() uses the return value from Callback.__call__
> which returns the return value of the user callback.  So, if the user
> callback returns False, it calls self.unregister().  For a OneShotTimer,
> this is normally a no-op, because OneShotTimer.__call__ has already
> called unregister() before this point.  So it's only an issue if the
> user callback reregisters the timer (by calling start()).  But since
> NotifierCallback.__call__ only calls unregister() if the user callback
> returns False, any non-False (even None [this was intentional when I
> coded this]) return value should cause the newly started timer to remain
> registered. 

Yes, I added that to the doc inside the class.

> The new timer will have a new id that's different from the
> timer's current id, so even though OneShotTimer.__call__ returns False,
> it shouldn't affect the new timer.

It does, because unregister now only knows the new id.

> So I guess I don't see why this was a problem to begin with.  As long as
> the user callback -- the one which restarts the timer -- returns
> non-False, you shouldn't need to worry about it.
>
> I tested the above explanation with this code:
>
>         from kaa import notifier, main
>         
>         class Foo:
>             def cb(self):
>                 print "Callback"
>                 self.timer.start(0.5)
>         
>         a = Foo()
>         a.timer = notifier.OneShotTimer(a.cb)
>         a.timer.start(0.5)
>         main()
>         
> It works as it should (without your recent check-in).  Of course, if
> Foo.cb() returns False, then it doesn't.

Right, that was my problem.

> But that makes sense to me, because we have a clear definition that
> "when a timer callback returns False, it does not get called again."
>
> So your check-in doesn't actually fix a problem, but adds complexity to
> the definition of notifier callback return values, because now it's:
> "when a timer callback returns False, it does not get called again,
> unless the timer callback restarts the timer, in which case it will be
> left alone."  Well, I maintain that the timer callback shouldn't be
> returning False if it wants to be restarted :)

I know, and you already won. :)


Dischi

-- 
After all is said and done, a hell of a lot more is said than done.

Attachment: pgpwU5uTGtDEH.pgp
Description: PGP signature

Reply via email to