[libevfibers] Re: interfacing with external resource callbacks

  • From: Konstantin Olkhovskiy <lupus@xxxxxxxxxx>
  • To: libevfibers@xxxxxxxxxxxxx
  • Date: Thu, 28 May 2015 19:00:06 +0300

Hello,


What I need to figure out first, though, is how hard it would be to plug
in an external resource/library. I see the fbr_eio_custom() function in
the existing API, but the library that I have in mind already has its own
asynchronous API which itself uses callbacks for completion notification.
There is no blocking function for me to execute.


It should be really easy. Use fbr_cond_wait() within your fiber and
fbr_cond_signal() from your completion callback.


As a result, what I really want to do is add my own fbr_foo() function that
posts the external operation, and have the callback for that external
operation do an ev_async_send() to wake up the event loop in evfibers and
continue fiber execution. I'm not sure if I described that properly, but
hopefully it makes sense. I'm looking at evfibers as a way to have external
library operations *appear* as if they are sequential blocking calls within
a fiber.


What you described is perfectly correct and makes sense.
fbr_cond_* functions wrap an ev_async internally, but are not
thread safe. You can wrap the call to fbr_cond_wait() into
my_fbr_foo() or whatever you like it to be.



My question is this: If I want to add my own fbr_foo() function as
described above, will I need to actually modify fiber.c to do it? Or does
an external user of libevfibers have access to enough internal data
structures to be able to interface with the event loop (an inject
completion events) from a separate library?


That would defeat the purpose of creating a fiber library. libevfibers is
just a client of libev event loop. You can use fibers, or you can use
the event loop, or both, depending on your needs.

If you know that completion callback from your library is going to be
invoked from the other thread, then you will likely need to manually
wait for ev_async. Just start an ev_async watcher, and do call
ev_async_send() from your library's completion callback. Within a fiber,
which will be waiting for this even to arrive, you need to wait for this
watcher to trigger. libevfibers has some wrappers for I/O operations,
but unfortunately it does not have one for ev_async, so you can just
copy paste the boilerplate wrapper from e.g. fbr_sleep. All of the
fbr_ev_* functions which are used within fbr_sleep are public API and
are documented as such.

--
Regards,
Konstantin

Other related posts: