From 5d68ec297a0627764236c5c08600e73b9119f916 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Sat, 17 Jun 2017 21:12:29 -0600 Subject: [PATCH] rktio: repair for Windows fs-change Also, add stress mode to rktio demo. --- racket/src/racket/src/port.c | 15 +++++++++ racket/src/rktio/.gitignore | 1 + racket/src/rktio/demo.c | 54 +++++++++++++++++++++++++------ racket/src/rktio/make32.bat | 2 +- racket/src/rktio/make64.bat | 2 +- racket/src/rktio/rktio.h | 2 +- racket/src/rktio/rktio_fd.c | 2 -- racket/src/rktio/rktio_poll_set.c | 2 ++ 8 files changed, 66 insertions(+), 14 deletions(-) diff --git a/racket/src/racket/src/port.c b/racket/src/racket/src/port.c index d4ed339614..bedf634ffc 100644 --- a/racket/src/racket/src/port.c +++ b/racket/src/racket/src/port.c @@ -4309,8 +4309,23 @@ Scheme_Object *scheme_filesystem_change_evt(Scheme_Object *path, int flags, int "filesystem-change-evt", NULL, SCHEME_GUARD_FILE_EXISTS); + rfc = rktio_fs_change(scheme_rktio, filename, scheme_semaphore_fd_set); + if (!rfc + && !(rktio_fs_change_properties(scheme_rktio) & RKTIO_FS_CHANGE_FILE_LEVEL) + && scheme_file_exists(filename)) { + Scheme_Object *base, *name; + int is_dir; + char *try_filename; + name = scheme_split_path(filename, strlen(filename), &base, &is_dir, SCHEME_PLATFORM_PATH_KIND); + try_filename = scheme_expand_string_filename(base, + "filesystem-change-evt", + NULL, + SCHEME_GUARD_FILE_EXISTS); + rfc = rktio_fs_change(scheme_rktio, try_filename, scheme_semaphore_fd_set); + } + if (!rfc) { if (scheme_last_error_is_racket(RKTIO_ERROR_UNSUPPORTED)) { scheme_raise_exn(MZEXN_FAIL_UNSUPPORTED, diff --git a/racket/src/rktio/.gitignore b/racket/src/rktio/.gitignore index 461053acf9..d1153d751d 100644 --- a/racket/src/rktio/.gitignore +++ b/racket/src/rktio/.gitignore @@ -1,4 +1,5 @@ # When building and running the demo with MSVC: /demo.exe /demo.obj +/demo.pdb /test1 diff --git a/racket/src/rktio/demo.c b/racket/src/rktio/demo.c index 69b0680a05..b6238686e9 100644 --- a/racket/src/rktio/demo.c +++ b/racket/src/rktio/demo.c @@ -482,6 +482,28 @@ static rktio_fd_t *connect_loop(rktio_t *rktio, rktio_addrinfo_t *addr, rktio_ad return fd; } +static rktio_fd_t *accept_loop(rktio_t *rktio, rktio_listener_t *lnr) +{ + rktio_fd_t *fd2; + rktio_poll_set_t *ps; + + while (rktio_poll_accept_ready(rktio, lnr) == RKTIO_POLL_NOT_READY) { + ps = rktio_make_poll_set(rktio); + check_valid(ps); + + rktio_poll_add_accept(rktio, lnr, ps); + rktio_sleep(rktio, 0, ps, NULL); + rktio_poll_set_forget(rktio, ps); + } + + check_valid(rktio_poll_accept_ready(rktio, lnr) == RKTIO_POLL_READY); + + fd2 = rktio_accept(rktio, lnr); + check_valid(fd2); + + return fd2; +} + static char *month_name(rktio_t *rktio, int month) { static char *months[] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "NOV", "DEC"}; @@ -507,11 +529,13 @@ int main(int argc, char **argv) rktio_directory_list_t *ls; rktio_file_copy_t *cp; rktio_timestamp_t *ts1, *ts1a; - int verbose = 0, dont_rely_on_sigchild = 0; + int verbose = 0, dont_rely_on_sigchild = 0, stress = 0; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-v")) verbose = 1; + else if (!strcmp(argv[i], "--stress")) + stress = 1; else if (!strcmp(argv[i], "--sleep-blocks-sigchld")) { /* Seems useful for Valgrind on MacOS */ dont_rely_on_sigchild = 1; @@ -676,9 +700,12 @@ int main(int argc, char **argv) if (verbose) printf("pipe\n"); - { + for (i = 0; i < (stress ? 100 : 1); i++) { rktio_fd_t **pipe_fds; - + + if (stress && verbose) + printf(" iter %d\n", i); + pipe_fds = rktio_make_pipe(rktio, 0); check_valid(pipe_fds); @@ -704,6 +731,15 @@ int main(int argc, char **argv) if (!PIPE_IMMEDIATELY_READY) wait_read(rktio, fd); check_drain_read(rktio, fd, 0, verbose); + + while (rktio_poll_write_flushed(rktio, fd2) == RKTIO_POLL_NOT_READY) { + rktio_poll_set_t *ps; + ps = rktio_make_poll_set(rktio); + check_valid(ps); + rktio_poll_add(rktio, fd, ps, RKTIO_POLL_FLUSH); + rktio_sleep(rktio, 0, ps, NULL); + rktio_poll_set_forget(rktio, ps); + } check_valid(rktio_poll_write_flushed(rktio, fd2) == RKTIO_POLL_READY); check_valid(rktio_close(rktio, fd)); @@ -715,10 +751,13 @@ int main(int argc, char **argv) if (verbose) printf("tcp\n"); - { + for (i = 0; i < (stress ? 100 : 1); i++) { rktio_addrinfo_t *addr; rktio_listener_t *lnr; + if (stress && verbose) + printf(" iter %d\n", i); + check_many_lookup(rktio); addr = lookup_loop(rktio, NULL, 4536, -1, 1, 1); @@ -732,10 +771,7 @@ int main(int argc, char **argv) addr = lookup_loop(rktio, "localhost", 4536, -1, 0, 1); fd = connect_loop(rktio, addr, NULL); - check_valid(rktio_poll_accept_ready(rktio, lnr) == RKTIO_POLL_READY); - - fd2 = rktio_accept(rktio, lnr); - check_valid(fd2); + fd2 = accept_loop(rktio, lnr); check_valid(!rktio_poll_accept_ready(rktio, lnr)); { @@ -776,7 +812,7 @@ int main(int argc, char **argv) fd = connect_loop(rktio, addr, NULL); rktio_addrinfo_free(rktio, addr); - fd2 = rktio_accept(rktio, lnr); + fd2 = accept_loop(rktio, lnr); if (verbose) printf(" fill\n"); diff --git a/racket/src/rktio/make32.bat b/racket/src/rktio/make32.bat index 1023f87da2..d48f60906e 100644 --- a/racket/src/rktio/make32.bat +++ b/racket/src/rktio/make32.bat @@ -2,4 +2,4 @@ echo ============================================ echo Assumes that the "librktio" project is built echo ============================================ -cl /I..\worksp\librktio demo.c ..\worksp\librktio\Win32\Release\librktio.lib ws2_32.lib user32.lib shell32.lib +cl /Zi /I..\worksp\librktio demo.c ..\worksp\librktio\Win32\Release\librktio.lib ws2_32.lib user32.lib shell32.lib diff --git a/racket/src/rktio/make64.bat b/racket/src/rktio/make64.bat index 813175453e..063bf68ee5 100644 --- a/racket/src/rktio/make64.bat +++ b/racket/src/rktio/make64.bat @@ -2,4 +2,4 @@ echo ============================================ echo Assumes that the "librktio" project is built echo ============================================ -cl /I..\worksp\librktio demo.c ..\worksp\librktio\x64\Release\librktio.lib ws2_32.lib user32.lib shell32.lib +cl /Zi /I..\worksp\librktio demo.c ..\worksp\librktio\x64\Release\librktio.lib ws2_32.lib user32.lib shell32.lib diff --git a/racket/src/rktio/rktio.h b/racket/src/rktio/rktio.h index 8e8a974cf6..7e5274e397 100644 --- a/racket/src/rktio/rktio.h +++ b/racket/src/rktio/rktio.h @@ -515,7 +515,7 @@ RKTIO_EXTERN rktio_fs_change_t *rktio_fs_change(rktio_t *rktio, const char *path /* Creates a filesystem-change tracker that reports changes in `path` after creation of the tracker. The properties repotred by `rktio_fs_change_properties` report various aspects of how the - tracket behaves. In particular, the `ltps` argument can be NULL + tracker behaves. In particular, the `ltps` argument can be NULL unless the `RKTIO_FS_CHANGE_NEED_LTPS` property is reported; if `lt` is provided, then the tracker must be canceled or discovered ready before `ltps` is closed. */ diff --git a/racket/src/rktio/rktio_fd.c b/racket/src/rktio/rktio_fd.c index 260b982552..6ffc9636f8 100644 --- a/racket/src/rktio/rktio_fd.c +++ b/racket/src/rktio/rktio_fd.c @@ -1313,8 +1313,6 @@ intptr_t rktio_write(rktio_t *rktio, rktio_fd_t *rfd, const char *buffer, intptr errsaved = oth->err_no; ok = 0; } else if (oth->buflen == RKTIO_FD_BUFFSIZE) { - /* clear any leftover notifications */ - WaitForSingleObject(oth->ready_sema, 0); ok = 1; } else { intptr_t topp; diff --git a/racket/src/rktio/rktio_poll_set.c b/racket/src/rktio/rktio_poll_set.c index 25cd08036e..10e3a7c853 100644 --- a/racket/src/rktio/rktio_poll_set.c +++ b/racket/src/rktio/rktio_poll_set.c @@ -518,6 +518,8 @@ void rktio_merge_fd_sets(rktio_poll_set_t *fds, rktio_poll_set_t *src_fds) if (src_fds->sockets[i] != INVALID_SOCKET) rktio_fdset(fds, (intptr_t)src_fds->sockets[i]); } + if (src_fds->no_sleep) + fds->no_sleep = 1; } void rktio_clean_fd_set(rktio_poll_set_t *fds)