X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/c0fea4742e91338fffdcf79f86a7c1d5e2b97eb1..0c530ab8987f0ae6a1a3d9284f40182b88852816:/bsd/vfs/vfs_fsevents.c diff --git a/bsd/vfs/vfs_fsevents.c b/bsd/vfs/vfs_fsevents.c index 3688244ef..801faa3c1 100644 --- a/bsd/vfs/vfs_fsevents.c +++ b/bsd/vfs/vfs_fsevents.c @@ -946,10 +946,13 @@ static int fsevents_installed = 0; static struct lock__bsd__ fsevents_lck; typedef struct fsevent_handle { + UInt32 flags; + SInt32 active; fs_event_watcher *watcher; struct selinfo si; } fsevent_handle; +#define FSEH_CLOSING 0x0001 static int fseventsf_read(struct fileproc *fp, struct uio *uio, @@ -981,15 +984,27 @@ fseventsf_ioctl(struct fileproc *fp, u_long cmd, caddr_t data, struct proc *p) pid_t pid = 0; fsevent_dev_filter_args *devfilt_args=(fsevent_dev_filter_args *)data; + OSAddAtomic(1, &fseh->active); + if (fseh->flags & FSEH_CLOSING) { + OSAddAtomic(-1, &fseh->active); + return 0; + } + switch (cmd) { case FIONBIO: case FIOASYNC: - return 0; + ret = 0; + break; case FSEVENTS_DEVICE_FILTER: { int new_num_devices; dev_t *devices_to_watch, *tmp=NULL; + if (fseh->flags & FSEH_CLOSING) { + ret = 0; + break; + } + if (devfilt_args->num_devices > 256) { ret = EINVAL; break; @@ -1044,6 +1059,7 @@ fseventsf_ioctl(struct fileproc *fp, u_long cmd, caddr_t data, struct proc *p) break; } + OSAddAtomic(-1, &fseh->active); return (ret); } @@ -1085,11 +1101,18 @@ static int fseventsf_close(struct fileglob *fg, struct proc *p) { fsevent_handle *fseh = (struct fsevent_handle *)fg->fg_data; + fs_event_watcher *watcher; + + OSBitOrAtomic(FSEH_CLOSING, &fseh->flags); + while (OSAddAtomic(0, &fseh->active) > 0) { + tsleep((caddr_t)fseh->watcher, PRIBIO, "fsevents-close", 1); + } - remove_watcher(fseh->watcher); - - fg->fg_data = NULL; + watcher = fseh->watcher; fseh->watcher = NULL; + fg->fg_data = NULL; + + remove_watcher(watcher); FREE(fseh, M_TEMP); return 0; @@ -1228,7 +1251,7 @@ fseventsioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) proc_fdunlock(p); copyout((void *)&fd, CAST_USER_ADDR_T(fse_clone_args->fd), sizeof(int32_t)); proc_fdlock(p); - *fdflags(p, fd) &= ~UF_RESERVED; + procfdtbl_releasefd(p, fd, NULL); fp_drop(p, fd, f, 1); proc_fdunlock(p); break;