Date: Sat, 30 Mar 2013 09:14:34 -0700 From: John-Mark Gurney <jmg@funkthat.com> To: Bakul Shah <bakul@bitblocks.com> Cc: freebsd-net@freebsd.org, Carl Shapiro <carl.shapiro@gmail.com>, Andriy Gapon <avg@freebsd.org>, FreeBSD Hackers <freebsd-hackers@freebsd.org> Subject: Re: close(2) while accept(2) is blocked Message-ID: <20130330161434.GG76354@funkthat.com> In-Reply-To: <20130329235431.32D7FB82A@mail.bitblocks.com> References: <515475C7.6010404@FreeBSD.org> <CANVK_QgnC-pLGwh7Oad87JO_z1WmLeY3kfT9HhdpSzMnpjdNgA@mail.gmail.com> <20130329235431.32D7FB82A@mail.bitblocks.com>
next in thread | previous in thread | raw e-mail | index | archive | help
Bakul Shah wrote this message on Fri, Mar 29, 2013 at 16:54 -0700: > On Fri, 29 Mar 2013 14:30:59 PDT Carl Shapiro <carl.shapiro@gmail.com> wrote: > > > > In other operating systems, such as Solaris and MacOS X, closing the > > descriptor causes blocked system calls to return with an error. > > What happens if you select() on a socket and another thread > closes this socket? Ideally select() should return (with > EINTR?) so that the blocking thread can some cleanup action. > And if you do that, the blocking accept() case is not really > different. > > There is no point in *not* telling blocking threads that the > descriptor they're waiting on is one EBADF and nothing is > going to happen. > > > It is not obvious whether there is any benefit to having the current > > blocking behaviour. > > This may need some new kernel code but IMHO this is worth fixing. As someone else pointed out in this thread, if a userland program depends upon this behavior, it has a race condition in it... Thread 1 Thread 2 Thread 3 enters routine to read enters routine to close calls close(3) open() returns 3 does read(3) for orignal fd How can the original threaded program ensure that thread 2 doesn't create a new fd in between? So even if you use a lock, this won't help, because as far as I know, there is no enter read and unlock mutex call yet... I decided long ago that this is only solvable by proper use of locking and ensuring that if you call close (the syscall), that you do not have any other thread that may use the fd. It's the close routine's (not syscall) function to make sure it locks out other threads and all other are out of the code path that will use the fd before it calls close.. If someone could describe how this new eject a person from read could be done in a race safe way, then I'd say go ahead w/ it... Otherwise we're just moving the race around, and letting people think that they have solved the problem when they haven't... I think I remeber another thread about this from a year or two ago, but I couldn't find it... If someone finds it, posting a link would be nice.. -- John-Mark Gurney Voice: +1 415 225 5579 "All that I will do, has been done, All that I have, has not."
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130330161434.GG76354>