After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 156048 - epoll support in gmain.c
epoll support in gmain.c
Status: RESOLVED DUPLICATE of bug 699132
Product: glib
Classification: Platform
Component: mainloop
unspecified
Other Linux
: Low enhancement
: ---
Assigned To: gtkdev
gtkdev
: 386350 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2004-10-21 11:05 UTC by Eduardo Pérez Ureta
Modified: 2018-02-16 12:08 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Thread with Jeff Garzik (12.62 KB, text/plain)
2004-10-21 18:22 UTC, Owen Taylor
  Details
Feasibility test for cascaded epoll (2.88 KB, text/plain)
2005-12-22 22:50 UTC, Mikhail Zabaluev
  Details
Initial GPollSet implementation (52.53 KB, patch)
2006-01-08 22:56 UTC, Mikhail Zabaluev
none Details | Review

Description Eduardo Pérez Ureta 2004-10-21 11:05:03 UTC
linux-2.6.x supports the new epoll (man epoll) interface that is faster when
polling lots of fds.
This is very low priority for most glib apps but someday it'll need to be done.
Comment 1 Owen Taylor 2004-10-21 18:22:10 UTC
Created attachment 32891 [details]
Thread with Jeff Garzik

Here's a conversation I had with Jeff Garzik on this subject and
what would be involved in doing this.
Comment 2 Mikhail Zabaluev 2005-12-21 11:54:48 UTC
On the priority problem:
epoll(4) says that epoll descriptors can be added to other epoll sets.
Maybe, a cascaded scheme can be implemented where each active priority level gets an epoll set for its fds, and the master epoll set contains epoll descriptors for the levels. A blocking epoll_wait is called on the master epoll descriptor, then the triggered level sets are processed with non-blocking epoll_wait accordingly to their priority. This will have acceptable performance when few priority levels are in effect, which was Oven's concern. Bizarre priority schemes will still work, too, at the cost of extra non-blocking system calls. When there is only one effective priority, the cascade can be bypassed altogether.
Comment 3 Mikhail Zabaluev 2005-12-21 11:56:33 UTC
Sorry Owen, I mistyped your name.
Comment 4 Owen Taylor 2005-12-21 16:21:42 UTC
Hmm. What might work well if possible, is use poll() to poll on
a set of one epoll descriptor per priority, in the case of
one priority, that could be optimized to a blocking epoll_wait().

Of course, the whole bug really does depend on someone having a GLib-using
app with enough file descriptors for epoll()/poll() to matter.
Comment 5 Mikhail Zabaluev 2005-12-21 22:22:28 UTC
(In reply to comment #4)
> Hmm. What might work well if possible, is use poll() to poll on
> a set of one epoll descriptor per priority,

Choice between poll or epoll_wait on the master set is not principal. I'd prefer using the same call every time. Also, epoll_wait allows for easier descriptor set structures.

Unfortunately, GMainContext exposes poll-like semantics; at least g_main_context_set_poll_func/g_main_context_get_poll_func will have to be deprecated if epoll is implemented internally.

> Of course, the whole bug really does depend on someone having a GLib-using
> app with enough file descriptors for epoll()/poll() to matter.

Count me in: I want to do the unthinkable and drag GLib onto a c10k-ish server.
With GSlice, thread pools and other niceties, it starts to look attractive for that niche, too.
So, will you be interested if I submit a patch?
Comment 6 Mikhail Zabaluev 2005-12-22 22:50:23 UTC
Created attachment 56316 [details]
Feasibility test for cascaded epoll

Here's a small test that demonstrates how epoll works in the proposed two-layered scheme. To put it short: an epoll over other epoll descriptors reports "read" events on those epolls that got any events to retrieve.
Comment 7 Mikhail Zabaluev 2005-12-22 23:03:41 UTC
I'm going to implement GPollSet, an object that abstracts the polling mechanism preferable for the platform (this may include kqueue as well some day). It will also implement priority cutoff similarly to how g_main_context_query operates.
Then, GMainContext can be modified to use GPollSet internally.
Comment 8 Mikhail Zabaluev 2006-01-08 22:56:26 UTC
Created attachment 56990 [details] [review]
Initial GPollSet implementation

Here is a patch that adds GPollSet, a waitable poll set abstraction, to GLib, and doesn't change anything else. It borrows heavily from GMainContext code and is currently implemented with epoll, poll, select, or Win32 wait functions, whichever is available and the most efficient. Instead of poll(2)-style event arrays, GPollSet uses callbacks to notify event consumers. While it can be shoehorned into existing g_main_context_query()/g_main_context_check() functions, doing so may actually hurt the main loop performance. Note that gratuitous add/remove/max priority change operations should be avoided because they may result in system calls being made.
The GPollSet operations are not MT-safe except the reference counting.

Known problems:
1. Behavior of g_pollset_wait() on an empty set is not implemented consistently; implementations rely on the underlying wait function's handling of an empty set. It should probably be specified and implemented so that g_pollset_wait() is equivalent to sleeping for the specified timeout (even infinite?) if the effective set is empty.
2. Return status of g_pollset_wait() should probably be more informative to be able to indicate timeouts in a distinct way from errors or event arrival.
3. The Win32 implementation is a heap of untested code that I didn't even try to build. However, it is thought out as well as the other implementations.
4. The test may lack coverage for a few corner cases; I wasn't especially thorough there.
Comment 9 Mikhail Zabaluev 2006-01-09 10:18:28 UTC
Further ideas for GPollSet:

- Implement g_pollset_modify for efficient modification of a descriptor event mask, which may be useful to temporarily block/unblock attached sources. This function might be callable from inside GPollNotify callbacks, which is currently prohibited for add/remove operations.

- Add a "one shot" event flag that would translate to EPOLLONESHOT for epoll and generally have a descriptor automatically disabled (its event mask set to 0) when an event is reported for it. g_pollset_modify should be used to enable the descriptor back.

- Separation of epoll- and non-epoll implementations is made squeaky clean for the initial code. In real life (e.g. distribution packages), epoll may turn out to be unavailable at runtime. So, the epoll code should probably be blended with the basic POSIX implementation so that when epoll_create returns ENOSYS, it falls back to the poll-based implementation.
Comment 10 Havoc Pennington 2006-12-15 23:38:05 UTC
*** Bug 386350 has been marked as a duplicate of this bug. ***
Comment 11 Sebastian Dröge (slomo) 2009-06-27 08:05:19 UTC
You could take a look at GstPoll[0], it abstracts poll() and similar things in a platform independent way.

[0] http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstPoll.html
Comment 12 Eduardo Lima Mitev 2011-02-23 19:00:35 UTC
adding myself to cc.
Comment 13 Mikhail Zabaluev 2011-02-28 16:11:29 UTC
An idea update for anyone who might have time and motivation to implement this:
I think the priority-based poll set management is more trouble than it's worth; it only has a negligible runtime cost with traditional poll/select because the poll set has to be resubmitted for each poll iteration anyway. All descriptors should be uniformly polled in an epoll-friendly replacement for GMainContext, making the priorities only meaningful for sources triggered besides the file descriptor polling.
Comment 14 Mikhail Zabaluev 2011-12-05 11:44:16 UTC
It looks like we may get some epoll love after all:
http://mail.gnome.org/archives/gtk-devel-list/2011-August/msg00059.html
Comment 15 Mikhail Zabaluev 2013-04-28 13:16:53 UTC
See #bug 699132 for a more ambitious proposal, which should support epoll as well as any other event loop backends generally conforming to the same model.
Comment 16 Mikhail Zabaluev 2013-05-19 20:05:38 UTC
An experimental epoll backend is implemented as part of the work on bug #699132:

https://github.com/mzabaluev/glib/commits/pluggable-mainloop
Comment 17 Mikhail Zabaluev 2014-01-24 21:32:03 UTC
(In reply to comment #16)
> An experimental epoll backend is implemented as part of the work on bug
> #699132:
> 
> https://github.com/mzabaluev/glib/commits/pluggable-mainloop

And now for new and improved:

https://github.com/mzabaluev/glib/commits/pollers
Comment 18 Philip Withnall 2018-02-16 12:08:40 UTC
Since this covers much of the same ground as bug #699132, let’s close it as a duplicate.

*** This bug has been marked as a duplicate of bug 699132 ***