From owner-freebsd-net@FreeBSD.ORG Sat Mar 30 16:54:45 2013 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id A63B2559 for ; Sat, 30 Mar 2013 16:54:45 +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 7C33DC5 for ; Sat, 30 Mar 2013 16:54:44 +0000 (UTC) Received: (qmail 12664 invoked by uid 1001); 30 Mar 2013 16:48:03 -0000 Delivered-To: qmda-intercept-freebsd-net@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> Cc: FreeBSD Hackers X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 30 Mar 2013 16:54:45 -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.