User: Password:
Subscribe / Log in / New account

Kernel events without kevents

Kernel events without kevents

Posted Mar 15, 2007 4:27 UTC (Thu) by felixfix (subscriber, #242)
Parent article: Kernel events without kevents

It's been a while since I've written signal handling code, and I remember how clever I thought I was when I thought up the idea of writing single bytes to an internal pipe. Signals really suck and I never did like them.

Is it possible that if this events-via-fd idea catches on, signal handling syscalls could eventually be done away with and emulated by libc? I salivate at the idea of reliable simple signals without all that messy overhead, or at least with that messy overhead tucked away out of sight in libc.

(Log in to post comments)

Kernel events without kevents

Posted Mar 15, 2007 8:17 UTC (Thu) by Ross (guest, #4065) [Link]

You didn't work on Netscape 4.x did you? :) What did you do when the pipe became full?

Kernel events without kevents

Posted Mar 15, 2007 11:05 UTC (Thu) by pphaneuf (subscriber, #23480) [Link]

Netscape 4.x was a single-threaded, event-driven program, so you do like every other file descriptor, set it non-blocking, and ignore EAGAIN.

Was that a trick question, because if so, I don't get it.

Kernel events without kevents

Posted Mar 15, 2007 12:43 UTC (Thu) by nix (subscriber, #2304) [Link]

Netscape 4 had a habit of going into interminable stalls :)

Kernel events without kevents

Posted Mar 15, 2007 12:50 UTC (Thu) by pphaneuf (subscriber, #23480) [Link]

Ah, there are many ways in which to wedge one-self, but thankfully, I think the simplest ones were indeed avoided. ;-)

The way Netscape 4 would wedge itself the most often for me (because I would often strace it when it did, since I was working on a big event-driven single-threaded program as well, and I'm curious to boot!) was to be reading the same file descriptor over and over, getting zero, and not getting the hint, for some reason.

I suspect there was a bit of code that wanted to do just the ONE synchronous thing, and of course, it screwed up and blocked the whole program. Tsk tsk tsk...

Kernel events without kevents

Posted Mar 15, 2007 15:28 UTC (Thu) by felixfix (subscriber, #242) [Link]

You have a main loop somewhere using select to read various file descriptors. One of them is the single byte signal pipe. You read that single byte.

The point is to not have multiple bytes which might not be written contiguously.

Kernel events without kevents

Posted Mar 15, 2007 16:04 UTC (Thu) by pphaneuf (subscriber, #23480) [Link]

It behaves just like a real signal. You get at least one, but it's possible that you lose some due to overflow (the signal handler got EAGAIN and ignores it, giving similar behaviour). The reading end should read until EAGAIN, of course, to drain the pipe, before handling the signal (so that if another signal comes in, it is not missed). Of course, I also use something like a 1K buffer on the stack to "eat" the bytes, I don't read a single byte at a time.

If you really want to avoid this, you can have a bool set aside that you test before writing the byte, set to true when you did, and so on, but I prefer to let the kernel do all the book-keeping for me, I have plenty of other opportunities to screw up.

On a pipe, everything is contiguous. Unless you find a way to seek. ;-)

Kernel events without kevents

Posted Mar 15, 2007 16:17 UTC (Thu) by felixfix (subscriber, #242) [Link]

Multiple writers to one pipe can easily interleave. It's been a while now, but there is that message pipe, is it the ATT substitute? which only writes complete messages atomically or returns an error. But regular pipes have no guarantees, just like writing to any file. If your data crosses a block boundary, you have no guarantees, and maybe not even if you stay within block boundaries.

Kernel events without kevents

Posted Mar 15, 2007 16:38 UTC (Thu) by pphaneuf (subscriber, #23480) [Link]

Well, since I don't even look at the value that I read, it doesn't matter much, doesn't it?

Depending on environmental constraints, I either use a pipe per signal, or the pipe is only to "wake up" the select() and I check some volatile bools that the signal handlers set to know which one it was.

Furthermore, since my "messages" are a single byte (I usually use 42 as a value), and that's the granularity of a pipe, they'd still be atomic. That's if I cared about their value, of course.

Copyright © 2017, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds