summaryrefslogtreecommitdiffstats
path: root/sys/kern/uipc_mqueue.c
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2007-12-30 01:42:15 +0000
committerjeff <jeff@FreeBSD.org>2007-12-30 01:42:15 +0000
commitce1863880500c459eb1395c1d6f81819e02e6608 (patch)
tree0f2354bfc200294c2629e6ecfba76e364beda579 /sys/kern/uipc_mqueue.c
parentbedce823534f9510ef9c65764069f927d359aeb8 (diff)
downloadFreeBSD-src-ce1863880500c459eb1395c1d6f81819e02e6608.zip
FreeBSD-src-ce1863880500c459eb1395c1d6f81819e02e6608.tar.gz
Remove explicit locking of struct file.
- Introduce a finit() which is used to initailize the fields of struct file in such a way that the ops vector is only valid after the data, type, and flags are valid. - Protect f_flag and f_count with atomic operations. - Remove the global list of all files and associated accounting. - Rewrite the unp garbage collection such that it no longer requires the global list of all files and instead uses a list of all unp sockets. - Mark sockets in the accept queue so we don't incorrectly gc them. Tested by: kris, pho
Diffstat (limited to 'sys/kern/uipc_mqueue.c')
-rw-r--r--sys/kern/uipc_mqueue.c23
1 files changed, 11 insertions, 12 deletions
diff --git a/sys/kern/uipc_mqueue.c b/sys/kern/uipc_mqueue.c
index 1c5cadb..8fe34bc 100644
--- a/sys/kern/uipc_mqueue.c
+++ b/sys/kern/uipc_mqueue.c
@@ -1999,12 +1999,8 @@ kmq_open(struct thread *td, struct kmq_open_args *uap)
mqnode_addref(pn);
sx_xunlock(&mqfs_data.mi_lock);
- FILE_LOCK(fp);
- fp->f_flag = (flags & (FREAD | FWRITE | O_NONBLOCK));
- fp->f_type = DTYPE_MQUEUE;
- fp->f_data = pn;
- fp->f_ops = &mqueueops;
- FILE_UNLOCK(fp);
+ finit(fp, flags & (FREAD | FWRITE | O_NONBLOCK), DTYPE_MQUEUE, pn,
+ &mqueueops);
FILEDESC_XLOCK(fdp);
if (fdp->fd_ofiles[fd] == fp)
@@ -2097,6 +2093,7 @@ kmq_setattr(struct thread *td, struct kmq_setattr_args *uap)
struct mqueue *mq;
struct file *fp;
struct mq_attr attr, oattr;
+ u_int oflag, flag;
int error;
if (uap->attr) {
@@ -2112,13 +2109,15 @@ kmq_setattr(struct thread *td, struct kmq_setattr_args *uap)
oattr.mq_maxmsg = mq->mq_maxmsg;
oattr.mq_msgsize = mq->mq_msgsize;
oattr.mq_curmsgs = mq->mq_curmsgs;
- FILE_LOCK(fp);
- oattr.mq_flags = (O_NONBLOCK & fp->f_flag);
if (uap->attr) {
- fp->f_flag &= ~O_NONBLOCK;
- fp->f_flag |= (attr.mq_flags & O_NONBLOCK);
- }
- FILE_UNLOCK(fp);
+ do {
+ oflag = flag = fp->f_flag;
+ flag &= ~O_NONBLOCK;
+ flag |= (attr.mq_flags & O_NONBLOCK);
+ } while (atomic_cmpset_int(&fp->f_flag, oflag, flag) == 0);
+ } else
+ oflag = fp->f_flag;
+ oattr.mq_flags = (O_NONBLOCK & oflag);
fdrop(fp, td);
if (uap->oattr)
error = copyout(&oattr, uap->oattr, sizeof(oattr));
OpenPOWER on IntegriCloud