From owner-freebsd-hackers@FreeBSD.ORG Sat Mar 30 16:55:26 2013 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 1D3AF5EF for ; Sat, 30 Mar 2013 16:55:26 +0000 (UTC) (envelope-from markd-freebsd-net@bushwire.net) Received: from smtp1.bushwire.net (f5.bushwire.net [199.48.133.46]) by mx1.freebsd.org (Postfix) with SMTP id E90AAD3 for ; Sat, 30 Mar 2013 16:55:25 +0000 (UTC) Received: (qmail 12681 invoked by uid 1001); 30 Mar 2013 16:48:03 -0000 Delivered-To: qmda-intercept-freebsd-hackers@freebsd.org DomainKey-Signature: a=rsa-sha1; q=dns; c=simple; s=2004; d=bushwire.net; b=3IJ6OWc4TVBvKz6r35kPNDJrHdeaAiBcoNehaDN/D/As6rvzxr3z+YWNJKvx2RWa; Comments: DomainKeys? See http://en.wikipedia.org/wiki/DomainKeys DomainKey-Trace-MD: h=16; b=36; l=C18R71D32M65F45T27C51S48R42?69?46?38M17C39C27I50; Comments: QMDA 0.3 Received: (qmail 12657 invoked by uid 1001); 30 Mar 2013 16:48:03 -0000 Date: 30 Mar 2013 16:48:03 +0000 Message-ID: <20130330164803.12656.qmail@f5-external.bushwire.net> From: "Mark" To: freebsd-net@freebsd.org Subject: Re: close(2) while accept(2) is blocked References: <515475C7.6010404@FreeBSD.org> <20130329235431.32D7FB82A@mail.bitblocks.com> <20130330161434.GG76354@funkthat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <20130330161434.GG76354@funkthat.com> X-Mailman-Approved-At: Sat, 30 Mar 2013 17:05:09 +0000 Cc: FreeBSD Hackers X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 30 Mar 2013 16:55:26 -0000 > 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... Right. The only "safe" way is to have all blocking syscalls on the same fd in the same process return to userland. This would need to be initiated in the close() syscall. Btw. Threads aren't the only scenario. A signal handler can also close the fd. Maybe not advised, but I have used this "technique" to force a return from a blocking accept() call since about FBSD4.x Mark.