ev_feed_event alternative?

164 views
Skip to first unread message

Saúl Ibarra Corretgé

unread,
Oct 2, 2012, 4:44:37 AM10/2/12
to li...@googlegroups.com
Hi all,

I'm replacing libev for libuv in a library and run into the following
problem: this library has a 'fake' watcher called a 'callback watcher'
which is supposed to run as soon as possible. This watcher uses a
ev_prepare handle, but it's actually never started, it's manually fed
with ev_feed_event.

The solution I found for this involves a global idle handle (used to
prevent the loop from blocking) and 2 handles, a prepare and a check.
The idea is to start both the prepare and the check handles at the same
time with the same callback, and also the idle handle, to prevent the
loop from blocking. Then since we don't care what handle (prepare or
check) executed the callback, we stop both handles.

I couldn't come up with other ideas for this, so does anyone have a
better way to do this or does it sound about right? :-)


Thanks!

--
Sa�l Ibarra Corretg�
http://saghul.net/blog | http://about.me/saghul

Ben Noordhuis

unread,
Oct 2, 2012, 6:48:31 PM10/2/12
to li...@googlegroups.com
Your solution is pretty good. You could call uv_run_once() in a loop
and do away with the prepare and check handles but that's basically
shifting the work, the basic concept remains the same.

Bert Belder

unread,
Oct 2, 2012, 6:51:59 PM10/2/12
to li...@googlegroups.com

Your solution is pretty good. You could call uv_run_once() in a loop
and do away with the prepare and check handles but that's basically
shifting the work, the basic concept remains the same.

Could we come up with something better, e.g. the ability to insert a special type of req into the request queue?

uv_custom_t* req = malloc(sizeof *req);
uv_feed(req, callback);

We could even add:
uv_feed_async(req, callback); // thread-safe version of uv_feed()

- Bert





 

Ben Noordhuis

unread,
Oct 2, 2012, 7:04:29 PM10/2/12
to li...@googlegroups.com
On Wed, Oct 3, 2012 at 12:51 AM, Bert Belder <bertb...@gmail.com> wrote:
> Could we come up with something better, e.g. the ability to insert a special
> type of req into the request queue?
>
> uv_custom_t* req = malloc(sizeof *req);
> uv_feed(req, callback);

When would that run and how would it be different from a prepare or
check handle?

> We could even add:
> uv_feed_async(req, callback); // thread-safe version of uv_feed()

On what thread does the callback run?

Bert Belder

unread,
Oct 2, 2012, 7:23:03 PM10/2/12
to li...@googlegroups.com


On Wednesday, October 3, 2012 1:04:29 AM UTC+2, Ben Noordhuis wrote:
On Wed, Oct 3, 2012 at 12:51 AM, Bert Belder <bertb...@gmail.com> wrote:
> Could we come up with something better, e.g. the ability to insert a special
> type of req into the request queue?
>
> uv_custom_t* req = malloc(sizeof *req);
> uv_feed(req, callback);

When would that run and how would it be different from a prepare or
check handle?

Somewhere in the future, with the guarantee that the loop doesn't "wait" before that, somewhat similar to process.nextTick(). The guarantee that the loop will not block is what makes it different from prepare/check. Prepare/check watchers are abused by many, including node. See http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#code_ev_prepare_code_and_code_ev_chehttp://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#code_ev_prepare_code_and_code_ev_che for it's intended use.

> We could even add:
> uv_feed_async(req, callback); // thread-safe version of uv_feed()

On what thread does the callback run?

Right - it needs to have a loop argument, I forgot that. Just like uv_getaddrinfo, for example.
 
Note that I want to add this API for another purpose as well. On windows there needs to be a way to create "custom" IOCP packets that will play nice with the libuv event loop. For example, node-serialport is now forced to do i/o in the thread pool, but overlapped operation would be quite possible. Another would be Tomasz' httpsys module, which abuses the private uv_async.t.overlapped for this purpose; this works "accidentally".

So I'm considering adding another variant of this API where the user would not "feed" a req but rather tell libuv to expect it. This would make something like this possible:

uv_custom_t* req = malloc(sizeof *req);
memset(req, 0, sizeof *req);

if (!WriteFile(h, data, n, NULL, &req->overlapped)) {
  // Handle failure
}

uv_expect(uv_default_loop(), req, after_write);

void after_write(uv_custom_t* req, int status) {
  // WriteFile completed
  free(req);
}

- Bert

Bert Belder

unread,
Oct 2, 2012, 7:26:11 PM10/2/12
to li...@googlegroups.com

 Apparently google groups didn't like my link. Another try: http://goo.gl/dV8QC

- Bert

Saúl Ibarra Corretgé

unread,
Oct 3, 2012, 2:33:37 AM10/3/12
to li...@googlegroups.com

Bert Belder wrote:
>
> On Wednesday, October 3, 2012 1:23:03 AM UTC+2, Bert Belder wrote:
>
>
>
> On Wednesday, October 3, 2012 1:04:29 AM UTC+2, Ben Noordhuis wrote:
>
> On Wed, Oct 3, 2012 at 12:51 AM, Bert Belder
> <bertb...@gmail.com> wrote:
> > Could we come up with something better, e.g. the ability to
> insert a special
> > type of req into the request queue?
> >
> > uv_custom_t* req = malloc(sizeof *req);
> > uv_feed(req, callback);
>
> When would that run and how would it be different from a prepare or
> check handle?
>
>
> Somewhere in the future, with the guarantee that the loop doesn't
> "wait" before that, somewhat similar to process.nextTick(). The
> guarantee that the loop will not block is what makes it different
> from prepare/check. Prepare/check watchers are abused by many,
> including node. See
> http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#code_ev_prepare_code_and_code_ev_che
> <http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#code_ev_prepare_code_and_code_ev_che>http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#code_ev_prepare_code_and_code_ev_che
Hi,

Thanks for the comments! Of course, having an API for this at the core
of libuv would be very convenient :-) The uv_custom / uv_feed approach
does seem nice.

uv_expect (the name), however, makes me somehow think that it would
block and wait or something like that. Or maybe my subconscious is
playing me.

Bert Belder

unread,
Oct 26, 2012, 1:19:17 PM10/26/12
to li...@googlegroups.com

I am in doubt about whether uv_custom should be a req or a handle. It being a req is probably the easiest; the advantage of it being a handle could be that you could unref() it.

Any thoughts?

- Bert

Tim Caswell

unread,
Oct 26, 2012, 1:59:51 PM10/26/12
to li...@googlegroups.com
I vote for req. What's the use case for wanting to unref it?
> --
> You received this message because you are subscribed to the Google Groups
> "libuv" group.
> To post to this group, send email to li...@googlegroups.com.
> Visit this group at http://groups.google.com/group/libuv?hl=en-US.
>
>
Reply all
Reply to author
Forward
0 new messages