clean up deregistration of VNODE watches via kqueue()

The shotgun approach generates errors/warnings.
This commit is contained in:
Matthew Flatt 2013-07-11 17:10:57 -06:00
parent 3b89a05d46
commit 79abd1f629
4 changed files with 39 additions and 11 deletions

View File

@ -800,8 +800,11 @@ is created, it remains findable via @cpp{scheme_fd_to_semaphore} for a
particular read/write mode as long as @var{fd} has not become ready in
the read/write mode since the creation of the semaphore, or unless
@cpp{MZFD_REMOVE} has been used to remove the registered semaphore.
The @var{is_socket} argument indicates whether @var{fd} is a socket
or a filesystem descriptor (and the difference matters only for Windows).
The @var{is_socket} argument indicates whether @var{fd} is a socket or
a filesystem descriptor; the difference matters for Windows, and it
matters for BSD-based platforms where sockets are always supported and
other file descriptors are tested for whether they correspond to a
directory or regular file.
The @var{mode} argument is one of the following:
@ -824,6 +827,19 @@ The @var{mode} argument is one of the following:
@item{@cpp{MZFD_REMOVE} (= @cpp{5}) --- removes all recorded
semaphores for @var{fd} (unregistering a poll with the
operating system) and returns @cpp{NULL}.}
@item{@cpp{MZFD_CREATE_VNODE} (= @cpp{6}) --- creates or finds a
semaphore to reflect whether @var{fd} changes; on some
platforms, @cpp{MZFD_CREATE_VNODE} is the same as
@cpp{MZFD_CREATE_READ}; on other platforms, only one or the
other can be used on a given file descriptor.}
@item{@cpp{MZFD_CHECK_VNODE} (= @cpp{7}) --- like @cpp{MZFD_CHECK_READ},
but to find a semaphore recorded via @cpp{MZFD_CREATE_VNODE}.}
@item{@cpp{MZFD_REMOVE_VNODE} (= @cpp{8}) --- like @cpp{MZFD_REMOVE},
but to remove a semaphore recorded via @cpp{MZFD_CREATE_VNODE}.}
]}

View File

@ -2107,6 +2107,7 @@ extern Scheme_Extension_Table *scheme_extension_table;
#define MZFD_REMOVE 5
#define MZFD_CREATE_VNODE 6
#define MZFD_CHECK_VNODE 7
#define MZFD_REMOVE_VNODE 8
/*========================================================================*/

View File

@ -6152,7 +6152,7 @@ void scheme_filesystem_change_evt_cancel(Scheme_Object *evt, void *ignored_data)
fc->fd = 0;
}
# else
(void)scheme_fd_to_semaphore(fc->fd, MZFD_REMOVE, 0);
(void)scheme_fd_to_semaphore(fc->fd, MZFD_REMOVE_VNODE, 0);
scheme_close_file_fd(fc->fd);
scheme_post_sema_all(fc->sema);
# endif

View File

@ -3507,7 +3507,8 @@ Scheme_Object *scheme_fd_to_semaphore(intptr_t fd, int mode, int is_socket)
if (!v && ((mode == MZFD_CHECK_READ)
|| (mode == MZFD_CHECK_WRITE)
|| (mode == MZFD_CHECK_VNODE)
|| (mode == MZFD_REMOVE)))
|| (mode == MZFD_REMOVE)
|| (mode == MZFD_REMOVE_VNODE)))
return NULL;
if (!v) {
@ -3521,7 +3522,7 @@ Scheme_Object *scheme_fd_to_semaphore(intptr_t fd, int mode, int is_socket)
e = MZ_GET_FDSET(scheme_semaphore_fd_set, 2);
# endif
if (mode == MZFD_REMOVE) {
if ((mode == MZFD_REMOVE) || (mode == MZFD_REMOVE_VNODE)) {
s = SCHEME_VEC_ELS(v)[0];
if (!SCHEME_FALSEP(s))
scheme_post_sema_all(s);
@ -3532,14 +3533,24 @@ Scheme_Object *scheme_fd_to_semaphore(intptr_t fd, int mode, int is_socket)
scheme_hash_set(scheme_semaphore_fd_mapping, key, NULL);
# ifdef HAVE_KQUEUE_SYSCALL
{
GC_CAN_IGNORE struct kevent kev[3];
GC_CAN_IGNORE struct kevent kev[2];
struct timespec timeout = {0, 0};
int kr;
EV_SET(kev, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
EV_SET(&kev[1], fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
EV_SET(&kev[2], fd, EVFILT_VNODE, EV_DELETE, 0, 0, NULL);
int kr, pos = 0;
if (mode == MZFD_REMOVE_VNODE) {
EV_SET(&kev[pos], fd, EVFILT_VNODE, EV_DELETE, 0, 0, NULL);
pos++;
} else {
if (SCHEME_TRUEP(SCHEME_VEC_ELS(v)[0])) {
EV_SET(&kev[pos], fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
pos++;
}
if (SCHEME_TRUEP(SCHEME_VEC_ELS(v)[1])) {
EV_SET(&kev[pos], fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
pos++;
}
}
do {
kr = kevent(scheme_semaphore_fd_kqueue, kev, 3, NULL, 0, &timeout);
kr = kevent(scheme_semaphore_fd_kqueue, kev, pos, NULL, 0, &timeout);
} while ((kr == -1) && (errno == EINTR));
log_kqueue_error("remove", kr);
}