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 <info@bnoordhuis.nl>
This commit is contained in:
Gireesh Punathil 2018-12-25 03:31:34 -05:00 committed by Ben Noordhuis
parent 3233ccf169
commit dce03d58f4

View File

@ -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;