summaryrefslogtreecommitdiffstats
path: root/sys/kern/uipc_syscalls.c
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2009-05-14 03:24:22 +0000
committerjeff <jeff@FreeBSD.org>2009-05-14 03:24:22 +0000
commit20397e643153b90263768cb71928b488cab2c91e (patch)
tree03247850c0c9db357665199f280535e6edca7d99 /sys/kern/uipc_syscalls.c
parentdc1ac440de95721f8b696146577a51ef7a418f59 (diff)
downloadFreeBSD-src-20397e643153b90263768cb71928b488cab2c91e.zip
FreeBSD-src-20397e643153b90263768cb71928b488cab2c91e.tar.gz
- Implement a lockless file descriptor lookup algorithm in
fget_unlocked(). - Save old file descriptor tables created on expansion until the entire descriptor table is freed so that pointers may be followed without regard for expanders. - Mark the file zone as NOFREE so we may attempt to reference potentially freed files. - Convert several fget_locked() users to fget_unlocked(). This requires us to manage reference counts explicitly but reduces locking overhead in the common case.
Diffstat (limited to 'sys/kern/uipc_syscalls.c')
-rw-r--r--sys/kern/uipc_syscalls.c25
1 files changed, 9 insertions, 16 deletions
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index f86e657..9adbbc6 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -122,23 +122,16 @@ getsock(struct filedesc *fdp, int fd, struct file **fpp, u_int *fflagp)
int error;
fp = NULL;
- if (fdp == NULL)
+ if (fdp == NULL || (fp = fget_unlocked(fdp, fd)) == NULL) {
error = EBADF;
- else {
- FILEDESC_SLOCK(fdp);
- fp = fget_locked(fdp, fd);
- if (fp == NULL)
- error = EBADF;
- else if (fp->f_type != DTYPE_SOCKET) {
- fp = NULL;
- error = ENOTSOCK;
- } else {
- fhold(fp);
- if (fflagp != NULL)
- *fflagp = fp->f_flag;
- error = 0;
- }
- FILEDESC_SUNLOCK(fdp);
+ } else if (fp->f_type != DTYPE_SOCKET) {
+ fdrop(fp, curthread);
+ fp = NULL;
+ error = ENOTSOCK;
+ } else {
+ if (fflagp != NULL)
+ *fflagp = fp->f_flag;
+ error = 0;
}
*fpp = fp;
return (error);
OpenPOWER on IntegriCloud