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,
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;
break;
}
+ OSAddAtomic(-1, &fseh->active);
return (ret);
}
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;
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;