
Can we implement eventfd(2) as documented here <https://man7.org/linux/man-pages/man2/eventfd.2.html>? It would only be available on the Linux platform, and one of the benefits would be the ability to create synchronisation primitives on said platform that can block on normal threads, and be awaited on in coroutines (without busy looping inside said coroutine). Currently the best place I can think of to put it would be in one of the Networking and Interprocess Communication modules (possibly `select` or `socket`?). The fact that it's Linux only shouldn't be an issue, since much of the contents of `select` is OS dependent.

On 16/06/2020 06:56, doodspav@gmail.com wrote:
Can we implement eventfd(2) as documented here <https://man7.org/linux/man-pages/man2/eventfd.2.html>?
EventFD is available on PyPI: https://pypi.org/project/eventfd/ -- Rhodri James *-* Kynesim Ltd

It would only be available on the Linux platform, and one of the benefits would be the ability to create synchronisation primitives on said platform that can block on normal threads, and be awaited on in coroutines (without busy looping inside said coroutine).
+1. Although it already exists as a package on PyPI, I've seen a non-negligible amount of user demand for a synchronization primitive that works as described above for asyncio. Adding eventfd() to the stdlib seems like a step towards eventually implementing something like that in an effective manner, and I don't think the maintenance burden would be especially high. I could also see a significant potential use case for multiprocessing (CC'd Antoine in case he has anything to add there).
Currently the best place I can think of to put it would be in one of the Networking and Interprocess Communication modules (possibly `select` or `socket`?).
The select module seems like it would be a reasonable location. On Tue, Jun 16, 2020 at 8:42 AM <doodspav@gmail.com> wrote:
Can we implement eventfd(2) as documented here < https://man7.org/linux/man-pages/man2/eventfd.2.html>?
It would only be available on the Linux platform, and one of the benefits would be the ability to create synchronisation primitives on said platform that can block on normal threads, and be awaited on in coroutines (without busy looping inside said coroutine).
Currently the best place I can think of to put it would be in one of the Networking and Interprocess Communication modules (possibly `select` or `socket`?). The fact that it's Linux only shouldn't be an issue, since much of the contents of `select` is OS dependent. _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/2BX6V4... Code of Conduct: http://python.org/psf/codeofconduct/

Hi As said earlier, it's on PyPi: https://pypi.org/project/eventfd/ However, it's only at version 0.2 and hasn't been changed since 2016. Digging a bit deeper, there's an unresolved issue that suggests more work is required. Issue: Race condition in "set" can lead to a bad state https://github.com/palaviv/eventfd/issues/2 Perhaps a good first step would be a code review of palaviv's enventfd, and finding a fix for this issue. -- Jonathan

I've looked over the PyPi version of `eventfd`, and I feel that it is trying to be more than just a thin wrapper. The attempt to make it cross platform has given it more fields than it requires, as has the attempt to wrap it as a semaphore, and with that comes added complexity. The `eventfd` that I was suggesting be added would in my mind look something more like this: `eventfd`: - `__init__(...)` - `read(...)` - `write(...)` - `close(...)` - `closed(...)` - `fileno(...)` + some extra dunder methods We could possibly add a method to get the flags that were passed to `__init__`, and I think pickling should be disabled (while it does get inherited through `fork(2)` and likely through `execve(2)` depending on flags, I think the fd's integer value in each process can be different, though I could be wrong here). From that, one could then build more complex classes, but the base primitive should be as simple as possible. Instead of trying to fix the PyPi version, I can write a proof of concept of what I described above? doodspav

Instead of trying to fix the PyPi version, I can write a proof of concept of what I described above?
That would definitely be useful, and would help us get a more solid idea of what exactly is being proposed. I also agree that a potential version contained in the select module should be as simple as possible and rather low-level (more so than the linked PyPI project), as it's likely going to be there primarily for building other tools with. There's no guarantee of course that it will ultimately be accepted, but a proof of concept implementation would be a highly productive first step, IMO. On Tue, Jun 16, 2020 at 2:58 PM <doodspav@gmail.com> wrote:
I've looked over the PyPi version of `eventfd`, and I feel that it is trying to be more than just a thin wrapper. The attempt to make it cross platform has given it more fields than it requires, as has the attempt to wrap it as a semaphore, and with that comes added complexity.
The `eventfd` that I was suggesting be added would in my mind look something more like this:
`eventfd`: - `__init__(...)` - `read(...)` - `write(...)` - `close(...)` - `closed(...)` - `fileno(...)` + some extra dunder methods
We could possibly add a method to get the flags that were passed to `__init__`, and I think pickling should be disabled (while it does get inherited through `fork(2)` and likely through `execve(2)` depending on flags, I think the fd's integer value in each process can be different, though I could be wrong here).
From that, one could then build more complex classes, but the base primitive should be as simple as possible. Instead of trying to fix the PyPi version, I can write a proof of concept of what I described above?
doodspav _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/62XBNI... Code of Conduct: http://python.org/psf/codeofconduct/

This is my first attempt at a C implementation: https://gist.github.com/doodspav/5d96c09696fa3ef1c89b4d6426ddc338 It stores the `fd` as an atomic int, since I think threads not being able to run in parallel is an implementation detail, and I shouldn't be designing code around it? I'm not sure if all Python platforms have a C compiler that supports stdatomic, but I'll cross that bridge when I get to it. Right now `read`/`write` raise `BlockingIOError` if the `fd` is set to non-blocking, and the operation would block - I was considering adding kwargs to both operations to give the option to return `None`/`False`, but kwargs in C are annoying, so maybe at a later stage. To build: - you'll probably need a lib like `libpython3-dev` - save the gist into a file called `py_eventfd.c` - create a file called `setup.py` and paste the following into it: ```py from distutils.core import setup, Extension setup(name="eventfd", version="1.0", ext_modules=[Extension("eventfd", ["py_eventfd.c"])]) ``` - run `python3 setup.py build` and `cd b*/l*` - from there you can `import eventfd` or `from eventfd import eventfd` It should go without saying that this will only compile on Linux.

On 16 Jun 2020, at 19:57, doodspav@gmail.com wrote:
I've looked over the PyPi version of `eventfd`, and I feel that it is trying to be more than just a thin wrapper. The attempt to make it cross platform has given it more fields than it requires, as has the attempt to wrap it as a semaphore, and with that comes added complexity.
The `eventfd` that I was suggesting be added would in my mind look something more like this:
`eventfd`: - `__init__(...)` - `read(...)` - `write(...)` - `close(...)` - `closed(...)` - `fileno(...)` + some extra dunder methods
We could possibly add a method to get the flags that were passed to `__init__`, and I think pickling should be disabled (while it does get inherited through `fork(2)` and likely through `execve(2)` depending on flags, I think the fd's integer value in each process can be different, though I could be wrong here).
From that, one could then build more complex classes, but the base primitive should be as simple as possible. Instead of trying to fix the PyPi version, I can write a proof of concept of what I described above?
Agreed the PyPi version is not worth investing in. Do you see this as add eventfd as os.eventfd? Add definitons for the flags and that is it? Turning that into a semaphore would then be easy to do on top of that os.eventf call. You could even do the eventfd PoC using ctypes. Barry
doodspav _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/62XBNI... Code of Conduct: http://python.org/psf/codeofconduct/

On 16/06/2020 07.56, doodspav@gmail.com wrote:
Can we implement eventfd(2) as documented here <https://man7.org/linux/man-pages/man2/eventfd.2.html>?
It would only be available on the Linux platform, and one of the benefits would be the ability to create synchronisation primitives on said platform that can block on normal threads, and be awaited on in coroutines (without busy looping inside said coroutine).
Currently the best place I can think of to put it would be in one of the Networking and Interprocess Communication modules (possibly `select` or `socket`?). The fact that it's Linux only shouldn't be an issue, since much of the contents of `select` is OS dependent.
We usually expose low-level, file descriptor-related functions in the os module and then provide high-level wrappers in Python. The approach is most flexible and allows 3rd parties to build on top of the raw file descriptor, too. I opened a BPO and created https://github.com/python/cpython/pull/20930 to implement a low-level interface to glibc's eventfd() function. Christian

I opened a BPO and created https://github.com/python/cpython/pull/20930 to implement a low-level interface to glibc's eventfd() function.
Perfect. What's the procedure now for getting that PR accepted?

Perfect. What's the procedure now for getting that PR accepted?
Next, it will go through a PR review process prior to being included for Python 3.10. Since it's being implemented as a wrapper for an existing OS API, a PR and bpo issue should be adequate (as opposed to major change proposals that typically require a PEP and/or in-depth discussion.) For more details on our GitHub PR process, see the following section from the devguide: https://devguide.python.org/pullrequest/. On Wed, Jun 17, 2020 at 6:58 AM <doodspav@gmail.com> wrote:
I opened a BPO and created https://github.com/python/cpython/pull/20930 to implement a low-level interface to glibc's eventfd() function.
Perfect. What's the procedure now for getting that PR accepted? _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/ZLHYEX... Code of Conduct: http://python.org/psf/codeofconduct/
participants (6)
-
Barry Scott
-
Christian Heimes
-
doodspav@gmail.com
-
Jonathan Fine
-
Kyle Stanley
-
Rhodri James