On Thursday 16 March 2006 15:22, Werner Almesberger wrote: > Jeff Dike wrote: > > Having said that, > > if you can get a stack from the hang, it might turn out to be an easily > > diagnosed and fixed bug. > > Seems that arch/um/kernel/sigio_user.c:write_sigio_thread begins > its poll before there are any fds in current_poll
Ah, and you mean it hangs... > , so update_thread > caused by a add_sigio_fd shortly thereafter hangs while waiting for > a response. Clearly > A sleep(1) at the beginning of write_sigio_thread "fixes" this :-) Er... there's only one thing which seems unclear - poll(NULL, 0, -1) shouldn't fail with -EFAULT instead of hanging? Yep, it should. I didn't believe what you said, so. But then I went to check the implementation. And, indeed, it seems that Linux isn't up to this :-). So: 1) I'll try to fix poll(2) to return -EINVAL. Dunno whether anyone will say "no, the app is stupid, it deserves no error", but hope not (with "try" I refer to this). Attached patch should do this. 2) write_sigio_thread should do a "down" on a semaphore/mutex and the first update_thread should "up" it. As usually, this semaphore would be indeed implemented as a pipe. -- Inform me of my mistakes, so I can keep imitating Homer Simpson's "Doh!". Paolo Giarrusso, aka Blaisorblade (Skype ID "PaoloGiarrusso", ICQ 215621894) http://www.user-mode-linux.org/~blaisorblade
poll(2): don't hang caller if nfds == 0 From: Paolo 'Blaisorblade' Giarrusso <[EMAIL PROTECTED]>, Werner Almesberger <[EMAIL PROTECTED]> As Werner Almesberger observed in a real program, poll(2) will never return if called with nfds == 0; which is stupid but not so badly deserving. I looked at the code and verified that indeed such a case is never detected and do_poll keeps looping, checking any fd passed, overlooking it wasn't passed any and calling schedule_timeout() endlessly. At least it's a TASK_INTERRUPTIBLE sleep... Signed-off-by: Paolo 'Blaisorblade' Giarrusso <[EMAIL PROTECTED]> Index: linux-2.6.git/fs/select.c =================================================================== --- linux-2.6.git.orig/fs/select.c +++ linux-2.6.git/fs/select.c @@ -629,6 +629,10 @@ int do_sys_poll(struct pollfd __user *uf struct fdtable *fdt; int max_fdset; + /* Otherwise below code would hang! */ + if (unlikely(nfds < 1)) + return -EINVAL; + /* Do a sanity check on nfds ... */ rcu_read_lock(); fdt = files_fdtable(current->files);
