Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 25 Nov 2005 12:20:13 +0000 (GMT)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Jon <comepu@gmail.com>
Cc:        freebsd-net@freebsd.org
Subject:   Re: a question about socket-syscall, thinks
Message-ID:  <20051125121352.U81764@fledge.watson.org>
In-Reply-To: <002001c5f19b$3c198ee0$ba00a8c0@wtfzhangj>
References:  <002001c5f19b$3c198ee0$ba00a8c0@wtfzhangj>

next in thread | previous in thread | raw e-mail | index | archive | help

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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20051125121352.U81764>