On Monday 01 October 2007 04:15, Davide Libenzi wrote: > On Mon, 1 Oct 2007, Denys Vlasenko wrote: > > > My use case is: I want to do a nonblocking read on descriptor 0 (stdin). > > It may be a pipe or a socket. > > > > There may be other processes which share this descriptor with me, > > I simply cannot know that. And they, too, may want to do reads on it. > > > > I want to do nonblocking read in such a way that neither those other > > processes will ever see fd switching to O_NONBLOCK and back, and > > I also want to be safe from other processes doing the same. > > > > I don't see how this can be done using standard unix primitives. > > Indeed. You could simulate non-blocking using poll with zero timeout, but > if another task may read/write on it, your following read/write may end up > blocking even after a poll returned the required events. > One way to solve this would be some sort of readx/writex where you pass an > extra flags parameter We have that already. They are called send and recv. ;) > (this could be done with sys_indirect, assuming > we'll ever get that mainline) where you specify the non-blocking > requirement for-this-call, and not as global per-file flag. Then, of > course, you'll have to modify all the "file->f_flags & O_NONBLOCK" tests > (and there are many of them) to check for that flag too (that can be a > per task_struct flag). Attached patch detects send/recv(fd, buf, size, MSG_DONTWAIT) on non-sockets and turns them into non-blocking write/read. Since filp->f_flags appear to be read and modified without any locking, I cannot modify it without potentially affecting other processes accessing the same file through shared struct file. Therefore I simply make a temporary copy of struct file, set O_NONBLOCK in it and pass it to vfs_read/write. Is this heresy? ;) I see only one spinlock in struct file: #ifdef CONFIG_EPOLL spinlock_t f_ep_lock; #endif /* #ifdef CONFIG_EPOLL */ Do I need to take it? Also attached is ndelaytest.c which can be used to test that send(MSG_DONTWAIT) indeed is failing with EAGAIN if write would block and that other processes never see O_NONBLOCK set. Comments? -- vda