diff options
author | Brad King <brad.king@kitware.com> | 2017-12-23 13:01:11 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2018-01-10 15:18:12 (GMT) |
commit | dd945345715b90b2a1db769865c79d86a1dfad06 (patch) | |
tree | c3d2095e4579d28959371516e5484c5cbc011385 | |
parent | 7e0eb77f2f0da764ba9d8a4045351bd7799e101d (diff) | |
download | CMake-dd945345715b90b2a1db769865c79d86a1dfad06.zip CMake-dd945345715b90b2a1db769865c79d86a1dfad06.tar.gz CMake-dd945345715b90b2a1db769865c79d86a1dfad06.tar.bz2 |
cmCTestMultiProcessHandler: Add helper to make libuv use SA_RESTART
Prior to 1.19, libuv does not use SA_RESTART in its signal handler.
Add a helper to cause libuv to install its handler and then revise
the handler's flags to add SA_RESTART.
-rw-r--r-- | Source/CTest/cmCTestMultiProcessHandler.cxx | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index 6cdec8d..4a980d7 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -22,6 +22,43 @@ #include <stdlib.h> #include <utility> +#if defined(CMAKE_USE_SYSTEM_LIBUV) && !defined(_WIN32) && \ + UV_VERSION_MAJOR == 1 && UV_VERSION_MINOR < 19 +#define CMAKE_UV_SIGNAL_HACK +/* + libuv does not use SA_RESTART on its signal handler, but C++ streams + depend on it for reliable i/o operations. This RAII helper convinces + libuv to install its handler, and then revises the handler to add the + SA_RESTART flag. We use a distinct uv loop that never runs to avoid + ever really getting a callback. libuv may fill the hack loop's signal + pipe and then stop writing, but that won't break any real loops. + */ +class cmUVSignalHackRAII +{ + uv_loop_t HackLoop; + cm::uv_signal_ptr HackSignal; + static void HackCB(uv_signal_t*, int) {} +public: + cmUVSignalHackRAII() + { + uv_loop_init(&this->HackLoop); + this->HackSignal.init(this->HackLoop); + this->HackSignal.start(HackCB, SIGCHLD); + struct sigaction hack_sa; + sigaction(SIGCHLD, NULL, &hack_sa); + if (!(hack_sa.sa_flags & SA_RESTART)) { + hack_sa.sa_flags |= SA_RESTART; + sigaction(SIGCHLD, &hack_sa, NULL); + } + } + ~cmUVSignalHackRAII() + { + this->HackSignal.stop(); + uv_loop_close(&this->HackLoop); + } +}; +#endif + class TestComparator { public: |