[Xcb] Feature Request: Function "xcb_test_for_event"

Micah Nordland mpnordland at gmail.com
Mon Apr 8 16:52:19 PDT 2013


I believe this is what you are looking for:

int xcb_get_file_descriptor (xcb_connection_t *c)
  Access the file descriptor of the connection. ]

Awesome WM currently uses this with glib, and in the past it used it with
libev.
bspwm uses this to do something similar to what you are doing.
https://github.com/baskerville/bspwm


On Mon, Apr 8, 2013 at 5:22 PM, Josh Triplett <josh at joshtriplett.org> wrote:

> On Sat, Apr 06, 2013 at 01:46:14PM +0200, Christian Heller wrote:
> > Hi Josh,
> >
> > thanks for replying.
> >
> > > Detecting events by polling periodically is highly inefficient; you
> > > really want some mechanism that will block until you recieve an event.
> > > So, first of all, I would not recommend adding an "xcb_test_for_event"
> > > function, because I don't see any way you could use it without polling.
> > [..]
> >
> > you are right in that this kind of "busy waiting" (loop + sleep) that
> > I use is not very efficient. A blocking function would be much nicer.
> > However, I cannot use "xcb_wait_for_event" for reasons I explain
> following.
> >
> > CYBOI tries to offer all possible communication channels transparently.
> > Application programmers should write their programme in CYBOL (XML) only.
> > All they have to do is write "send" or "receive" and give a "channel",
> > e.g.: inline text, file, terminal, serial_port, x_window_system, socket.
> > The rest is done by CYBOI internally.
> >
> > CYBOI starts up, runs the usual event loop, handles events, shuts down.
> > This all in the main thread. Additional threads may be started ONLY for
> > detection, but NOT for reception or sending of data. This is to avoid
> > memory conflicts. Just a design decision that I wouldn't like to change.
> >
> > Now, the "detection" threads somehow have to inform the "main" thread,
> > if data arrived on some channel. This is done via simple "int" variables,
> > something like an internal interrupt request (irq) flag. So I have to
> > use "busy waiting" at least on this point of the code.
> >
> > Detection of the different channels is done like this:
> > - terminal: fgetwc + ungetwc
> > - serial_port: fgetc + ungetc
> > - socket: accept
> > - x_window_system: int n = XEventsQueued(d, QueuedAfterReading);
> >
> > The terminal and serial_port functions are blocking, which is nice.
> > But I have to write back the received character with "ungetc". Why?
> > Because the receiving of data shall be done in the main thread only.
> > For the socket, all that is to be stored is a single integer number
> > representing the client socket, which is not that problematic.
>
> You don't need to get a character to block on a terminal or serial port.
> You should just select() or poll() or epoll() or similar on the file
> descriptor.  Likewise with sockets, and in fact you can watch many file
> descriptors with a single select/poll/epoll/etc.  That'll eliminate the
> unget.
>
> Ideally, you should use one of those calls on your main thread rather
> than flag variables.  If you have to wait on something for which you
> don't have a file descriptor, you could always spin off a thread and
> have it write a byte to a pipe when ready, then add the read end of the
> pipe as another file descriptor to block on.
>
> You might also look at timerfd, signalfd, and similar calls; those make
> it possible to include even more things in your select/poll/epoll.
>
> Depending on your target platforms, you may also find the portable
> libevent or libev wrappers useful, rather than calling epoll or similar
> directly.
>
> > Concerning "x_window_system": If using "xcb_wait_for_event", I am
> > forced to store the event received in the "detection" thread.
> > Then, the main thread gets informed that events are available.
> > In the main thread, I would have to use that stored first event
> > and receive further events using "xcb_poll_for_event", because the
> > main thread is not allowed to block, since further communication
> > might occur on other channels.
> >
> > I'd prefer not to store any event in the "detection" thread.
> > It would be nicer to have a function just notifying me if there are
> > events available (a simple int flag returned, no event).
> > Ideally -- you are right -- that function would be a BLOCKING one!
> > So, if you could make "xcb_test_for_event" blocking, even better.
> >
> > > For your use case, you really want a blocking function like
> > > xcb_wait_for_event, but without actually returning the event;
> > > it should block until at least one event exists to return.
> >
> > Yes, exactly. This is what I need. Thanks for clarifying.
>
> OK, glad to hear that blocking would work for you.
>
> Ideally I'd still love to have some way for XCB to just supply a file
> descriptor you can block on, but I don't know if the structure of the X
> protocol would reasonably allow that.  Failing that, an
> xcb_block_until_event or xcb_wait_for_event_noret or similar call seems
> vaguely reasonable.
>
> > > That still seems suboptimal for the purposes of most event loops (which
> > [..]
> >
> > I am aware of the disadvantages of "busy waiting". But this is the
> > price of flexibility in CYBOI. All communication channels shall be
> > used easily. In effect, CYBOI with its irq flags (between "detection"
> > threads and "main" thread) tries to do what is an operating system's
> task.
> >
> > I am constantly looking for optimisations and am thankful for ideas.
>
> You should definitely look into the select/poll/epoll family of
> syscalls.
>
> - Josh Triplett
> _______________________________________________
> Xcb mailing list
> Xcb at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/xcb
>



-- 
Praising my Savior all the day long,
Micah Nordland
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/xcb/attachments/20130408/94ed8629/attachment.html>


More information about the Xcb mailing list