From dce03d58f4f86cd7e30e167e04c07425b3e51888 Mon Sep 17 00:00:00 2001 From: Gireesh Punathil Date: Tue, 25 Dec 2018 03:31:34 -0500 Subject: [PATCH] aix: manually trigger fs event monitoring In AIX, fs watch feature leverages AHAFS function. According to AHAFS, monitoring of events does not begin until the monitoring application issues a select() or a blocking read() call. In edge cases where the watch request as well as fs event both occurs in single event loop cycle, we miss the event, as the event monitors are created but not yet registered in the current cycle, instead only enqueued into the poll structure, that will be taken up with the OS on the loop edge only. Trigger a select call in-line on the monitoring fd, that tells AHAFS to kick-start the moitoring. Fixes: https://github.com/libuv/libuv/issues/2118 PR-URL: https://github.com/libuv/libuv/pull/2123 Reviewed-By: Ben Noordhuis --- src/unix/aix.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/unix/aix.c b/src/unix/aix.c index 44c9cf5b..6642f026 100644 --- a/src/unix/aix.c +++ b/src/unix/aix.c @@ -555,7 +555,7 @@ static int uv__setup_ahafs(const char* filename, int *fd) { sprintf(mon_file_write_string, "CHANGED=YES;WAIT_TYPE=WAIT_IN_SELECT;INFO_LVL=1"); rc = write(*fd, mon_file_write_string, strlen(mon_file_write_string)+1); - if (rc < 0) + if (rc < 0 && errno != EBUSY) return UV__ERR(errno); return 0; @@ -728,6 +728,8 @@ int uv_fs_event_start(uv_fs_event_t* handle, char cwd[PATH_MAX]; char absolute_path[PATH_MAX]; char readlink_cwd[PATH_MAX]; + struct timeval zt; + fd_set pollfd; /* Figure out whether filename is absolute or not */ @@ -768,6 +770,15 @@ int uv_fs_event_start(uv_fs_event_t* handle, uv__io_start(handle->loop, &handle->event_watcher, POLLIN); + /* AHAFS wants someone to poll for it to start mointoring. + * so kick-start it so that we don't miss an event in the + * eventuality of an event that occurs in the current loop. */ + do { + memset(&zt, 0, sizeof(zt)); + FD_ZERO(&pollfd); + FD_SET(fd, &pollfd); + rc = select(fd + 1, &pollfd, NULL, NULL, &zt); + } while (rc == -1 && errno == EINTR); return 0; #else return UV_ENOSYS;