a question about socket-syscall, thinks
Robert Watson
rwatson at FreeBSD.org
Fri Nov 25 12:20:14 GMT 2005
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
More information about the freebsd-net
mailing list