diff options
| author | Eli Zaretskii | 2020-03-27 15:43:20 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2020-03-27 16:19:20 +0300 |
| commit | f98ee21c0e3d4e00569fdd9f2671fd8394ab8a65 (patch) | |
| tree | 2fbc74b9c43d67ecd1c6fcb5f46841578248d3b5 /test | |
| parent | e4f8098b9e6e1a0b310cb64f73d39d2b0d3d9f2f (diff) | |
| download | emacs-f98ee21c0e3d4e00569fdd9f2671fd8394ab8a65.tar.gz emacs-f98ee21c0e3d4e00569fdd9f2671fd8394ab8a65.zip | |
Port the 'module/async-pipe' test to MS-Windows
These changes let the code compile and produce a valid DLL, but the
test hangs. It looks like the hang is in Fdelete_process, when it
closes one of the descriptors of the pipe process.
In addition, this use of the pipe process cannot currently work
on MS-Windows, since make-pipe-process doesn't set up the reader
thread to read from the Emacs's side of the pipe, so the select
emulation doesn't know there's stuff to read from that pipe.
* test/data/emacs-module/mod-test.c [WINDOWSNT]: Include
windows.h.
(ALIGN_STACK) [!__x86_64__]: Define for 32-bit builds.
(sleep_for_half_second): New function.
(write_to_pipe): Declare return type differently for WINDOWSNT.
Call sleep_for_half_second.
(Fmod_test_async_pipe) [WINDOWSNT]: Use _beginthread as substitute
for pthread_create.
(invalid_finalizer): Replace non_ASCII character in a comment.
* test/src/emacs-module-tests.el (module/async-pipe): Skip on
MS-Windows, as the test fails and then hangs.
Diffstat (limited to 'test')
| -rw-r--r-- | test/data/emacs-module/mod-test.c | 48 | ||||
| -rw-r--r-- | test/src/emacs-module-tests.el | 3 |
2 files changed, 44 insertions, 7 deletions
diff --git a/test/data/emacs-module/mod-test.c b/test/data/emacs-module/mod-test.c index 61733f1ef49..5e3112f4471 100644 --- a/test/data/emacs-module/mod-test.c +++ b/test/data/emacs-module/mod-test.c | |||
| @@ -30,8 +30,18 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 30 | #include <string.h> | 30 | #include <string.h> |
| 31 | #include <time.h> | 31 | #include <time.h> |
| 32 | 32 | ||
| 33 | #include <pthread.h> | 33 | #ifdef WINDOWSNT |
| 34 | #include <unistd.h> | 34 | /* Cannot include <process.h> because of the local header by the same |
| 35 | name, sigh. */ | ||
| 36 | uintptr_t _beginthread (void (__cdecl *)(void *), unsigned, void *); | ||
| 37 | # if !defined __x86_64__ | ||
| 38 | # define ALIGN_STACK __attribute__((force_align_arg_pointer)) | ||
| 39 | # endif | ||
| 40 | # include <windows.h> /* for Sleep */ | ||
| 41 | #else /* !WINDOWSNT */ | ||
| 42 | # include <pthread.h> | ||
| 43 | # include <unistd.h> | ||
| 44 | #endif | ||
| 35 | 45 | ||
| 36 | #ifdef HAVE_GMP | 46 | #ifdef HAVE_GMP |
| 37 | #include <gmp.h> | 47 | #include <gmp.h> |
| @@ -302,7 +312,7 @@ Fmod_test_invalid_load (emacs_env *env, ptrdiff_t nargs, emacs_value *args, | |||
| 302 | } | 312 | } |
| 303 | 313 | ||
| 304 | /* An invalid finalizer: Finalizers are run during garbage collection, | 314 | /* An invalid finalizer: Finalizers are run during garbage collection, |
| 305 | where Lisp code can’t be executed. -module-assertions tests for | 315 | where Lisp code can't be executed. -module-assertions tests for |
| 306 | this case. */ | 316 | this case. */ |
| 307 | 317 | ||
| 308 | static emacs_env *current_env; | 318 | static emacs_env *current_env; |
| @@ -542,20 +552,39 @@ Fmod_test_function_finalizer_calls (emacs_env *env, ptrdiff_t nargs, | |||
| 542 | return env->funcall (env, Flist, 2, list_args); | 552 | return env->funcall (env, Flist, 2, list_args); |
| 543 | } | 553 | } |
| 544 | 554 | ||
| 555 | static void | ||
| 556 | sleep_for_half_second (void) | ||
| 557 | { | ||
| 558 | /* mingw.org's MinGW has nanosleep, but MinGW64 doesn't. */ | ||
| 559 | #ifdef WINDOWSNT | ||
| 560 | Sleep (500); | ||
| 561 | #else | ||
| 562 | const struct timespec sleep = {0, 500000000}; | ||
| 563 | if (nanosleep (&sleep, NULL) != 0) | ||
| 564 | perror ("nanosleep"); | ||
| 565 | #endif | ||
| 566 | } | ||
| 567 | |||
| 568 | #ifdef WINDOWSNT | ||
| 569 | static void ALIGN_STACK | ||
| 570 | #else | ||
| 545 | static void * | 571 | static void * |
| 572 | #endif | ||
| 546 | write_to_pipe (void *arg) | 573 | write_to_pipe (void *arg) |
| 547 | { | 574 | { |
| 548 | /* We sleep a bit to test that writing to a pipe is indeed possible | 575 | /* We sleep a bit to test that writing to a pipe is indeed possible |
| 549 | if no environment is active. */ | 576 | if no environment is active. */ |
| 550 | const struct timespec sleep = {0, 500000000}; | 577 | sleep_for_half_second (); |
| 551 | if (nanosleep (&sleep, NULL) != 0) | ||
| 552 | perror ("nanosleep"); | ||
| 553 | FILE *stream = arg; | 578 | FILE *stream = arg; |
| 579 | /* The string below should be identical to the one we compare with | ||
| 580 | in emacs-module-tests.el:module/async-pipe. */ | ||
| 554 | if (fputs ("data from thread", stream) < 0) | 581 | if (fputs ("data from thread", stream) < 0) |
| 555 | perror ("fputs"); | 582 | perror ("fputs"); |
| 556 | if (fclose (stream) != 0) | 583 | if (fclose (stream) != 0) |
| 557 | perror ("close"); | 584 | perror ("close"); |
| 585 | #ifndef WINDOWSNT | ||
| 558 | return NULL; | 586 | return NULL; |
| 587 | #endif | ||
| 559 | } | 588 | } |
| 560 | 589 | ||
| 561 | static emacs_value | 590 | static emacs_value |
| @@ -572,12 +601,17 @@ Fmod_test_async_pipe (emacs_env *env, ptrdiff_t nargs, emacs_value *args, | |||
| 572 | signal_errno (env, "fdopen"); | 601 | signal_errno (env, "fdopen"); |
| 573 | return NULL; | 602 | return NULL; |
| 574 | } | 603 | } |
| 604 | #ifdef WINDOWSNT | ||
| 605 | uintptr_t thd = _beginthread (write_to_pipe, 0, stream); | ||
| 606 | int error = (thd == (uintptr_t)-1L) ? errno : 0; | ||
| 607 | #else /* !WINDOWSNT */ | ||
| 575 | pthread_t thread; | 608 | pthread_t thread; |
| 576 | int error | 609 | int error |
| 577 | = pthread_create (&thread, NULL, write_to_pipe, stream); | 610 | = pthread_create (&thread, NULL, write_to_pipe, stream); |
| 611 | #endif | ||
| 578 | if (error != 0) | 612 | if (error != 0) |
| 579 | { | 613 | { |
| 580 | signal_system_error (env, error, "pthread_create"); | 614 | signal_system_error (env, error, "thread create"); |
| 581 | if (fclose (stream) != 0) | 615 | if (fclose (stream) != 0) |
| 582 | perror ("fclose"); | 616 | perror ("fclose"); |
| 583 | return NULL; | 617 | return NULL; |
diff --git a/test/src/emacs-module-tests.el b/test/src/emacs-module-tests.el index 1f91795e1e6..6851b890451 100644 --- a/test/src/emacs-module-tests.el +++ b/test/src/emacs-module-tests.el | |||
| @@ -426,6 +426,7 @@ See Bug#36226." | |||
| 426 | 426 | ||
| 427 | (ert-deftest module/async-pipe () | 427 | (ert-deftest module/async-pipe () |
| 428 | "Check that writing data from another thread works." | 428 | "Check that writing data from another thread works." |
| 429 | (skip-unless (not (eq system-type 'windows-nt))) ; FIXME! | ||
| 429 | (with-temp-buffer | 430 | (with-temp-buffer |
| 430 | (let ((process (make-pipe-process :name "module/async-pipe" | 431 | (let ((process (make-pipe-process :name "module/async-pipe" |
| 431 | :buffer (current-buffer) | 432 | :buffer (current-buffer) |
| @@ -435,6 +436,8 @@ See Bug#36226." | |||
| 435 | (progn | 436 | (progn |
| 436 | (mod-test-async-pipe process) | 437 | (mod-test-async-pipe process) |
| 437 | (should (accept-process-output process 1)) | 438 | (should (accept-process-output process 1)) |
| 439 | ;; The string below must be identical to what | ||
| 440 | ;; mod-test.c:write_to_pipe produces. | ||
| 438 | (should (equal (buffer-string) "data from thread"))) | 441 | (should (equal (buffer-string) "data from thread"))) |
| 439 | (delete-process process))))) | 442 | (delete-process process))))) |
| 440 | 443 | ||