[FFmpeg-devel] [RFC] Event loop

Mark Thompson sw at jkqxz.net
Sat Feb 20 23:26:30 EET 2021


On 19/02/2021 19:34, Kieran Kunhya wrote:
> On Fri, 19 Feb 2021 at 19:04, Nicolas George <george at nsup.org> wrote:
> 
>> Kieran Kunhya (12021-02-19):
>>> I don't have a strong opinion on either. But I think you can use
>>> container_of on the fd.
>>
>> Thanks. I find no trace of it in the docs:
>>
>>
>> http://docs.libuv.org/en/v1.x/search.html?q=container_of&check_keywords=yes&area=default
>>
>> Can you be a little more precise?
>>
>> The portability arguments have been compelling for libuv over libev, so
>> if we find a way of getting libuv to work for our needs, it would be
>> best.
>>
> 
> Actually maybe you can't use container_of and mmap since the fd is not a
> pointer...

I'm not entirely sure where this discussion was going, but I believe the original questions would have been simple to answer if anyone had bothered to read the documentation.

Adding a file descriptor referring to something independent of libuv (such as an alsa or xcb fd) is handled by uv_poll_init(), see <http://docs.libuv.org/en/v1.x/poll.html>.

A user context pointer is carried into callbacks via the "data" member of uv_handle_t (and hence the same member in all subtypes of it, like uv_poll_t), see <http://docs.libuv.org/en/v1.x/handle.html>.


I think we need to be clear here that libuv and libev are solving some of the same problems but not really in the same way.

libev is essentially super-poll(): it gives you a uniform interface to whatever the preferred synchronous multiplexing method is on your platform (epoll on Linux, kqueue on BSD and derivatives, traditional BSD select on Windows, etc.).  For Windows, that of course only supports things to which the synchronous multiplexing interface applies, which is network sockets only.

libev isn't really giving you anything which we don't have already, though the common interface may be nice for other applications which also use libev.

libuv is trying to solve event loop problem in a uniform way across all platforms, with no requirement that the underlying method is synchronous.

That lets it provide better support on systems which want to use asynchrous I/O (like Windows with I/O completion ports), but has the consequence that it has to own the sockets internally because the details of the multiplexer affect all socket I/O.  If the underlying method is asynchrous, then every socket call will need additional detail that the user doesn't want to deal with (e.g. send() becomes WSASend() with an OVERLAPPED argument on Windows so the result can be delivered to an I/O completion port later).


In my opinion, we would be best off ensuring that we support the more general solution in libuv (or, if libuv has separate problems which rule it out, another library with the same approach such as libevent), since FFmpeg provides cross-platform libraries which we would like to work properly on all systems we support.  This has future benefits for the systems which in current form would be covered by libev, as asynchronous I/O becomes is becoming more common on Unix platforms as well (e.g. io_uring on Linux) and we will be able to handle it without another redesign.

Thanks,

- Mark


More information about the ffmpeg-devel mailing list