AnyEvent driver for Prima

Dmitry Karasik dmitry at karasik.eu.org
Wed Dec 14 10:47:00 CET 2016


On Wed, Dec 14, 2016 at 12:04:30AM +0100, Marc Lehmann wrote:
> On Tue, Dec 13, 2016 at 08:50:35PM +0100, Dmitry Karasik <dmitry at karasik.eu.org> wrote:
> > It gets a bit messy with everyone answering everone's mail, but I'll try to answer my best,
> > and mix answers from different mails.
> You are doing great :)
Thank you :)

> 
> > to extend Prima so it can work with FDs, but it seems to me that if that is the common
> > problem with event loop backends,
> I could be wrong and some bug workarounds hide this for other loops, but
> atm., it seems Prima is the only event loop that doesn't support it.

Okay, not anymore :) Just added support for Prima::File->fd(fileno($HANDLE))

> I think this question might mean something else - if you have a timer, and it
> is expired (i.e. its callback would be invoked soon), will a destroy() call
> keep that callback from being invokes?

Yes

> 
> There is another question - how does one invoke the event loop without an
> application, i.e. how does one call $::application->yield when there isn't an
> $::application?
> 
> As I see it, it can't be done, so AnyEvent would simply "use
> Prima::Application" and not have any problems with it not existing - it
> doesn't seem as if Prima would work well with multiple application objects
> anyway.

Exactly. Prima's event loop doesn't run without X11 connection (when on X11),
and the connection is established by Prima::Application. In theory, it might be
possible to decouple that, but for now I'd suggest to just 'use
Prima::Application'.

> They are basically background jobs for event loops - if you have a CPU
> intense job, you can run it in many steps from an idle watcher, running at
> full speed when the app is otherwise idle, and not running at all when the
> app handles events, such as user input.

Ok, thank you, I got it. It seems that GTK (the first working example I found) uses the one-off
model for idle watcher, and if that is the case, then I believe one could just use the
existing post_message/onPostMessage for this. While not exactly matching the notion of being idle,
it is still serviced as low priority event. 

I'll try to experiment some more on Prima's event loop internals to see if I
can provide some more guarantees, because x11 and win32 backend work
differently with onPostMessage now (although in both cases the event is
delivered).

> > Yes. On a simple level, all callbacks are killed as soon as the object that hosts them
> > is killed too.
> So the only thing we need to do is explicitly kill them with destroy(),
> rather then relying on perl's destructor.
> Out of curiosity, does Prima keep an internal reference, or what happens
> when perl calls DESTROYm on those objects?

There's a notion of Prima::Component->owner($owner), that can be used to hook up objects to the $owner.
If $owner is undef, then the object is just the same as any other perl object. The thing with Timer was,
that until now, it wasn't possible to create it without a proper owner, thus the refcnt was never decreased
to zero. When though one calls destroy(), the C object indeed gets cleaned up, but the perl scalar
still lingers, without DESTROY being called until refcnt goes to 0.
> 
> > For more fine-grained implmenentation, one can un-registed callbacks individually,
> > but one has to register them explicitly first, and save the resulting handle to address them later.
> 
> Ah, ok, things are more complicated - with the object hosting them you
> mean e.g. $::application? Can there be more than one such objects? If
> yes, is there a way to find the main object that hosts the event loop
> somehow, or does one always have to abuse the main namespace and use
> $::application?

Not quite. Hosting means that that a Prima object can host more than one callback, not just by type
(as f.ex. File hosts onRead/onWrite ), but also of the same type. One can add more callbacks
with add_notification(), and have them all triggered when the event arrives (and removed with
remove_notification(), too).

> 
> > > what time timers are relative to and probably
> > 
> > They are not relative to anything, a Prima::Timer->new( timeout => 100 ) fires up 10 times a second,
> > imprecisely :)
> 
> Hmm, that's not good - how does one make a delay then? What you are saying
> basically is:
> 
>    Prima::Timer->new( timeout => 10000 )
> 
> can basically fire anytime, even after a millisecond? Is there a way to

No, it's not that - a 10000 ms timeout will not fire up before 10000 ms. Later, or even never - yes, but not before.
The subsequent events can actually fire up before 10000 ms, if the previous one was delayed, so one could observe f.ex.
such timeline:

0 - timer.start
12000 - event #1
20000 - event #2

-- 
Sincerely,
	Dmitry Karasik




More information about the anyevent mailing list