From owner-freebsd-net@FreeBSD.ORG Fri Nov 25 12:20:14 2005 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id CB69016A41F for ; Fri, 25 Nov 2005 12:20:14 +0000 (GMT) (envelope-from rwatson@FreeBSD.org) Received: from cyrus.watson.org (cyrus.watson.org [209.31.154.42]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7B09543D4C for ; Fri, 25 Nov 2005 12:20:14 +0000 (GMT) (envelope-from rwatson@FreeBSD.org) Received: from fledge.watson.org (fledge.watson.org [209.31.154.41]) by cyrus.watson.org (Postfix) with ESMTP id 0B42046B16; Fri, 25 Nov 2005 07:20:14 -0500 (EST) Date: Fri, 25 Nov 2005 12:20:13 +0000 (GMT) From: Robert Watson X-X-Sender: robert@fledge.watson.org To: Jon In-Reply-To: <002001c5f19b$3c198ee0$ba00a8c0@wtfzhangj> Message-ID: <20051125121352.U81764@fledge.watson.org> References: <002001c5f19b$3c198ee0$ba00a8c0@wtfzhangj> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: freebsd-net@freebsd.org Subject: Re: a question about socket-syscall, thinks X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 25 Nov 2005 12:20:14 -0000 On Fri, 25 Nov 2005, Jon wrote: > NET_LOCK_GIANT(); > error = socreate(uap->domain, &so, uap->type, uap->protocol, > td->td_ucred, td); > NET_UNLOCK_GIANT(); > if (error) { > fdclose(fdp, fp, fd, td); > } else { > FILEDESC_LOCK_FAST(fdp); > fp->f_data = so; /* already has ref count */ > fp->f_flag = FREAD|FWRITE; > fp->f_ops = &socketops; > fp->f_type = DTYPE_SOCKET; > FILEDESC_UNLOCK_FAST(fdp); > td->td_retval[0] = fd; > } > fdrop(fp, td); > return (error); > > I found these lines in "kern/uipc_syscalls.c(166-182, version:5.4)". I > had a question! Why drop "fp" if socreate function return success? Can > you tell me? Thank you very much! 'struct file' is a reference counted object, where references are typically one of two sorts: - References can be owned by file descriptor arrays (struct filedesc). - Referneces can be owned by threads currently operating on the file descriptor. falloc() initialized the file descriptor reference count to 1 to reflect the reference in the file descriptor array, and then bumps it by 1 if the caller has requested a struct file * result pointer not just a file descriptor index. When falloc() returns a struct file reference, the caller holds a valid reference, which prevents it from being garbage collected as a result of a simultaneous close() by another thread. When the thread calling socket() is done initializing the socket associated with the file descriptor, it calls fdrop() to release the extra thread reference. The file descriptor will still be referenced by the file descriptor array for the process, however (i.e., the reference count drops from 2 to 1, assuming no simultaneous close()). Other system calls operating on file descriptors after creation use fget_*() (sometimes wrapped) to acquire an additional thread reference to the struct file, and similarly release that reference using fdrop() when done. Robert N M Watson