From 20dc94adce6fd07f031ae26cc4bbb64438ab3a5d Mon Sep 17 00:00:00 2001 From: Sjors Provoost Date: Tue, 12 May 2026 11:34:42 +0200 Subject: [PATCH 1/6] build: stop referencing libmultiprocess example targets The libmultiprocess subtree no longer ships the example/ directory (it lives outside the published 'lib' branch), so the mpcalculator, mpprinter and mpexample targets are not defined. Drop the EXPORT_COMPILE_COMMANDS tweak that referenced them. --- cmake/libmultiprocess.cmake | 6 ------ 1 file changed, 6 deletions(-) diff --git a/cmake/libmultiprocess.cmake b/cmake/libmultiprocess.cmake index 027109a90511..1ba656972366 100644 --- a/cmake/libmultiprocess.cmake +++ b/cmake/libmultiprocess.cmake @@ -29,10 +29,4 @@ function(add_libmultiprocess subdir) # Add tests to "all" target so ctest can run them set_target_properties(mptest PROPERTIES EXCLUDE_FROM_ALL OFF) endif() - # Exclude examples from compilation database, because the examples are not - # built by default, and they contain generated c++ code. Without this - # exclusion, tools like clang-tidy and IWYU that make use of compilation - # database would complain that the generated c++ source files do not exist. An - # alternate fix could build "mpexamples" by default like "mptests" above. - set_target_properties(mpcalculator mpprinter mpexample PROPERTIES EXPORT_COMPILE_COMMANDS OFF) endfunction() From 64b28c98aa1721c8886c6d0b7837ead29bbb1bd5 Mon Sep 17 00:00:00 2001 From: Sjors Provoost Date: Tue, 12 May 2026 11:50:37 +0200 Subject: [PATCH 2/6] Squashed 'src/ipc/libmultiprocess/' changes from 3edbe8f67c..3c69d125a1 3c69d125a1 Merge bitcoin-core/libmultiprocess#260: event loop: tolerate unexpected exceptions in `post()` callbacks b8a48c65e6 event loop: tolerate unexpected exceptions in `post()` callbacks f787863d2c Merge bitcoin-core/libmultiprocess#270: doc: Bump version 10 > 11 a22f602910 doc: Bump version 10 > 11 git-subtree-dir: src/ipc/libmultiprocess git-subtree-split: 3c69d125a175084e4056ec9db8badb625e5f31d8 --- doc/versions.md | 7 ++++++- include/mp/version.h | 2 +- src/mp/proxy.cpp | 8 +++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/doc/versions.md b/doc/versions.md index 2c2ec50e7c6d..3cfa28e36fa8 100644 --- a/doc/versions.md +++ b/doc/versions.md @@ -7,9 +7,14 @@ Library versions are tracked with simple Versioning policy is described in the [version.h](../include/mp/version.h) include. -## v10 +## v11 - Current unstable version. +## [v10.0](https://github.com/bitcoin-core/libmultiprocess/commits/v10.0) +- Increases spawn test timeout to avoid spurious failures. +- Uses `throwRecoverableException` instead of raw `throw` to improve runtime error messages in macOS builds. +- Used in Bitcoin Core master branch, pulled in by [#34977](https://github.com/bitcoin/bitcoin/pull/34977). Also pulled into Bitcoin Core 31.x stable branch by [#35028](https://github.com/bitcoin/bitcoin/pull/35028). + ## [v9.0](https://github.com/bitcoin-core/libmultiprocess/commits/v9.0) - Fixes race conditions where worker thread could be used after destruction, where getParams() could be called after request cancel, and where m_on_cancel could be called after request finishes. - Adds `CustomHasField` hook to map Cap'n Proto null values to C++ null values. diff --git a/include/mp/version.h b/include/mp/version.h index 964667a98fb6..423ed460070c 100644 --- a/include/mp/version.h +++ b/include/mp/version.h @@ -24,7 +24,7 @@ //! pointing at the prior merge commit. The /doc/versions.md file should also be //! updated, noting any significant or incompatible changes made since the //! previous version. -#define MP_MAJOR_VERSION 10 +#define MP_MAJOR_VERSION 11 //! Minor version number. Should be incremented in stable branches after //! backporting changes. The /doc/versions.md file should also be updated to diff --git a/src/mp/proxy.cpp b/src/mp/proxy.cpp index d24208dbfd89..963050c3bcfc 100644 --- a/src/mp/proxy.cpp +++ b/src/mp/proxy.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -245,7 +246,12 @@ void EventLoop::loop() if (read_bytes != 1) throw std::logic_error("EventLoop wait_stream closed unexpectedly"); Lock lock(m_mutex); if (m_post_fn) { - Unlock(lock, *m_post_fn); + // m_post_fn throwing is never expected. If it does happen, the caller + // of EventLoop::post() will return without any indication of failure, + // which will likely cause other bugs. Log the error and continue. + KJ_IF_MAYBE(exception, kj::runCatchingExceptions([&]() MP_REQUIRES(m_mutex) { Unlock(lock, *m_post_fn); })) { + MP_LOG(*this, Log::Error) << "EventLoop: m_post_fn threw: " << kj::str(*exception).cStr(); + } m_post_fn = nullptr; m_cv.notify_all(); } else if (done()) { From 0dd3f5c98945c6daeff43fa1781c858fcb413e6b Mon Sep 17 00:00:00 2001 From: Sjors Provoost Date: Tue, 12 May 2026 11:50:48 +0200 Subject: [PATCH 3/6] Squashed 'src/ipc/libmultiprocess/' changes from 3c69d125a1..27ada40809 27ada40809 build: move library sources under lib/ for subtree split REVERT: 3c69d125a1 Merge bitcoin-core/libmultiprocess#260: event loop: tolerate unexpected exceptions in `post()` callbacks REVERT: b8a48c65e6 event loop: tolerate unexpected exceptions in `post()` callbacks REVERT: f787863d2c Merge bitcoin-core/libmultiprocess#270: doc: Bump version 10 > 11 REVERT: a22f602910 doc: Bump version 10 > 11 REVERT: 3edbe8f67c Merge bitcoin-core/libmultiprocess#268: Use throwRecoverableException instead of raw throw for stored exceptions REVERT: 23be44b0d3 Use throwRecoverableException instead of raw throw for stored exceptions REVERT: 75c2a2764c Merge bitcoin-core/libmultiprocess#266: test: increase spawn test child timeout to 30 seconds REVERT: 8b5f805301 Merge bitcoin-core/libmultiprocess#267: doc: Bump version 9 > 10 REVERT: cc0b23fc32 test: increase spawn test child timeout to 30 seconds REVERT: 050f878db8 doc: Improve versions.md descriptions and formatting REVERT: c6a288a889 doc: Bump version 9 > 10 REVERT: 70f632bda8 Merge bitcoin-core/libmultiprocess#265: ci: set LC_ALL in shell scripts REVERT: 8e8e564259 Merge bitcoin-core/libmultiprocess#249: fixes for race conditions on disconnects REVERT: 05d34cc2ec ci: set LC_ALL in shell scripts REVERT: e606fd84a8 Merge bitcoin-core/libmultiprocess#264: ci: reduce nproc multipliers REVERT: ff0eed1bf1 refactor: Use loop variable in type-context.h REVERT: ff1d8ba172 refactor: Move type-context.h getParams() call closer to use REVERT: 1dbc59a4aa race fix: m_on_cancel called after request finishes REVERT: 1643d05ba0 test: m_on_cancel called after request finishes REVERT: f5509a31fc race fix: getParams() called after request cancel REVERT: 4a60c39f24 test: getParams() called after request cancel REVERT: f11ec29ed2 race fix: worker thread destroyed before it is initialized REVERT: a1d643348f test: worker thread destroyed before it is initialized REVERT: 336023382c ci: reduce nproc multipliers REVERT: b090beb965 Merge bitcoin-core/libmultiprocess#256: ci: cache gnu32 nix store REVERT: be8622816d ci: cache gnu32 nix store REVERT: 975270b619 Merge bitcoin-core/libmultiprocess#263: ci: bump timeout factor to 40 REVERT: 09f10e5a59 ci: bump timeout factor to 40 REVERT: db8f76ad29 Merge bitcoin-core/libmultiprocess#253: ci: run some Bitcoin Core CI jobs REVERT: 55a9b557b1 ci: set Bitcoin Core CI test repetition REVERT: fb0fc84d55 ci: add TSan job with instrumented libc++ REVERT: 0f29c38725 ci: add Bitcoin Core IPC tests (ASan + macOS) REVERT: 3f64320315 Merge bitcoin-core/libmultiprocess#262: ci: enable clang-tidy in macOS job, use nullptr REVERT: cd9f8bdc9f Merge bitcoin-core/libmultiprocess#258: log: add socket connected info message and demote destroy logs to debug REVERT: b5d6258a42 Merge bitcoin-core/libmultiprocess#255: fix: use unsigned char cast and sizeof in LogEscape escape sequence REVERT: d94688e2c3 Merge bitcoin-core/libmultiprocess#251: Improved CustomBuildField for std::optional in IPC/libmultiprocess REVERT: a9499fad75 mp: use nullptr with pthread_threadid_np REVERT: f499e37850 ci: enable clang-tidy in macOS job REVERT: 98f1352159 log: add socket connected info message and demote destroy logs to debug REVERT: 554a481ea7 fix: use unsigned char cast and sizeof in LogEscape escape sequence REVERT: 1977b9f3f6 Use std::forward in CustomBuildField for std::optional to allow move semantics, resolves FIXME REVERT: 22bec918c9 Merge bitcoin-core/libmultiprocess#247: type-map: Work around LLVM 22 "out of bounds index" error REVERT: 8a5e3ae6ed Merge bitcoin-core/libmultiprocess#242: proxy-types: add CustomHasField hook to map Cap'n Proto values to null C++ values REVERT: e8d3524691 Merge bitcoin-core/libmultiprocess#246: doc: Bump version 8 > 9 REVERT: 97d877053b proxy-types: add CustomHasField hook for nullable decode paths REVERT: 8c2f10252c refactor: add missing includes to mp/type-data.h REVERT: b1638aceb4 doc: Bump version 8 > 9 REVERT: f61af48721 type-map: Work around LLVM 22 "out of bounds index" error REVERT: 1868a84451 Merge bitcoin-core/libmultiprocess#245: type-context.h: Extent cancel_mutex lock to prevent theoretical race REVERT: fd4a90d310 Merge bitcoin-core/libmultiprocess#244: ci: suppress two tidy lint issues REVERT: 16dfc36864 ci: avoid bugprone-unused-return-value lint in test REVERT: dacd5eda46 ci: suppress nontrivial-threadlocal lint in proxy.cpp REVERT: ef96a5b2be doc: Comment cleanups after #240 REVERT: e0f1cd7621 type-context.h: Extent cancel_mutex lock to prevent theoretical race REVERT: 290702c74c Merge bitcoin-core/libmultiprocess#240: Avoid errors from asynchronous (non-c++) clients REVERT: 3a69d4755a Merge bitcoin-core/libmultiprocess#241: doc: Bump version number v7 -> v8 REVERT: 0174450ca2 Prevent crash on unclean disconnect if abandoned IPC call returns interface pointer REVERT: ddb5f74196 Allow simultaneous calls on same Context.thread REVERT: c4762c7b51 refactor: Add ProxyServer::post() method REVERT: 0ade1b40ac doc: Bump version number REVERT: 1fc65008f7 Merge bitcoin-core/libmultiprocess#237: Made SpawnProcess() behavior safe post fork() REVERT: 5205a87cd9 test: check SpawnProcess post-fork safety REVERT: 69652f0edf Precompute argv before fork in SpawnProcess REVERT: 30a8681de6 SpawnProcess: avoid fd leak on close failure REVERT: d0fc1081d0 Merge bitcoin-core/libmultiprocess#196: ci: Add NetBSD job REVERT: 7b171f45bf Merge bitcoin-core/libmultiprocess#234: doc: Fix typos and grammar in documentation and comments REVERT: 861da39cae ci: Add NetBSD job REVERT: 458745e394 Fix various typos, spelling mistakes, and grammatical errors in design.md and source code comments. REVERT: 585decc856 Merge bitcoin-core/libmultiprocess#236: ci: Install binary package `capnproto` on OpenBSD instead of building it REVERT: 14e926a3ff refactor: extract MakeArgv helper REVERT: 1ee909393f ci: Install binary package `capnproto` on OpenBSD instead of building it REVERT: 470fc518d4 Merge bitcoin-core/libmultiprocess#230: cmake: add ONLY_CAPNP target_capnp_sources option REVERT: 2d8886f26c Merge bitcoin-core/libmultiprocess#228: Add versions.md and version.h files describing version branches and tags REVERT: c1838be565 Merge bitcoin-core/libmultiprocess#225: Improve and document act support REVERT: a173f1704c Merge bitcoin-core/libmultiprocess#223: ci: Replace nix-shell with equivalent nix develop command REVERT: 625eaca42f Merge bitcoin-core/libmultiprocess#229: Design Documentation Update REVERT: cc234be73a Design doc update REVERT: 81c652687b cmake: add ONLY_CAPNP target_capnp_sources option REVERT: 6e01d2d766 Add versions.md and version.h files describing version branches and tags REVERT: a4f9296964 Merge bitcoin-core/libmultiprocess#224: doc: fix typos REVERT: f4344ae87d Merge bitcoin-core/libmultiprocess#222: test, ci: Fix threadsanitizer errors in mptest REVERT: 4e3f8fa0d2 doc: add instructions for using act REVERT: 81712ff6bb ci: disable KVM and sandbox inside act containers REVERT: 1434642b38 doc: fix typos REVERT: 73d22ba2e9 test: Fix tsan race in thread busy test REVERT: b74e1bba01 ci: Use tsan-instrumented cap'n proto in sanitizers job REVERT: c332774409 test: Fix failing exception check in new thread busy test REVERT: ca3c05d567 test: Use KJ_LOG instead of std::cout for logging REVERT: 7eb1da120a ci: Use tsan-instrumented libcxx in sanitizers job REVERT: 18a2237a8e ci: Replace nix-shell with equivalent nix develop command REVERT: ec86e4336e Merge bitcoin-core/libmultiprocess#220: Add log levels and advertise them to users via logging callback REVERT: 515ce93ad3 Logging: Pass LogData struct to logging callback REVERT: 213574ccc4 Logging: reclassify remaining log messages REVERT: e4de0412b4 Logging: Break out expensive log messages and classify them as Trace REVERT: 408874a78f Logging: Use new logging macros REVERT: 67b092d835 Logging: Disable logging if messsage level is less than the requested level REVERT: d0a1ba7ebf Logging: add log levels to mirror Core's REVERT: 463a8296d1 Logging: Disable moving or copying Logger REVERT: 83a2e10c0b Logging: Add an EventLoop constructor to allow for user-specified log options REVERT: 58cf47a7fc Merge bitcoin-core/libmultiprocess#221: test default PassField impl handles output parameters REVERT: db03a663f5 Merge bitcoin-core/libmultiprocess#214: Fix crash on simultaneous IPC calls using the same thread REVERT: afcc40b0f1 Merge bitcoin-core/libmultiprocess#213: util+doc: Clearer errors when attempting to run examples + polished docs REVERT: 6db6696283 test In|Out parameter REVERT: 29cf2ada75 test default PassField impl handles output parameters REVERT: 1238170f68 test: simultaneous IPC calls using same thread REVERT: eb069ab75d Fix crash on simultaneous IPC calls using the same thread REVERT: ec03a9639a doc: Precision and typos REVERT: 2b43481935 doc: Where possible, remove links to ryanofsky/bitcoin/ REVERT: 286fe469c9 util: Add helpful error message when failing to execute file REVERT: 47d79db8a5 Merge bitcoin-core/libmultiprocess#201: bug: fix mptest hang, ProxyClient deadlock in disconnect handler REVERT: f15ae9c9b9 Merge bitcoin-core/libmultiprocess#211: Add .gitignore REVERT: 4a269b21b8 bug: fix ProxyClient deadlock if disconnected as IPC call is returning REVERT: 85df96482c Use try_emplace in SetThread instead of threads.find REVERT: ca9b380ea9 Use std::optional in ConnThreads to allow shortening locks REVERT: 9b07991135 doc: describe ThreadContext struct and synchronization requirements REVERT: d60db601ed proxy-io.h: add Waiter::m_mutex thread safety annotations REVERT: 4e365b019a ci: Use -Wthread-safety not -Wthread-safety-analysis REVERT: 15d7bafbb0 Add .gitignore REVERT: fe1cd8c761 Merge bitcoin-core/libmultiprocess#208: ci: Test minimum cmake version in olddeps job REVERT: b713a0b7bf Merge bitcoin-core/libmultiprocess#207: ci: output CMake version in CI script REVERT: 0f580397c9 ci: Test minimum cmake version in olddeps job REVERT: d603dcc0ee ci: output CMake version in CI script REVERT: 13424cf2ec Merge bitcoin-core/libmultiprocess#205: cmake: check for Cap'n Proto / Clang / C++20 incompatibility REVERT: 72dce11864 Merge bitcoin-core/libmultiprocess#200: event loop: add LogOptions struct and reduce the log size REVERT: 85003409f9 eventloop: add `LogOptions` struct REVERT: 657d80622f cmake: capnproto pkg missing helpful error REVERT: d314057775 cmake: check for Cap'n Proto / Clang / C++20 incompatibility REVERT: 878e84dc30 Merge bitcoin-core/libmultiprocess#203: cmake: search capnproto in package mode only REVERT: 1a85da5873 Merge bitcoin-core/libmultiprocess#202: doc: correct the build instructions for the example REVERT: df01873e1e Merge bitcoin-core/libmultiprocess#197: ci: Add freebsd and macos build REVERT: 3bee07ab33 cmake: search capnproto in package mode only REVERT: b6d3dc4419 doc: correct the build instructions for example REVERT: fa1ac30000 ci: Add macos and freebsd task REVERT: 1b8d4a6f1e Merge bitcoin-core/libmultiprocess#194: mpgen: Work around c++20 / capnproto 0.8 incompatibility REVERT: f1fad396bf Merge bitcoin-core/libmultiprocess#195: ci: Add openbsd REVERT: eed42f210d ci: Bump all tasks to actions/checkout@v5 REVERT: 486a510bbe ci: Remove ancient and problematic -lstdc++fs in mpexample REVERT: dd40897efe Add missing thread include REVERT: 98414e7d28 ci: Add openbsd REVERT: dc3ba22046 cmake, doc: Add check for CVE-2022-46149 REVERT: cb170d4913 Merge bitcoin-core/libmultiprocess#193: build: require CapnProto 0.7.0 or better REVERT: 8ceeaa6ae4 ci: Add olddeps job to test old dependencies versions REVERT: c4cb758ecc mpgen: Work around c++20 / capnproto 0.8 incompatibility REVERT: 30930dff7b build: require CapnProto 0.7.0 or better REVERT: b4120d34ba Merge bitcoin-core/libmultiprocess#192: doc: fix typos REVERT: 6ecbdcd35a doc: fix typos REVERT: a11e6905c2 Merge bitcoin-core/libmultiprocess#186: Fix mptest failures in bitcoin CI REVERT: 6f340a583f doc: fix DrahtBot LLM Linter error REVERT: c6f7fdf173 type-context: revert client disconnect workaround REVERT: e09143d2ea proxy-types: fix UndefinedBehaviorSanitizer: null-pointer-use REVERT: 84b292fcc4 mptest: fix MemorySanitizer: use-of-uninitialized-value REVERT: fe4a188803 proxy-io: fix race conditions in disconnect callback code REVERT: d8011c8360 proxy-io: fix race conditions in ProxyClientBase cleanup handler REVERT: 97e82ce19c doc: Add note about Waiter::m_mutex and interaction with the EventLoop::m_mutex REVERT: 81d58f5580 refactor: Rename ProxyClient cleanup_it variable REVERT: 07230f259f refactor: rename ProxyClient::m_cleanup_it REVERT: c0efaa5e8c Merge chaincodelabs/libmultiprocess#187: ci: have bash scripts explicitly opt out of locale dependence. REVERT: 0d986ff144 mptest: fix race condition in TestSetup constructor REVERT: d2f6aa2e84 ci: add thread sanitizer job REVERT: 3a6db38e56 ci: rename configs to .bash REVERT: 401e0ce1d9 ci: add copyright to bash scripts REVERT: e956467ae4 ci: export LC_ALL REVERT: 8954cc0377 Merge chaincodelabs/libmultiprocess#184: Add CI jobs and fix clang-tidy and iwyu errors REVERT: 757e13a755 ci: add gnu32 cross-compiled 32-bit build REVERT: 15bf349000 doc: fix typo found by DrahtBot REVERT: 1a598d5905 clang-tidy: drop 'bitcoin-*' check REVERT: cbb1e43fdc ci: test libc++ instead of libstdc++ in one job REVERT: 76313450c2 type-context: disable clang-tidy UndefinedBinaryOperatorResult error REVERT: 4896e7fe51 proxy-types: fix clang-tidy EnumCastOutOfRange error REVERT: 060a739269 proxy-types: fix clang-tidy StackAddressEscape error REVERT: 977d721020 ci: add github actions jobs testing gcc, clang-20, clang-tidy, and iwyu REVERT: 0d5f1faae5 iwyu: fix add/remove include errors REVERT: 753d2b10cc util: fix clang-tidy modernize-use-equals-default error REVERT: ae4f1dc2bb type-number: fix clang-tidy modernize-use-nullptr error REVERT: 07a741bf69 proxy-types: fix clang-tidy bugprone-use-after-move error REVERT: 3673114bc9 proxy-types: fix clang-tidy bugprone-use-after-move error REVERT: 422923f384 proxy-types: fix clang-tidy bugprone-use-after-move error REVERT: c6784c6ade mpgen: disable clang-tidy misc-no-recursion error REVERT: c5498aa11b tidy: copy clang-tidy file from bitcoin core REVERT: 258a617c1e Merge chaincodelabs/libmultiprocess#160: refactor: EventLoop locking cleanups + client disconnect exception REVERT: 84cf56a0b5 test: Test disconnects during IPC calls REVERT: 949573da84 Prevent IPC server crash if disconnected during IPC call REVERT: 0198397580 Merge chaincodelabs/libmultiprocess#179: scripted-diff: Remove copyright year (ranges) REVERT: ea38392960 Prevent EventLoop async cleanup thread early exit during shutdown REVERT: 616d9a75d2 doc: Document ProxyClientBase destroy_connection option REVERT: 56fff76f94 Improve IPC client disconnected exceptions REVERT: 9b8ed3dc5f refactor: Add clang thread safety annotations to EventLoop REVERT: 52256e730f refactor: Remove DestructorCatcher and AsyncCallable REVERT: f24894794a refactor: Drop addClient/removeClient methods REVERT: 2b830e558e refactor: Use EventLoopRef instead of addClient/removeClient REVERT: 315ff537fb refactor: Add ProxyContext EventLoop* member REVERT: 9aaeec3678 proxy-io.h: Add EventLoopRef RAII class handle addClient/removeClient refcounting REVERT: f58c8d8ba2 proxy-io.h: Add more detailed EventLoop comment REVERT: 5108445e5d test: Add test coverage for client & server disconnections REVERT: 59030c68cb Merge chaincodelabs/libmultiprocess#181: type-function.h: Fix CustomBuildField overload REVERT: 688140b1df test: Add coverage for type-function.h REVERT: 8b96229da5 type-function.h: Fix CustomBuildField overload REVERT: fa2ff9a668 scripted-diff: Remove copyright year (ranges) REVERT: 27c7e8e5a5 Merge chaincodelabs/libmultiprocess#172: refactor: fix warnings from clang-tidy-20 and bitcoin-tidy REVERT: 2fe87d016b Merge chaincodelabs/libmultiprocess#173: doc: Fix error string typo REVERT: 57a65b8546 clang-tidy: Suppress bitcoin-nontrivial-threadlocal error REVERT: 0d8012f656 Merge chaincodelabs/libmultiprocess#165: clang-tidy: fix warnings introduced in version 19 REVERT: 3a96cdc18f clang-tidy: Fix bugprone-move-forwarding-reference error REVERT: c1e8c1a028 clang-tidy: Fix bugprone-move-forwarding-reference errors REVERT: aa19285303 use ranges transform REVERT: a78137ca73 make member function const REVERT: ca3226ec8a replace custom tuple unpacking code with `std::apply` REVERT: 949fe85fc9 replace SFINAE trick with `if constexpr` REVERT: 44ee4b40b8 doc: Fix error string typo REVERT: 35944ffd23 Merge chaincodelabs/libmultiprocess#168: Switch `MP_INCLUDE_DIR` to global property REVERT: a77c8e18eb Switch `MP_INCLUDE_DIR` to global property REVERT: f35df6bdc5 Merge bitcoin-core/libmultiprocess#166: doc: rename from chaincodelabs to bitcoin-core REVERT: 2e119973ce doc: rename from chaincodelabs to bitcoin-core REVERT: 1954f7f656 Merge chaincodelabs/libmultiprocess#164: Bump minimum required cmake to 3.12 REVERT: 729ff16d55 Bump minimum required cmake to 3.12 REVERT: 011fc53aea Merge chaincodelabs/libmultiprocess#161: cmake: Avoid including CTest if not top level project REVERT: 26b9f3dda4 Merge chaincodelabs/libmultiprocess#159: bugfix: Do not lock EventLoop::mutex after EventLoop is done REVERT: a7f0669320 cmake: Avoid including CTest if not top level project REVERT: 48d01bcca7 bugfix: Do not lock EventLoop::mutex after EventLoop is done REVERT: 408990787f Merge chaincodelabs/libmultiprocess#157: refactor: Avoid using std::format REVERT: eca8fd3eee refactor: Avoid using std::format REVERT: 9ba88dc2c7 Merge chaincodelabs/libmultiprocess#156: refactor: Remove locale-dependent function calls REVERT: 91193005a9 Merge chaincodelabs/libmultiprocess#155: scripted-diff: s/Libmultiprocess_EXTERNAL_MPGEN/MPGEN_EXECUTABLE/g REVERT: c8351c5f0b refactor: Remove locale-dependent function calls REVERT: 250c2ea54d scripted-diff: s/Libmultiprocess_EXTERNAL_MPGEN/MPGEN_EXECUTABLE/g REVERT: 9558ceb0d4 Merge chaincodelabs/libmultiprocess#152: refactor: Fix compiler and clang-tidy warnings REVERT: c6a61d8b9e Merge chaincodelabs/libmultiprocess#149: Avoid `-Wundef` compiler warnings REVERT: 0b8b7f92ca refactor: Fix `-Wsign-compare` compiler warning REVERT: a02c0794fd clang-tidy: Suppress `performance-enum-size` check warning REVERT: 593807ab5b clang-tidy: Fix `readability-container-size-empty` check REVERT: 68c1c6c51a clang-tidy: Fix `readability-avoid-return-with-void-value` check REVERT: 4abaa98429 clang-tidy: Fix `readability-avoid-nested-conditional-operator` check REVERT: 01ef094b4c clang-tidy: Fix `performance-unnecessary-value-param` check REVERT: c665a43f9c clang-tidy: Fix `misc-use-internal-linkage` check REVERT: 15c77e9722 clang-tidy: Fix `misc-include-cleaner` check REVERT: 848c902dd0 clang-tidy: Fix `misc-const-correctness` check REVERT: 4a2508c499 clang-tidy: Fix `modernize-type-traits` check REVERT: 8170d3d421 clang-tidy: Suppress `bugprone-empty-catch` check warning REVERT: c068596ac3 clang-tidy: Fix `bugprone-crtp-constructor-accessibility` check REVERT: 00036c0648 clang-tidy: Disable `performance-avoid-endl` check REVERT: 359a6157af clang-tidy: Disable `misc-use-anonymous-namespace` check REVERT: c978878a3c Merge chaincodelabs/libmultiprocess#145: CTest: Module must be included at the top level REVERT: 63ac092ddd CTest: Module must be included at the top level REVERT: d450fbf63e Avoid `-Wundef` compiler warnings REVERT: 477405eda3 Merge chaincodelabs/libmultiprocess#148: util: fix -Wpessimizing-move warning REVERT: 3bce9d03d1 util: fix -Wpessimizing-move warning REVERT: f09c50118f Merge chaincodelabs/libmultiprocess#147: cmake: EXTERNAL_MPGEN cleanups REVERT: 3d83c7aef1 Merge chaincodelabs/libmultiprocess#146: cmake: Suppress compiler warnings from capnproto headers REVERT: 21b92b69c9 cmake: EXTERNAL_MPGEN cleanups REVERT: 2fdd920b1e Merge chaincodelabs/libmultiprocess#143: cleanup: initialize vars in the EventLoop constructor in the correct order REVERT: 0c2ac4d772 Merge chaincodelabs/libmultiprocess#142: build: add option for external mpgen binary REVERT: f52d08c7f0 cleanup: initialize vars in the EventLoop constructor in the correct order REVERT: 75cf04a6ed build: add option for external mpgen binary REVERT: 72326b5d1e cmake: Simplify capnp include handling REVERT: 1e06ff07cd Merge chaincodelabs/libmultiprocess#140: build: don't clobber user/superproject c++ version REVERT: 65c7048251 cmake: Suppress compiler warnings from capnproto headers REVERT: df2153551e build: don't clobber user/superproject c++ version REVERT: 07c917f7ca Merge chaincodelabs/libmultiprocess#137: doc: Fix broken markdown links REVERT: e15816a6c3 doc: Fix broken markdown links REVERT: e89b2c6ac2 Merge chaincodelabs/libmultiprocess#136: cmake: Support being included with add_subdirectory REVERT: 3dea1d555a Merge chaincodelabs/libmultiprocess#135: refactor: proxy-types.h API cleanup REVERT: 6adbb1d6eb cmake: Support being included with add_subdirectory REVERT: 10bb7e4734 Merge chaincodelabs/libmultiprocess#94: c++ 20 cleanups REVERT: 7d59b8d14c move: add mp/type-data.h REVERT: 1103f86cd9 cmake: Define and use MP_INCLUDE_DIR variable REVERT: 798f4b5e35 moveonly: add mp/type-chrono.h REVERT: a595a0b228 moveonly: add mp/type-threadmap.h REVERT: e834ebd219 moveonly: add mp/type-decay.h REVERT: 5ee6cd4118 moveonly: add mp/type-exception.h REVERT: 394651237b moveonly: add mp/type-void.h REVERT: 8969d5a008 moveonly: add mp/type-message.h REVERT: 11b418f438 moveonly: add mp/type-struct.h REVERT: 5df55a3666 moveonly: add mp/type-function.h REVERT: 0d2f939214 moveonly: add mp/type-interface.h REVERT: 5417716ad8 moveonly: add mp/type-char.h REVERT: 83c444dc9d moveonly: add mp/type-string.h REVERT: df1375bd68 moveonly: add mp/type-number.h REVERT: 6d831ebb1d moveonly: add mp/type-tuple.h REVERT: c999100289 moveonly: add mp/type-pair.h REVERT: 079277f2ba moveonly: add mp/type-map.h REVERT: 6a68472bb3 moveonly: add mp/type-set.h REVERT: c6246c9198 moveonly: add mp/type-vector.h REVERT: 619d2c7405 moveonly: add mp/type-pointer.h REVERT: 3cb9d9fd5b moveonly: add mp/type-optional.h REVERT: b32e2b096c moveonly: add mp/type-context.h REVERT: f18a1ccd20 refactor: Rename ReadDestValue to ReadDestUpdate REVERT: 3dc1d42a7a Merge chaincodelabs/libmultiprocess#133: Fix debian "libatomic not found" error in downstream builds REVERT: eb27f5918f Merge chaincodelabs/libmultiprocess#131: doc: fix startAsyncThread comment REVERT: caf01fa469 Merge chaincodelabs/libmultiprocess#130: refactor: Add CleanupRun function to dedup clean list code REVERT: 72f6669b50 Merge chaincodelabs/libmultiprocess#129: Fix "disconnected: write(m_post_fd, &buffer, 1): Broken pipe" EventLoop shutdown races. REVERT: 67afc23069 Fix debian "libatomic not found" error in downstream builds REVERT: 0e4f88d3f9 Fix "disconnected: write(m_post_fd, &buffer, 1): Broken pipe" EventLoop shutdown races. REVERT: 063ff18210 fix startAsyncThread comment REVERT: 3b2617b3e5 Merge chaincodelabs/libmultiprocess#127: ProxyClientBase: avoid static_cast to partially destructed object REVERT: 63a39d4c9b ProxyClientBase: avoid static_cast to partially destructed object REVERT: 700085f9a8 refactor: Add CleanupRun function to dedup clean list code REVERT: 621a04a70f Merge chaincodelabs/libmultiprocess#120: proxy-types.h: add static_assert to detect int/enum size mismatch REVERT: 110349f626 test: Add coverage for enum/int conversions REVERT: 350067f431 Merge chaincodelabs/libmultiprocess#121: ProxyClientBase: avoid static_cast to partially constructed object REVERT: 5b81192847 ProxyClientBase: avoid static_cast to partially constructed object REVERT: bbc80abc20 proxy-types.h: add static_assert to detect when an int fields is too small to hold an enum value REVERT: abe254b973 Merge chaincodelabs/libmultiprocess#119: cmake: avoid libatomic not found error on debian REVERT: 245581d3e3 Merge chaincodelabs/libmultiprocess#118: shutdown bugfix: Prevent segfault in server if connection is broken during long function call REVERT: 196e6fcdbc bugfix: prevent null pointer dereference in server if client disconnects during method call REVERT: 296c380a4b cmake: avoid libatomic not found error on debian REVERT: 9d11042772 bugfix: prevent double delete segfault in server if client disconnects during method call REVERT: 181837b391 Merge chaincodelabs/libmultiprocess#116: shutdown bugfix: destroy RPC system before running cleanup callbacks REVERT: 2350843a31 shutdown bugfix: destroy RPC system before running cleanup callbacks REVERT: a4ac4241e0 Merge chaincodelabs/libmultiprocess#113: Add missing include to util.h REVERT: 6929c40913 Add missing include to util.h REVERT: f5a4957d26 Merge chaincodelabs/libmultiprocess#111: doc: Add internal design section REVERT: 1fa2ca7cd8 doc: Add internal design section REVERT: 015e95f7eb Merge chaincodelabs/libmultiprocess#110: cmake: add target_capnp_sources headers target REVERT: 66e12f1fae cmake: add target_capnp_sources headers target REVERT: f67cae8909 Merge chaincodelabs/libmultiprocess#109: example: Add missing thread.join() call so example can exit cleanly REVERT: 70b2d8794f example: Add missing thread.join() call so example can exit cleanly REVERT: 8bb6eab71b Merge chaincodelabs/libmultiprocess#108: doc: Add comments for socket descriptor handling when forking REVERT: 17a2399fe1 Merge chaincodelabs/libmultiprocess#107: example: Remove manual client adding REVERT: b56bf218c7 doc: Add comments for socket descriptor handling when forking REVERT: 34998101a3 example: Remove manual client adding REVERT: c1b4ab4eb8 Merge chaincodelabs/libmultiprocess#106: Bugfix: Clean up ThreadContext pointers when Connection is destroyed REVERT: 8ba0d03b44 Bugfix: Clean up ThreadContext pointers when Connection is destroyed REVERT: a9e16da55e Merge chaincodelabs/libmultiprocess#105: types: Add Custom{Build,Read,Pass}Message hooks REVERT: ca2cfedd2b types: Add Custom{Build,Read,Pass}Message hooks REVERT: 6aca5f389b Merge chaincodelabs/libmultiprocess#104: Fix $Proxy.wrap mapping for empty structs with no fields REVERT: e4540729c9 Merge chaincodelabs/libmultiprocess#103: cmake: Fix package configuration file REVERT: 90f8b37a3b Fix $Proxy.wrap mapping for empty structs with no fields REVERT: c373a94d5b cmake: Fix package configuration file REVERT: 8b8a4766ce Merge chaincodelabs/libmultiprocess#102: doc: Document shutdown sequences better REVERT: 2c66dd5995 doc: Document shutdown sequences better REVERT: 6cbe56ef3b refactor, moveonly: order lambda move captures first REVERT: 8da0524628 Merge chaincodelabs/libmultiprocess#101: connection: run async cleanups in LIFO not FIFO order REVERT: 1f76880dbf util: Get rid of unused Discard struct REVERT: c92e90ce08 proxy-types Drop JoinPromises function REVERT: 53ee9faf84 Merge chaincodelabs/libmultiprocess#100: doc: Add various code comments and documentation REVERT: e45c482c40 Merge chaincodelabs/libmultiprocess#99: proxy-types: Fix missing space in server destroy log print REVERT: 6825523c6e connection: run async cleanups in LIFO not FIFO order REVERT: 537c645652 doc: Improve ProxyServerCustom class documentation REVERT: 0c70a0f89e proxy-types: Fix missing space in server destroy log print REVERT: e29f74e8ff Merge chaincodelabs/libmultiprocess#98: cmake: Combine installed packages REVERT: d4d9f93175 doc: Document FunctionTraits/ProxyMethodTraits classes REVERT: 78c7dd0be5 doc: Document ProxyClient construct/destroy methods REVERT: e99c0b7564 doc: Document clientInvoke/serverInvoke functions REVERT: 2098ae1b18 doc: Add comment on serverInvoke ReplaceVoid usage REVERT: a1dfb0bab4 doc: Add comments to mp.Context PassField function on updating g_thread_context REVERT: e49a925a40 doc: Add comments to mp.Context PassField function on mp.Context.thread lookup REVERT: dc9b4e6a99 cmake: Combine installed packages REVERT: 2ed1e9aedb cmake: CMakeLists.txt cleanup REVERT: 3f8483b61a Merge chaincodelabs/libmultiprocess#97: cmake: rename new packages and module introduced in #95 and #96 REVERT: c6a1d7fb6b cmake: rename new packages and module introduced in #95 and #96 REVERT: 003eb04d6d Merge chaincodelabs/libmultiprocess#96: cmake: Introduce packages REVERT: 19dea85cf2 Merge chaincodelabs/libmultiprocess#95: cmake: Introduce `LibmultiprocessMacros` module REVERT: 4e70ad4719 cmake, refactor: Rename target export files REVERT: 694b6b13e9 cmake: Configure `LibmultiprocessGen` package REVERT: 3b20e35ab8 cmake: Configure `Libmultiprocess` package REVERT: 66643d8eaa cmake, refactor: Use `target_capnp_sources` for examples REVERT: bd2dfe27b0 cmake, refactor: Use `target_capnp_sources` for `mptest` target REVERT: d9ec22f81b cmake: Add `LibmultiprocessMacros` module REVERT: 8da797c5f1 Merge chaincodelabs/libmultiprocess#93: Fix support for vector serialization with libc++ REVERT: 10fc3eda9c Fix support for vector serialization with libc++ REVERT: 7d1fee06d6 Merge chaincodelabs/libmultiprocess#91: util: Drop Bind, BindTuple, ComposeFn, GetFn, and ThrowFn helpers REVERT: 65260d1851 util: Drop Bind, BindTuple, ComposeFn, GetFn, and ThrowFn helpers REVERT: 2cbbd09d8b Merge chaincodelabs/libmultiprocess#90: pkgconfig: Use @CMAKE_INSTALL_LIBDIR@ variable REVERT: 02711958d9 Merge chaincodelabs/libmultiprocess#89: pkgconfig: Drop -std=c++17 compile flag REVERT: 0f9605b026 pkgconfig: Use @CMAKE_INSTALL_LIBDIR@ variable REVERT: 590d1e737c pkgconfig: Drop -std=c++17 compile flag REVERT: 414542f81e Merge chaincodelabs/libmultiprocess#88: Fix current deprecation warnings as of capnproto-1.0.1 REVERT: 962e681356 mpgen: Avoid deprecated SchemaParser::parseDiskFile call REVERT: e8e89dfd37 Remove deprecated kj::mvCapture calls to avoid warnings REVERT: 61d5a0e661 Merge chaincodelabs/libmultiprocess#86: Add support for vector serialization REVERT: 1c6fb04ddd Add support for vector serialization REVERT: aea56f0e2a Merge chaincodelabs/libmultiprocess#85: Remove naming requirement for std::pair/std::tuple REVERT: 3df497456b Remove naming requirement for std::pair/std::tuple REVERT: fc28a48f01 Merge #83: Introduce `clang-tidy` and optimize code REVERT: 594466ae97 clang-tidy: Fix `readability-make-member-function-const` check REVERT: 037fec47c8 clang-tidy: Fix `performance-unnecessary-value-param` check REVERT: 463bead1f3 clang-tidy: Fix `performance-inefficient-vector-operation` check REVERT: a435b24e64 clang-tidy: Fix `performance-faster-string-find` check REVERT: ae416f903f clang-tidy: Fix `modernize-use-nullptr` check REVERT: 9f86c9a0a8 clang-tidy: Fix `modernize-use-equals-default` check REVERT: 18b52c1663 clang-tidy: Fix `modernize-use-emplace` check REVERT: 1a33c35a3b clang-tidy: Fix `modernize-return-braced-init-list` check REVERT: 8dd83bbd91 clang-tidy: Suppress `bugprone-suspicious-semicolon` check warning REVERT: 5e787bfbd0 Add option to run `clang-tidy` with compiler REVERT: 74e25d2cd4 Merge #84: Avoid passing some function arguments by value REVERT: 8ef94d2e86 Avoid passing some function arguments by value REVERT: 917877afa8 Merge #79: Install Exports for custom `install-{lib,bin}` targets REVERT: 2dda7536b5 Install Exports for custom `install-{lib,bin}` targets REVERT: 54bd57fb3b Use `GNUInstallDirs` module REVERT: 1af83d1523 Merge #81: Add ReadDestTemp function to make it easier to call ReadField with less boilerplate REVERT: e66e6e82f6 Merge #82: build: Fix missing Cap'n Proto include directories REVERT: c75362392f build: Fix missing Cap'n Proto include directories REVERT: 70d108bc60 Add ReadDestTemp function to make it easier to call ReadField with less boilerplate REVERT: 7441069261 Merge #80: doc: Fix mpgen usage string REVERT: fcad5fbe53 doc: Fix mpgen usage string REVERT: ddd2cee627 Merge #78: refactor: Do not shadow `InvokeContext::connection` member REVERT: f999694daa refactor: Do not shadow `InvokeContext::connection` member REVERT: 4992b52754 Merge #74: Add `install-lib` and `install-bin` build targets REVERT: fa130db398 Add `install-bin` target REVERT: c4d26d2ddb Add `install-lib` target REVERT: bc3d166d37 Install `proxy.capnp` with `mpgen` target REVERT: f85fefff28 Merge #73: Drop unneeded include directory REVERT: 80dc922e4c Merge #72: Make `mpgen` target independent from `multiprocess` one REVERT: d321ef89e7 Merge #71: Use defined `CXX_STANDARD` for environment introspection REVERT: 331b5a6e49 Merge #70: Fix check for `pthread_threadid_np` REVERT: d36ebb9ace Drop unneeded include directory REVERT: 665d1fdc67 Make `mpgen` target independent from `multiprocess` one REVERT: 2eff5da83c Use defined `CXX_STANDARD` for environment introspection REVERT: 373d0d7823 Fix check for `pthread_threadid_np` REVERT: c6849de823 Merge #69: Fix CMake minimum required version REVERT: 6902bfd40e Fix CMake minimum required version REVERT: 49dc279926 Merge chaincodelabs/libmultiprocess#66: Fix typos REVERT: 9f4dac644a Fix typos REVERT: 7d10f3b1e3 Merge chaincodelabs/libmultiprocess#65: Fix clang "unknown warning group" errors REVERT: 680776fcc8 Fix clang "unknown warning group" errors REVERT: bc6624a5d3 Merge chaincodelabs/libmultiprocess#64: cleanup: Remove AUTORET macro and clean up PassField overrides REVERT: d2a9db9ebf Merge chaincodelabs/libmultiprocess#63: Fix mptest link error caused by missing kj-async dependency REVERT: cf7ebfe68d Replace ThreadMap Passfield override with generic count(0) override REVERT: 3f388cf064 Inline last AUTO_RETURN uses and remove macro REVERT: 41db49c7bc Consolidate PassField function to remove AUTO_RETURN uses REVERT: 1d005053b0 Replace output.init AUTO_RETURN uses with decltype(auto) REVERT: ea1a77b98b Replace AUTO_RETURN uses with decltype(auto) REVERT: 029d84fe77 Fix mptest link error caused by missing kj-async dependency REVERT: 306c8b100d Merge chaincodelabs/libmultiprocess#62: Fix clang compiler warnings REVERT: 1b638d67de Avoid delete-non-abstract-non-virtual-dtor warnings for mp::ProxyCallbackImpl REVERT: 5738b8ae09 Avoid delete-non-abstract-non-virtual-dtor warnings REVERT: 921e23e8d1 Disable clang suggest-override warnings for proxy clients REVERT: 34ce921d2d Merge chaincodelabs/libmultiprocess#58: Fix std::move compiler warning REVERT: 49004c8726 Merge chaincodelabs/libmultiprocess#57: doc/install.md: add cmake to brew install command REVERT: e386cfad52 Fix std::move compiler warning REVERT: 424d635ab1 doc/install.md: add cmake to brew install command REVERT: 8abd3daf1c Merge #55: Add doc/ folder, split up readme and add more usage documentation REVERT: 1a3dc8d263 Add documentation about interface definitions REVERT: 5539208883 Split up README.md REVERT: 805eb73e57 Merge #49: Add standalone example with 3 processes REVERT: 4b45e14aad Add standalone example with 3 processes REVERT: 17bfda9ece Merge #48: Move test/src/ files one level up REVERT: b648f2a13d Merge #47: gen.cpp: Check local includes before install includes REVERT: 8b5259c5b4 Move test/src/ files one level up REVERT: c2f866fa8d Merge #45: Comments and LogEscape REVERT: 1007bd7c2b gen.cpp: Check local includes before install includes REVERT: 22afe27d1e util: fix LogEscape bug REVERT: 89ababdd3c doc: add note on vats REVERT: 6e36f0f53c doc: fix various typos REVERT: b6e060af7b README: add kj explainer REVERT: d576d975de Merge #43: Drop hardcoded #include lines in generated files REVERT: 35d2091134 Merge #42: Support attaching custom cleanup functions to proxy client and server classes REVERT: 2ccc479f86 Drop hardcoded #include lines in generated files REVERT: ce8e8b654a Add ProxyTypeRegister typeid map REVERT: fbdaaa75aa Add cleanup callbacks to ProxyContext REVERT: 34e9b78ec1 refactor: Move connection field to ProxyContext struct REVERT: 39ad0f5eae Generate ProxyType traits for interface types REVERT: 1b4012cadd Merge #41: Avoid depending on argument default constructors REVERT: 0e97be35f9 Avoid depending on argument default constructors REVERT: 4dcd80741e Merge #40: Disable GCC suggest-override warnings for proxy clients REVERT: 05f9817c36 Disable GCC suggest-override warnings for proxy clients REVERT: 4c59977392 Merge #38: Add "extends" inherited method support REVERT: de748be4cf Add "extends" inherited method support REVERT: 9f5b835564 Merge #37: Add "make check" target to build and run tests REVERT: 037835320b Add "make check" target to build and run tests REVERT: 9d23fdd030 Merge #35: Fix README.md markdown REVERT: 4d946aa6d2 Fix README.md markdown REVERT: 5741d750a0 Merge #34: Add shared_ptr callback support REVERT: 9ce0335b26 Add comment saying how to fix clientInvoke missing Proxy.Context assert REVERT: 31b4f1be84 Add shared_ptr ownership and lifetime support REVERT: 27f8a35ec0 Add saveCallback / callbackSaved test setup REVERT: 5390a1b116 Add support for passing shared_ptrs without extending lifetime REVERT: 39bbf74a08 Add CustomReadField priority param for more flexibility and consistency with CustomBuildField REVERT: da489bef3f Fix bugs in PassField overload for callback objects passed by reference REVERT: ab4568bbbd Add test coverage for thread map and callbacks REVERT: 1d630f536d Merge #33: Fix empty exception values from bad ThrowFn declaration REVERT: c3efcae099 Fix empty exception values from bad ThrowFn declaration REVERT: 78f2f75d47 Merge #31: Unify ReadFieldNew / ReadFieldUpdate REVERT: 112f364f01 Unify ReadFieldNew / ReadFieldUpdate REVERT: c0e3a50455 Merge #25: Obliterate Boost REVERT: 10b5c69dbc Obliterate Boost REVERT: f4112b7966 Switch from C++14 to C++17 REVERT: f2ea4b91b4 Merge #30: proxy-io.h: fix missing assert.h include REVERT: e2ad13aee2 Merge #29: Update make test command in readme REVERT: fad36ab1a1 proxy-io.h: fix missing assert.h include REVERT: 4d7864560e Merge #28: CMake workarounds for ubuntu capnproto 0.6.1 compatibility REVERT: c8923eb01b Update make test command in readme REVERT: 097bce268a Merge #24: Don't print a dash if thread name is not known REVERT: a440eda4c8 Merge #23: Tell std::system_error() which function failed REVERT: b09973bf7a CMake workarounds for ubuntu capnproto 0.6.1 compatibility REVERT: 570db83ef4 Don't print a dash if thread name is not known REVERT: d6dac63584 Tell std::system_error() which function failed REVERT: 49a9637237 Merge #22: Handle fork(2) failures REVERT: 50b6a7f8c2 Merge #21: Refactor ThreadName() to improve its portability REVERT: 16ebae8225 Handle fork(2) failures REVERT: f1857e3e91 Refactor ThreadName() to improve its portability REVERT: fe76b287f7 Merge #19: Fix compilation of foo.h: include REVERT: 829741ce5f Merge #18: A followup to a616312: remove unnecessary call REVERT: c92112a786 Fix compilation of foo.h: include REVERT: 3b5da8fb44 A followup to a616312: remove unnecessary call REVERT: d3388da2c0 Merge #17: Avoid using boost::optional in PassField() REVERT: a616312ed8 Avoid using boost::optional in PassField() REVERT: abb3ae9ce9 Merge #16: Reduce boost usage REVERT: fb73b81b98 Change EventLoop::m_task_set to not use boost REVERT: 138ad6794a Change Field::(param and result) to not use boost REVERT: 5724a2c58a Remove boost usage from GetAnnotation() REVERT: cab9c51669 Remove unnecessary boost include REVERT: e0319f428a Merge #15: Add ListenConnections function REVERT: d519e18859 Add ListenConnections function REVERT: d24cae648a Merge #14: Add simpler ServeStream function REVERT: 710238c551 Add simpler ServeStream function REVERT: 5f425473be Merge #13: Add mpgen.mk makefile rules REVERT: b72ec472bb Add mpgen.mk makefile rules REVERT: 86d5a45b8d Merge #12: Add Eventloop void* context pointer REVERT: 2a2549cea3 Merge #11: Replace ProxyServer connection pointer with reference REVERT: 4907c5dced Add Eventloop void* context pointer REVERT: e7687dbed6 Replace ProxyServer connection pointer with reference REVERT: bd8ee26336 Merge #10: Remove #include to avoid mac os build error REVERT: 4e452e9c1c Remove #include to avoid mac os build error REVERT: 9cd1a5a9c1 Merge #9: Invoke capnp compile from mpgen REVERT: f89e4b32dc Invoke capnp compile from mpgen REVERT: dee0711538 Merge #8: Add Connnect/Serve/Spawn/Wait functions REVERT: 8125688f6c Merge #7: Add ProxyClientBase destroy_connection option REVERT: f324c66615 Add Connnect/Serve/Spawn/Wait functions REVERT: da73a6765f Merge #6: Explicitly request C++14 compiler REVERT: c685fa9bed Add ProxyClientBase destroy_connection option REVERT: 409fe97492 Explicitly request C++14 compiler REVERT: 45785e7f19 Merge #3: Limit LogEscape string size REVERT: 99bc4c523d Merge #2: Set mpgen rpath REVERT: 724d2f7fe3 Limit LogEscape string size REVERT: 4dcf39ffda Set mpgen rpath REVERT: cf5afd6dd9 Merge #1: Fix libmultiprocess.pc install path REVERT: 1bc076fbb9 Fix libmultiprocess.pc install path REVERT: 06e1045bab libmultiprocess initial commit git-subtree-dir: src/ipc/libmultiprocess git-subtree-split: 27ada4080964d26fed43d1c7329ba54b4c86199f --- .clang-tidy | 40 ---- .github/workflows/bitcoin-core-ci.yml | 300 -------------------------- .github/workflows/ci.yml | 183 ---------------- .gitignore | 5 - CMakeLists.txt | 30 ++- COPYING | 22 -- README.md | 8 - ci/README.md | 52 ----- ci/configs/default.bash | 5 - ci/configs/freebsd.bash | 5 - ci/configs/gnu32.bash | 11 - ci/configs/llvm.bash | 11 - ci/configs/macos.bash | 5 - ci/configs/netbsd.bash | 11 - ci/configs/olddeps.bash | 5 - ci/configs/openbsd.bash | 5 - ci/configs/sanitize.bash | 8 - ci/patches/spaceship.patch | 29 --- ci/scripts/bitcoin_core_ci.sh | 173 --------------- ci/scripts/ci.sh | 37 ---- ci/scripts/ci_helpers.sh | 94 -------- ci/scripts/config.sh | 26 --- ci/scripts/run.sh | 24 --- doc/design.md | 227 ------------------- doc/install.md | 52 ----- doc/usage.md | 27 --- doc/versions.md | 83 ------- example/CMakeLists.txt | 28 --- example/calculator.capnp | 16 -- example/calculator.cpp | 64 ------ example/calculator.h | 17 -- example/example.cpp | 77 ------- example/init.capnp | 21 -- example/init.h | 20 -- example/printer.capnp | 16 -- example/printer.cpp | 57 ----- example/printer.h | 17 -- example/types.h | 23 -- shell.nix | 84 -------- test/CMakeLists.txt | 2 +- 40 files changed, 22 insertions(+), 1898 deletions(-) delete mode 100644 .clang-tidy delete mode 100644 .github/workflows/bitcoin-core-ci.yml delete mode 100644 .github/workflows/ci.yml delete mode 100644 .gitignore delete mode 100644 COPYING delete mode 100644 README.md delete mode 100644 ci/README.md delete mode 100644 ci/configs/default.bash delete mode 100644 ci/configs/freebsd.bash delete mode 100644 ci/configs/gnu32.bash delete mode 100644 ci/configs/llvm.bash delete mode 100644 ci/configs/macos.bash delete mode 100644 ci/configs/netbsd.bash delete mode 100644 ci/configs/olddeps.bash delete mode 100644 ci/configs/openbsd.bash delete mode 100644 ci/configs/sanitize.bash delete mode 100644 ci/patches/spaceship.patch delete mode 100755 ci/scripts/bitcoin_core_ci.sh delete mode 100755 ci/scripts/ci.sh delete mode 100755 ci/scripts/ci_helpers.sh delete mode 100755 ci/scripts/config.sh delete mode 100755 ci/scripts/run.sh delete mode 100644 doc/design.md delete mode 100644 doc/install.md delete mode 100644 doc/usage.md delete mode 100644 doc/versions.md delete mode 100644 example/CMakeLists.txt delete mode 100644 example/calculator.capnp delete mode 100644 example/calculator.cpp delete mode 100644 example/calculator.h delete mode 100644 example/example.cpp delete mode 100644 example/init.capnp delete mode 100644 example/init.h delete mode 100644 example/printer.capnp delete mode 100644 example/printer.cpp delete mode 100644 example/printer.h delete mode 100644 example/types.h delete mode 100644 shell.nix diff --git a/.clang-tidy b/.clang-tidy deleted file mode 100644 index 9a2afcc5248c..000000000000 --- a/.clang-tidy +++ /dev/null @@ -1,40 +0,0 @@ -Checks: ' --*, -bugprone-argument-comment, -bugprone-move-forwarding-reference, -bugprone-string-constructor, -bugprone-use-after-move, -bugprone-lambda-function-name, -bugprone-unhandled-self-assignment, -misc-unused-using-decls, -misc-no-recursion, -modernize-deprecated-headers, -modernize-use-default-member-init, -modernize-use-emplace, -modernize-use-equals-default, -modernize-use-noexcept, -modernize-use-nullptr, -modernize-use-starts-ends-with, -performance-*, --performance-avoid-endl, --performance-enum-size, --performance-inefficient-string-concatenation, --performance-no-int-to-ptr, --performance-noexcept-move-constructor, --performance-unnecessary-value-param, -readability-const-return-type, -readability-redundant-declaration, -readability-redundant-string-init, -clang-analyzer-core.*, --clang-analyzer-core.UndefinedBinaryOperatorResult, -clang-analyzer-optin.core.*, -' -HeaderFilterRegex: '.' -WarningsAsErrors: '*' -CheckOptions: - - key: modernize-deprecated-headers.CheckHeaderFile - value: false - - key: performance-move-const-arg.CheckTriviallyCopyableMove - value: false - - key: bugprone-unhandled-self-assignment.WarnOnlyIfThisHasSuspiciousField - value: false diff --git a/.github/workflows/bitcoin-core-ci.yml b/.github/workflows/bitcoin-core-ci.yml deleted file mode 100644 index e6ac83f0bd45..000000000000 --- a/.github/workflows/bitcoin-core-ci.yml +++ /dev/null @@ -1,300 +0,0 @@ -# Copyright (c) The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or https://opensource.org/license/mit. - -# Test libmultiprocess inside Bitcoin Core by replacing the subtree copy -# with the version from this PR, then building and running IPC-related -# unit & functional tests. - -name: Bitcoin Core CI - -on: - push: - pull_request: - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -env: - BITCOIN_REPO: bitcoin/bitcoin - LLVM_VERSION: 22 - LIBCXX_DIR: /tmp/libcxx-build/ - -jobs: - bitcoin-core: - name: ${{ matrix.name }} - runs-on: ${{ matrix.runner }} - timeout-minutes: 120 - - strategy: - fail-fast: false - matrix: - include: - - name: 'ASan + UBSan' - unit_test_runs: 15 - functional_test_runs: 20 - nproc_multiplier: 2 - functional_timeout_factor: 40 - runner: ubuntu-24.04 - apt-llvm: true - packages: >- - ccache - clang-22 - llvm-22 - libclang-rt-22-dev - libevent-dev - libboost-dev - libsqlite3-dev - libcapnp-dev - capnproto - ninja-build - pkgconf - python3-pip - pip-packages: --break-system-packages pycapnp - cmake-args: |- - -DSANITIZERS=address,float-divide-by-zero,integer,undefined - -DCMAKE_C_COMPILER=clang - -DCMAKE_CXX_COMPILER=clang++ - -DCMAKE_C_FLAGS=-ftrivial-auto-var-init=pattern - -DCMAKE_CXX_FLAGS=-ftrivial-auto-var-init=pattern - - - name: 'macOS' - unit_test_runs: 50 - functional_test_runs: 20 - nproc_multiplier: 2 - functional_timeout_factor: 40 - runner: macos-15 - brew-packages: ccache capnp boost libevent sqlite pkgconf ninja - pip-packages: --break-system-packages pycapnp - cmake-args: |- - -DREDUCE_EXPORTS=ON - - env: - CCACHE_MAXSIZE: 400M - CCACHE_DIR: ${{ github.workspace }}/.ccache - - steps: - - name: Checkout Bitcoin Core - uses: actions/checkout@v4 - with: - repository: ${{ env.BITCOIN_REPO }} - fetch-depth: 1 - - - name: Checkout libmultiprocess - uses: actions/checkout@v4 - with: - path: _libmultiprocess - - - name: Replace libmultiprocess subtree - run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh replace_subtree - - - name: Add LLVM apt repository - if: matrix.apt-llvm - run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh add_llvm_apt_repository - - - name: Install APT packages - if: matrix.packages - run: _libmultiprocess/ci/scripts/ci_helpers.sh install_apt_packages ${{ matrix.packages }} - - - name: Configure LLVM alternatives - if: matrix.packages - run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh install_llvm_alternatives - - - name: Install Homebrew packages - if: matrix.brew-packages - run: _libmultiprocess/ci/scripts/ci_helpers.sh install_homebrew_packages ${{ matrix.brew-packages }} - - - name: Install pip packages - if: matrix.pip-packages - run: _libmultiprocess/ci/scripts/ci_helpers.sh install_pip_packages ${{ matrix.pip-packages }} - - - name: Determine parallelism - run: _libmultiprocess/ci/scripts/ci_helpers.sh determine_parallelism "${{ matrix.nproc_multiplier }}" - - - name: Restore ccache - id: ccache-restore - uses: actions/cache/restore@v4 - with: - path: ${{ env.CCACHE_DIR }} - key: ccache-${{ matrix.name }}-${{ github.ref }}-${{ github.sha }} - restore-keys: | - ccache-${{ matrix.name }}-${{ github.ref }}- - ccache-${{ matrix.name }}- - - - name: Reset ccache stats - if: matrix.packages || matrix.brew-packages - run: _libmultiprocess/ci/scripts/ci_helpers.sh reset_ccache_stats - - - name: CMake configure - env: - BITCOIN_CORE_CMAKE_ARGS: ${{ matrix.cmake-args }} - run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh configure_bitcoin_core - - - name: Build - run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh build_bitcoin_core - - - name: Show ccache stats - if: matrix.packages || matrix.brew-packages - run: _libmultiprocess/ci/scripts/ci_helpers.sh show_ccache_stats - - - name: Run IPC unit tests - env: - ASAN_OPTIONS: detect_leaks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1 - LSAN_OPTIONS: suppressions=${{ github.workspace }}/test/sanitizer_suppressions/lsan - UBSAN_OPTIONS: suppressions=${{ github.workspace }}/test/sanitizer_suppressions/ubsan:print_stacktrace=1:halt_on_error=1:report_error_type=1 - run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh run_ipc_unit_tests "${{ matrix.unit_test_runs }}" - - - name: Run IPC functional tests - env: - ASAN_OPTIONS: detect_leaks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1 - LSAN_OPTIONS: suppressions=${{ github.workspace }}/test/sanitizer_suppressions/lsan - UBSAN_OPTIONS: suppressions=${{ github.workspace }}/test/sanitizer_suppressions/ubsan:print_stacktrace=1:halt_on_error=1:report_error_type=1 - CI_FAILFAST_TEST_LEAVE_DANGLING: 1 - run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh run_ipc_functional_tests "${{ matrix.functional_test_runs }}" "${{ matrix.functional_timeout_factor }}" - - - name: Save ccache - uses: actions/cache/save@v4 - if: github.ref == 'refs/heads/master' || steps.ccache-restore.outputs.cache-hit != 'true' - with: - path: ${{ env.CCACHE_DIR }} - key: ccache-${{ matrix.name }}-${{ github.ref }}-${{ github.sha }} - - bitcoin-core-tsan: - name: ${{ matrix.name }} - runs-on: ubuntu-24.04 - timeout-minutes: 180 - - strategy: - matrix: - include: - - name: TSan - unit_test_runs: 8 - functional_test_runs: 25 - nproc_multiplier: 2 - functional_timeout_factor: 40 - - env: - CCACHE_MAXSIZE: 400M - CCACHE_DIR: ${{ github.workspace }}/.ccache - LIBCXX_FLAGS: >- - -fsanitize=thread - -nostdinc++ - -nostdlib++ - -isystem /tmp/libcxx-build/include/c++/v1 - -L/tmp/libcxx-build/lib - -Wl,-rpath,/tmp/libcxx-build/lib - -lc++ - -lc++abi - -lpthread - -Wno-unused-command-line-argument - TSAN_OPTIONS: suppressions=${{ github.workspace }}/test/sanitizer_suppressions/tsan:halt_on_error=1:second_deadlock_stack=1 - - steps: - - name: Checkout Bitcoin Core - uses: actions/checkout@v4 - with: - repository: ${{ env.BITCOIN_REPO }} - fetch-depth: 1 - - - name: Checkout libmultiprocess - uses: actions/checkout@v4 - with: - path: _libmultiprocess - - - name: Add LLVM apt repository - run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh add_llvm_apt_repository - - - name: Install packages - run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh install_tsan_packages - - - name: Determine parallelism - run: _libmultiprocess/ci/scripts/ci_helpers.sh determine_parallelism "${{ matrix.nproc_multiplier }}" - - - name: Restore instrumented libc++ cache - id: libcxx-cache - uses: actions/cache@v4 - with: - path: ${{ env.LIBCXX_DIR }} - key: libcxx-Thread-llvmorg-${{ env.LLVM_VERSION }}.1.0 - - - name: Build instrumented libc++ - if: steps.libcxx-cache.outputs.cache-hit != 'true' - run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh build_instrumented_libcxx - - - name: Determine host - id: host - run: _libmultiprocess/ci/scripts/ci_helpers.sh determine_host - - - name: Restore depends cache - id: depends-cache - uses: actions/cache/restore@v4 - with: - path: | - depends/built - depends/${{ steps.host.outputs.host }} - key: depends-tsan-${{ hashFiles('depends/packages/*.mk') }}-${{ env.LLVM_VERSION }} - - - name: Build depends (stage 1, without IPC) - if: steps.depends-cache.outputs.cache-hit != 'true' - run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh build_depends_without_ipc - - - name: Save depends cache - uses: actions/cache/save@v4 - if: steps.depends-cache.outputs.cache-hit != 'true' - with: - path: | - depends/built - depends/${{ steps.host.outputs.host }} - key: depends-tsan-${{ hashFiles('depends/packages/*.mk') }}-${{ env.LLVM_VERSION }} - - - name: Replace libmultiprocess subtree - run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh replace_subtree - - - name: Build depends (stage 2, IPC packages including libmultiprocess) - run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh build_depends_with_ipc - - - name: Restore ccache - id: ccache-restore - uses: actions/cache/restore@v4 - with: - path: ${{ env.CCACHE_DIR }} - key: ccache-TSan-${{ github.ref }}-${{ github.sha }} - restore-keys: | - ccache-TSan-${{ github.ref }}- - ccache-TSan- - - - name: Reset ccache stats - run: _libmultiprocess/ci/scripts/ci_helpers.sh reset_ccache_stats - - - name: CMake configure - env: - BITCOIN_CORE_CMAKE_ARGS: |- - -DSANITIZERS=thread - -DAPPEND_CPPFLAGS=-DARENA_DEBUG -DDEBUG_LOCKCONTENTION -D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES - -DCMAKE_TOOLCHAIN_FILE=depends/${{ steps.host.outputs.host }}/toolchain.cmake - run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh configure_bitcoin_core - - - name: Build - run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh build_bitcoin_core - - - name: Show ccache stats - run: _libmultiprocess/ci/scripts/ci_helpers.sh show_ccache_stats - - - name: Run IPC unit tests - env: - LD_LIBRARY_PATH: depends/${{ steps.host.outputs.host }}/lib - run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh run_ipc_unit_tests "${{ matrix.unit_test_runs }}" - - - name: Run IPC functional tests - env: - LD_LIBRARY_PATH: depends/${{ steps.host.outputs.host }}/lib - CI_FAILFAST_TEST_LEAVE_DANGLING: 1 - run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh run_ipc_functional_tests "${{ matrix.functional_test_runs }}" "${{ matrix.functional_timeout_factor }}" - - - name: Save ccache - uses: actions/cache/save@v4 - if: github.ref == 'refs/heads/master' || steps.ccache-restore.outputs.cache-hit != 'true' - with: - path: ${{ env.CCACHE_DIR }} - key: ccache-TSan-${{ github.ref }}-${{ github.sha }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index ffaca1cac93c..000000000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,183 +0,0 @@ -name: CI - -on: - push: - pull_request: - -jobs: - build-netbsd: - runs-on: ubuntu-latest - name: build • netbsd ${{ matrix.release }} - defaults: - run: - shell: netbsd {0} - strategy: - fail-fast: false - matrix: - # Test all supported releases. - # See https://www.netbsd.org/releases/. - include: - - release: 9.4 - capnproto-cppflags: 'CPPFLAGS="-DKJ_NO_EXCEPTIONS=0 -DKJ_USE_KQUEUE=0"' - - release: 10.1 - capnproto-cppflags: 'CPPFLAGS="-DKJ_NO_EXCEPTIONS=0"' - steps: - - uses: actions/checkout@v6 - - - name: Start NetBSD VM - uses: vmactions/netbsd-vm@v1 - with: - release: ${{ matrix.release }} - # The installed compiler version must match the CXX variable - # defined in `ci/configs/netbsd.bash`. - prepare: | - pkg_add cmake ninja-build gcc14 - # capnproto prerequisites. - # See the following "Install capnproto" step. - run: | - set -e - pkg_add digest libtool-base mktools pkgconf cwrappers - pkg_admin -K /usr/pkg/pkgdb fetch-pkg-vulnerabilities - cd /usr - cvs -danoncvs@anoncvs.NetBSD.org:/cvsroot checkout -P \ - pkgsrc/devel/capnproto \ - pkgsrc/devel/libtool-base \ - pkgsrc/devel/pkgconf \ - pkgsrc/devel/zlib \ - `# gcc15 is referenced here because the pkgsrc framework requires lang/gcc15/version.mk to exist` \ - `# during the "make install" step below, even though we compile our project with gcc14.` \ - pkgsrc/lang/gcc15 \ - pkgsrc/mk \ - pkgsrc/pkgtools \ - pkgsrc/security/openssl \ - pkgsrc/sysutils/install-sh/files - sync: 'rsync' - copyback: false - - - name: Install capnproto - run: | - cd /usr/pkgsrc/devel/capnproto/ - unset PKG_PATH - make ${{ matrix.capnproto-cppflags }} install - - - name: Run CI script - run: | - cd ${{ github.workspace }} - CI_CONFIG="ci/configs/netbsd.bash" bash ci/scripts/ci.sh - - build-openbsd: - runs-on: ubuntu-latest - name: build • openbsd - defaults: - run: - shell: openbsd {0} - steps: - - uses: actions/checkout@v5 - - - name: Start OpenBSD VM - uses: vmactions/openbsd-vm@v1 - with: - prepare: | - pkg_add -v cmake ninja bash capnproto - sync: 'rsync' - copyback: false - - - name: Run CI script - run: | - cd ${{ github.workspace }} - CI_CONFIG="ci/configs/openbsd.bash" bash ci/scripts/ci.sh - - build-freebsd: - runs-on: ubuntu-latest - name: build • freebsd - defaults: - run: - shell: freebsd {0} - steps: - - uses: actions/checkout@v5 - - - name: Start FreeBSD VM - uses: vmactions/freebsd-vm@v1 - with: - prepare: | - pkg install -y cmake ninja bash capnproto - sync: 'rsync' - copyback: false - - - name: Run CI script - run: | - cd ${{ github.workspace }} - CI_CONFIG="ci/configs/freebsd.bash" bash ci/scripts/ci.sh - - build-macos: - runs-on: macos-latest - name: build • macos - - steps: - - uses: actions/checkout@v5 - - - name: Install dependencies - env: - HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1 - run: | - brew install --quiet ninja capnp llvm - - - name: Run CI script - run: | - export PATH="$(brew --prefix llvm)/bin:$PATH" - CI_CONFIG="ci/configs/macos.bash" bash ci/scripts/ci.sh - - build: - runs-on: ubuntu-latest - - env: - NIXPKGS_CHANNEL: nixos-25.05 - NIX_EXTRA_CONFIG: | - keep-env-derivations = true - keep-outputs = true - NIX_EXTRA_CONFIG_ACT: | - sandbox = false - filter-syscalls = false - - strategy: - fail-fast: false - matrix: - config: [default, llvm, gnu32, sanitize, olddeps] - - name: build • ${{ matrix.config }} - - steps: - - uses: actions/checkout@v5 - - - name: Determine CI configuration - id: config - env: - CI_CONFIG: ci/configs/${{ matrix.config }}.bash - run: ci/scripts/config.sh - - - name: Install Nix - uses: cachix/install-nix-action@v31 # 2025-05-27, from https://github.com/cachix/install-nix-action/tags - with: - nix_path: nixpkgs=https://github.com/NixOS/nixpkgs/archive/${{ steps.config.outputs.nixpkgs_rev }}.tar.gz - # Act executes inside an unprivileged container (Docker or Podman), - # so KVM support isn't available. - enable_kvm: "${{ github.actor != 'nektos/act' }}" - extra_nix_config: | - ${{ env.NIX_EXTRA_CONFIG }} - ${{ github.actor == 'nektos/act' && env.NIX_EXTRA_CONFIG_ACT || '' }} - - - name: Cache Nix store - if: steps.config.outputs.cache_nix_store == 'true' - uses: nix-community/cache-nix-action@v7 - with: - primary-key: nix-${{ runner.os }}-${{ matrix.config }}-${{ steps.config.outputs.nixpkgs_rev }}-${{ hashFiles('shell.nix', 'ci/patches/*.patch', format('ci/configs/{0}.bash', matrix.config)) }} - restore-prefixes-first-match: | - nix-${{ runner.os }}-${{ matrix.config }}-${{ steps.config.outputs.nixpkgs_rev }}- - nix-${{ runner.os }}-${{ matrix.config }}- - nix-${{ runner.os }}- - gc-max-store-size-linux: 10G - - - name: Run CI script - env: - CI_CONFIG: ci/configs/${{ matrix.config }}.bash - run: ci/scripts/run.sh diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 30b4b7864881..000000000000 --- a/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# CMake artifacts -/*build* - -# Git artifacts -*.patch diff --git a/CMakeLists.txt b/CMakeLists.txt index a36023b18101..99b992e7cc57 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,14 @@ endif() include("cmake/compat_find.cmake") find_package(Threads REQUIRED) -find_package(CapnProto 0.7 QUIET NO_MODULE) +# When this file is processed via add_subdirectory() from the standalone +# wrapper, find_package(CapnProto) has already been called there to make the +# IMPORTED targets visible to the example/ sibling directory. Re-running it +# here would fail on platforms whose CapnProto cmake config registers global +# targets (e.g. NetBSD pkgsrc), so skip it when CapnProto is already found. +if(NOT CapnProto_FOUND) + find_package(CapnProto 0.7 QUIET NO_MODULE) +endif() if(NOT CapnProto_FOUND) message(FATAL_ERROR "Cap'n Proto is required but was not found.\n" @@ -113,6 +120,7 @@ endif() include("cmake/compat_config.cmake") include("cmake/pthread_checks.cmake") +include("cmake/TargetCapnpSources.cmake") include(GNUInstallDirs) # Set MP_INCLUDE_DIR as a global property so target_capnp_sources function can @@ -120,12 +128,17 @@ include(GNUInstallDirs) # to avoid "error: Import failed: /mp/proxy.capnp" failures from capnproto. set_property(GLOBAL PROPERTY MP_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include") -# Set a convenience variable for subdirectories. -if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) - set(MP_STANDALONE TRUE) - include(CTest) -else() - set(MP_STANDALONE FALSE) +# Set a convenience variable for subdirectories. May be pre-set by a parent +# CMakeLists.txt (e.g. the top-level wrapper used for `cmake -S .` standalone +# builds) so that test/ and other subdirectories know they should expose +# convenience targets even though lib/ is not the top-level source. +if(NOT DEFINED MP_STANDALONE) + if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + set(MP_STANDALONE TRUE) + include(CTest) + else() + set(MP_STANDALONE FALSE) + endif() endif() # Prevent include directories from parent project from leaking into this one. @@ -259,6 +272,5 @@ add_custom_target(install-lib VERBATIM) add_dependencies(install-lib multiprocess) -# Example and test subdirectories -add_subdirectory(example EXCLUDE_FROM_ALL) +# Test subdirectory add_subdirectory(test EXCLUDE_FROM_ALL) diff --git a/COPYING b/COPYING deleted file mode 100644 index 9d54ecbde122..000000000000 --- a/COPYING +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2009-2019 The Bitcoin Core developers -Copyright (c) 2009-2019 Bitcoin Developers - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/README.md b/README.md deleted file mode 100644 index 9a6e65795b3f..000000000000 --- a/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# libmultiprocess - -`libmultiprocess` is a C++ library and code generator making it easy to call functions and reference objects in different processes. - -For more information see the [usage instructions](doc/usage.md), [installation instructions](doc/install.md), or [design documentation](doc/design.md). - -If you have any questions, comments, or feedback, please submit an [issue](https://github.com/bitcoin-core/libmultiprocess/issues/new). -Duplicate issues are perfectly fine and all discussion about the project is welcome, since there isn't another discussion forum currently. diff --git a/ci/README.md b/ci/README.md deleted file mode 100644 index fef1c022b5c8..000000000000 --- a/ci/README.md +++ /dev/null @@ -1,52 +0,0 @@ -### CI quick-reference - -All CI is just bash and nix. - -* **Workflow**: - - `.github/workflows/ci.yml` – lists the jobs (`default`, `llvm`, …). -* **Scripts**: - - `ci/scripts/run.sh` – spins up the Nix shell then calls… - - `ci/scripts/ci.sh` – …to configure, build, and test. -* **Configuration**: - - `ci/configs/*.sh` – defines flags for each job. - - `shell.nix` – defines build environment (compilers, tools, libraries). -* **Build directories**: - - `build-*/` – separate build directories (like `build-default`, `build-llvm`) will be created for each job. - -To run jobs locally: - -```bash -CI_CONFIG=ci/configs/default.bash ci/scripts/run.sh -CI_CONFIG=ci/configs/llvm.bash ci/scripts/run.sh -CI_CONFIG=ci/configs/gnu32.bash ci/scripts/run.sh -CI_CONFIG=ci/configs/sanitize.bash ci/scripts/run.sh -CI_CONFIG=ci/configs/olddeps.bash ci/scripts/run.sh -``` - -By default CI jobs will reuse their build directories. `CI_CLEAN=1` can be specified to delete them before running instead. - -### Running workflows with `act` - -You can run either the entire workflow or a single matrix entry locally. On -macOS or Linux: - -1. Install [`act`](https://github.com/nektos/act) and either Docker or - Podman. -2. Inside the Podman VM, create a named volume for the Nix store (ext4, - case-sensitive) so builds persist across runs. Recreate it any time you want - a clean cache: - ```bash - podman volume create libmultiprocess-nix - ``` -3. From the repo root, launch the workflow. The example below targets the - sanitize matrix entry; drop the `--matrix` flag to run every configuration. - ```bash - act \ - --reuse \ - -P ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-24.04 \ - --container-options "-v libmultiprocess-nix:/nix" \ - -j build \ - --matrix config:sanitize - ``` - - diff --git a/ci/configs/default.bash b/ci/configs/default.bash deleted file mode 100644 index 56231228d4f3..000000000000 --- a/ci/configs/default.bash +++ /dev/null @@ -1,5 +0,0 @@ -CI_DESC="CI job using default libraries and tools, and running IWYU" -CI_DIR=build-default -export CXXFLAGS="-Werror -Wall -Wextra -Wpedantic -Wno-unused-parameter" -CMAKE_ARGS=(-DMP_ENABLE_IWYU=ON) -BUILD_ARGS=(-k) diff --git a/ci/configs/freebsd.bash b/ci/configs/freebsd.bash deleted file mode 100644 index 017f2186653e..000000000000 --- a/ci/configs/freebsd.bash +++ /dev/null @@ -1,5 +0,0 @@ -CI_DESC="CI config for FreeBSD" -CI_DIR=build-freebsd -export CXXFLAGS="-Werror -Wall -Wextra -Wpedantic -Wno-unused-parameter" -CMAKE_ARGS=(-G Ninja) -BUILD_ARGS=(-k 0) diff --git a/ci/configs/gnu32.bash b/ci/configs/gnu32.bash deleted file mode 100644 index 04d78a24fc5c..000000000000 --- a/ci/configs/gnu32.bash +++ /dev/null @@ -1,11 +0,0 @@ -CI_DESC="CI job cross-compiling to 32-bit" -CI_DIR=build-gnu32 -# Cache the heaviest Nix job to stay within GitHub's cache budget. -CI_CACHE_NIX_STORE=true -NIX_ARGS=( - --arg minimal true - --arg crossPkgs 'import { crossSystem = { config = "i686-unknown-linux-gnu"; }; }' -) -export CXXFLAGS="-Werror -Wall -Wextra -Wpedantic -Wno-unused-parameter" -CMAKE_ARGS=(-G Ninja) -BUILD_ARGS=(-k 0) diff --git a/ci/configs/llvm.bash b/ci/configs/llvm.bash deleted file mode 100644 index ba34cbf467bb..000000000000 --- a/ci/configs/llvm.bash +++ /dev/null @@ -1,11 +0,0 @@ -CI_DESC="CI job using LLVM-based libraries and tools (clang, libc++, clang-tidy, iwyu) and testing Ninja" -CI_DIR=build-llvm -NIX_ARGS=(--arg enableLibcxx true) -export CXX=clang++ -export CXXFLAGS="-Werror -Wall -Wextra -Wpedantic -Wthread-safety -Wno-unused-parameter" -CMAKE_ARGS=( - -G Ninja - -DMP_ENABLE_CLANG_TIDY=ON - -DMP_ENABLE_IWYU=ON -) -BUILD_ARGS=(-k 0) diff --git a/ci/configs/macos.bash b/ci/configs/macos.bash deleted file mode 100644 index 895d795f8912..000000000000 --- a/ci/configs/macos.bash +++ /dev/null @@ -1,5 +0,0 @@ -CI_DESC="CI config for macOS" -CI_DIR=build-macos -export CXXFLAGS="-Werror -Wall -Wextra -Wpedantic -Wno-unused-parameter" -CMAKE_ARGS=(-G Ninja -DMP_ENABLE_CLANG_TIDY=ON) -BUILD_ARGS=(-k 0) diff --git a/ci/configs/netbsd.bash b/ci/configs/netbsd.bash deleted file mode 100644 index c3e7d258e685..000000000000 --- a/ci/configs/netbsd.bash +++ /dev/null @@ -1,11 +0,0 @@ -CI_DESC="CI config for NetBSD" -CI_DIR=build-netbsd -export CXXFLAGS="-Werror -Wall -Wextra -Wpedantic -Wno-unused-parameter" -# Hardcode GCC 14, since default GCC versions installed by NetBSD are older -# and may not be compatible with libmultiprocess. GCC 14 was chosen because -# it's the latest compiler available on all versions of NetBSD that we test. -# Note that the GCC version specified here must match the version specified -# in pkg_add in ci.yml. -export CXX="/usr/pkg/gcc14/bin/g++" -CMAKE_ARGS=(-G Ninja) -BUILD_ARGS=(-k 0) diff --git a/ci/configs/olddeps.bash b/ci/configs/olddeps.bash deleted file mode 100644 index 95f44128d90c..000000000000 --- a/ci/configs/olddeps.bash +++ /dev/null @@ -1,5 +0,0 @@ -CI_DESC="CI job using old Cap'n Proto and cmake versions" -CI_DIR=build-olddeps -export CXXFLAGS="-Werror -Wall -Wextra -Wpedantic -Wno-unused-parameter -Wno-error=array-bounds" -NIX_ARGS=(--argstr capnprotoVersion "0.7.1" --argstr cmakeVersion "3.12.4") -BUILD_ARGS=(-k) diff --git a/ci/configs/openbsd.bash b/ci/configs/openbsd.bash deleted file mode 100644 index a404e2bc630a..000000000000 --- a/ci/configs/openbsd.bash +++ /dev/null @@ -1,5 +0,0 @@ -CI_DESC="CI config for OpenBSD" -CI_DIR=build-openbsd -export CXXFLAGS="-Werror -Wall -Wextra -Wpedantic -Wno-unused-parameter" -CMAKE_ARGS=(-G Ninja) -BUILD_ARGS=(-k 0) diff --git a/ci/configs/sanitize.bash b/ci/configs/sanitize.bash deleted file mode 100644 index 0375fd3ab2d2..000000000000 --- a/ci/configs/sanitize.bash +++ /dev/null @@ -1,8 +0,0 @@ -CI_DESC="CI job running ThreadSanitizer" -CI_DIR=build-sanitize -NIX_ARGS=(--arg enableLibcxx true --argstr libcxxSanitizers "Thread" --argstr capnprotoSanitizers "thread") -export CXX=clang++ -export CXXFLAGS="-ggdb -Werror -Wall -Wextra -Wpedantic -Wthread-safety -Wno-unused-parameter -fsanitize=thread" -CMAKE_ARGS=() -BUILD_ARGS=(-k -j4) -BUILD_TARGETS=(mptest) diff --git a/ci/patches/spaceship.patch b/ci/patches/spaceship.patch deleted file mode 100644 index 08a885ddf0ab..000000000000 --- a/ci/patches/spaceship.patch +++ /dev/null @@ -1,29 +0,0 @@ -commit e3da7da967b94f373c29a198ce45f30fb9f0e517 -Author: Ed Catmur -Date: Tue Jan 31 16:27:04 2023 +0000 - - Remove operator!= synthesized by spaceship - - An operator!= suppresses the reversed equality comparison candidate generation. - - This is visible in clang 16 (rc0 just released) and in gcc trunk (so probably gcc 13). - -diff --git a/c++/src/kj/string.h b/c++/src/kj/string.h -index 193442aa..17835892 100644 ---- a/c++/src/kj/string.h -+++ b/c++/src/kj/string.h -@@ -122,10 +122,14 @@ public: - inline constexpr const char* end() const { return content.end() - 1; } - - inline constexpr bool operator==(decltype(nullptr)) const { return content.size() <= 1; } -+#if !__cpp_impl_three_way_comparison - inline constexpr bool operator!=(decltype(nullptr)) const { return content.size() > 1; } -+#endif - - inline bool operator==(const StringPtr& other) const; -+#if !__cpp_impl_three_way_comparison - inline bool operator!=(const StringPtr& other) const { return !(*this == other); } -+#endif - inline bool operator< (const StringPtr& other) const; - inline bool operator> (const StringPtr& other) const { return other < *this; } - inline bool operator<=(const StringPtr& other) const { return !(other < *this); } diff --git a/ci/scripts/bitcoin_core_ci.sh b/ci/scripts/bitcoin_core_ci.sh deleted file mode 100755 index 7f3c5cbd4b97..000000000000 --- a/ci/scripts/bitcoin_core_ci.sh +++ /dev/null @@ -1,173 +0,0 @@ -#!/usr/bin/env bash - -export LC_ALL=C - -set -o errexit -o nounset -o pipefail -o xtrace - -readonly SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" - -source "${SCRIPT_DIR}/ci_helpers.sh" - -replace_subtree() { - rm -rf src/ipc/libmultiprocess - cp -a _libmultiprocess src/ipc/libmultiprocess - rm -rf src/ipc/libmultiprocess/.git -} - -add_llvm_apt_repository() { - curl -s "https://apt.llvm.org/llvm-snapshot.gpg.key" | sudo tee "/etc/apt/trusted.gpg.d/apt.llvm.org.asc" > /dev/null - source /etc/os-release - echo "deb http://apt.llvm.org/${VERSION_CODENAME}/ llvm-toolchain-${VERSION_CODENAME}-${LLVM_VERSION} main" | sudo tee "/etc/apt/sources.list.d/llvm.list" - sudo apt-get update -} - -install_llvm_alternatives() { - sudo update-alternatives --install /usr/bin/clang++ clang++ "/usr/bin/clang++-${LLVM_VERSION}" 100 - sudo update-alternatives --install /usr/bin/clang clang "/usr/bin/clang-${LLVM_VERSION}" 100 - sudo update-alternatives --install /usr/bin/llvm-symbolizer llvm-symbolizer "/usr/bin/llvm-symbolizer-${LLVM_VERSION}" 100 -} - -set_llvm_alternatives() { - sudo update-alternatives --set clang "/usr/bin/clang-${LLVM_VERSION}" - sudo update-alternatives --set clang++ "/usr/bin/clang++-${LLVM_VERSION}" - sudo update-alternatives --set llvm-symbolizer "/usr/bin/llvm-symbolizer-${LLVM_VERSION}" -} - -install_tsan_packages() { - install_apt_packages \ - ccache \ - "clang-${LLVM_VERSION}" \ - "llvm-${LLVM_VERSION}" \ - "llvm-${LLVM_VERSION}-dev" \ - "libclang-${LLVM_VERSION}-dev" \ - "libclang-rt-${LLVM_VERSION}-dev" \ - ninja-build \ - pkgconf \ - python3-pip \ - bison - install_llvm_alternatives - set_llvm_alternatives - install_pip_packages --break-system-packages pycapnp -} - -build_instrumented_libcxx() { - export PATH="/usr/lib/llvm-${LLVM_VERSION}/bin:${PATH}" - - ls -l /usr/bin/clang /usr/bin/clang++ /usr/bin/llvm-symbolizer - which clang clang++ llvm-symbolizer - clang --version - clang++ --version - "/usr/bin/clang-${LLVM_VERSION}" --version - "/usr/bin/clang++-${LLVM_VERSION}" --version - git clone --depth=1 https://github.com/llvm/llvm-project -b "llvmorg-${LLVM_VERSION}.1.0" /tmp/llvm-project - cmake -G Ninja -B "${LIBCXX_DIR}" \ - -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \ - -DCMAKE_BUILD_TYPE=Release \ - -DLLVM_USE_SANITIZER=Thread \ - -DCMAKE_C_COMPILER="/usr/bin/clang-${LLVM_VERSION}" \ - -DCMAKE_CXX_COMPILER="/usr/bin/clang++-${LLVM_VERSION}" \ - -DLLVM_TARGETS_TO_BUILD=Native \ - -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF \ - -DLIBCXX_INCLUDE_TESTS=OFF \ - -DLIBCXXABI_INCLUDE_TESTS=OFF \ - -DLIBUNWIND_INCLUDE_TESTS=OFF \ - -DLIBCXXABI_USE_LLVM_UNWINDER=OFF \ - -S /tmp/llvm-project/runtimes - grep -E 'CMAKE_(C|CXX)_COMPILER' "${LIBCXX_DIR}/CMakeCache.txt" - ninja -C "${LIBCXX_DIR}" -j "${BUILD_PARALLEL}" -v - rm -rf /tmp/llvm-project -} - -configure_bitcoin_core() { - local cmake_arg - local cmake_args=() - - if [[ -n "${BITCOIN_CORE_CMAKE_ARGS:-}" ]]; then - while IFS= read -r cmake_arg; do - [[ -n "${cmake_arg}" ]] || continue - cmake_args+=("${cmake_arg}") - done <<< "${BITCOIN_CORE_CMAKE_ARGS}" - fi - - cmake -S . -B build \ - --preset=dev-mode \ - -DCMAKE_BUILD_TYPE=Debug \ - -DBUILD_GUI=OFF \ - -DBUILD_GUI_TESTS=OFF \ - -DWITH_ZMQ=OFF \ - -DWITH_USDT=OFF \ - -DBUILD_BENCH=OFF \ - -DBUILD_FUZZ_BINARY=OFF \ - -DWITH_QRENCODE=OFF \ - -G Ninja \ - "${cmake_args[@]}" -} - -build_bitcoin_core() { - cmake --build build --parallel "${BUILD_PARALLEL}" -} - -build_depends_without_ipc() { - make -C depends -j "${BUILD_PARALLEL}" \ - CC=clang \ - CXX=clang++ \ - CXXFLAGS="${LIBCXX_FLAGS}" \ - NO_QT=1 \ - NO_ZMQ=1 \ - NO_USDT=1 \ - NO_QR=1 \ - NO_IPC=1 -} - -build_depends_with_ipc() { - make -C depends -j "${BUILD_PARALLEL}" \ - CC=clang \ - CXX=clang++ \ - CXXFLAGS="${LIBCXX_FLAGS}" \ - NO_QT=1 \ - NO_ZMQ=1 \ - NO_USDT=1 \ - NO_QR=1 -} - -run_ipc_unit_tests() { - local runs="$1" - - for _ in $(seq 1 "${runs}"); do - build/bin/test_bitcoin --run_test=ipc_tests,miner_tests --catch_system_error=no --log_level=nothing --report_level=no - done -} - -run_ipc_functional_tests() { - local runs="$1" - local timeout_factor="$2" - local test_scripts - local test_args=() - - test_scripts=$(python3 -c "import sys; import os; sys.path.append(os.path.abspath('build/test/functional')); from test_runner import ALL_SCRIPTS; print(' '.join(s for s in ALL_SCRIPTS if s.startswith('interface_ipc')))") - for _ in $(seq 1 "${runs}"); do - for script in $test_scripts; do - test_args+=("$script") - done - done - build/test/functional/test_runner.py "${test_args[@]}" --jobs "${PARALLEL}" --timeout-factor="${timeout_factor}" --failfast --combinedlogslen=99999999 -} - -main() { - local command="${1:?missing command}" - shift - - [[ "${command}" =~ ^[a-z_][a-z0-9_]*$ ]] || { - echo "Invalid command: ${command}" >&2 - exit 1 - } - - if declare -F "${command}" >/dev/null; then - "${command}" "$@" - else - echo "Unknown command: ${command}" >&2 - exit 1 - fi -} - -main "$@" diff --git a/ci/scripts/ci.sh b/ci/scripts/ci.sh deleted file mode 100755 index d989e9f45969..000000000000 --- a/ci/scripts/ci.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -export LC_ALL=C.UTF-8 - -set -o errexit -o nounset -o pipefail -o xtrace - -[ "${CI_CONFIG+x}" ] && source "$CI_CONFIG" - -: "${CI_DIR:=build}" -if ! [ -v BUILD_TARGETS ]; then - BUILD_TARGETS=(all tests mpexamples) -fi - -[ -n "${CI_CLEAN-}" ] && rm -rf "${CI_DIR}" - -cmake --version -cmake_ver=$(cmake --version | awk '/version/{print $3; exit}') -ver_ge() { [ "$(printf '%s\n' "$2" "$1" | sort -V | head -n1)" = "$2" ]; } - -src_dir=$PWD -mkdir -p "$CI_DIR" -cd "$CI_DIR" -cmake "$src_dir" "${CMAKE_ARGS[@]+"${CMAKE_ARGS[@]}"}" -if ver_ge "$cmake_ver" "3.15"; then - cmake --build . -t "${BUILD_TARGETS[@]}" -- "${BUILD_ARGS[@]+"${BUILD_ARGS[@]}"}" -else - # Older versions of cmake can only build one target at a time with --target, - # and do not support -t shortcut - for t in "${BUILD_TARGETS[@]}"; do - cmake --build . --target "$t" -- "${BUILD_ARGS[@]+"${BUILD_ARGS[@]}"}" - done -fi -ctest --output-on-failure diff --git a/ci/scripts/ci_helpers.sh b/ci/scripts/ci_helpers.sh deleted file mode 100755 index 1b6d0121969e..000000000000 --- a/ci/scripts/ci_helpers.sh +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/env bash - -export LC_ALL=C - -set -o errexit -o nounset -o pipefail -o xtrace - -write_env_var() { - local key="$1" - local value="$2" - - if [[ -n "${GITHUB_ENV:-}" ]]; then - echo "${key}=${value}" >> "${GITHUB_ENV}" - else - export "${key}=${value}" - fi -} - -write_output_var() { - local key="$1" - local value="$2" - - if [[ -n "${GITHUB_OUTPUT:-}" ]]; then - echo "${key}=${value}" >> "${GITHUB_OUTPUT}" - else - echo "${key}=${value}" - fi -} - -available_nproc() { - if command -v nproc >/dev/null 2>&1; then - nproc - else - sysctl -n hw.logicalcpu - fi -} - -determine_parallelism() { - local multiplier="$1" - local available - - available="$(available_nproc)" - write_env_var BUILD_PARALLEL "${available}" - write_env_var PARALLEL "$((available * multiplier))" -} - -reset_ccache_stats() { - which ccache - ccache --version - ccache --zero-stats -} - -show_ccache_stats() { - ccache --show-stats -} - -install_apt_packages() { - sudo apt-get install --no-install-recommends -y "$@" -} - -install_homebrew_packages() { - HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install --quiet "$@" -} - -install_pip_packages() { - pip3 install "$@" -} - -determine_host() { - local config_guess="${1:-./depends/config.guess}" - local output_key="${2:-host}" - - write_output_var "${output_key}" "$("${config_guess}")" -} - -ci_helpers_main() { - local command="${1:?missing command}" - shift - - [[ "${command}" =~ ^[a-z_][a-z0-9_]*$ ]] || { - echo "Invalid command: ${command}" >&2 - exit 1 - } - - if declare -F "${command}" >/dev/null; then - "${command}" "$@" - else - echo "Unknown command: ${command}" >&2 - exit 1 - fi -} - -if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then - ci_helpers_main "$@" -fi diff --git a/ci/scripts/config.sh b/ci/scripts/config.sh deleted file mode 100755 index 7fe8118d7bee..000000000000 --- a/ci/scripts/config.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -# -# Source CI configuration and output variables needed by the workflow. - -export LC_ALL=C - -set -o errexit -o nounset -o pipefail -o xtrace - -readonly SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" - -source "${SCRIPT_DIR}/ci_helpers.sh" - -[ "${CI_CONFIG+x}" ] && source "$CI_CONFIG" - -# Resolve the nixpkgs channel to a specific revision for use in cache keys. -if [[ -n "${NIXPKGS_CHANNEL:-}" ]]; then - rev="$(curl --fail --location --silent --show-error "https://channels.nixos.org/${NIXPKGS_CHANNEL}/git-revision")" - test -n "${rev}" - write_output_var nixpkgs_rev "${rev}" -fi - -write_output_var cache_nix_store "${CI_CACHE_NIX_STORE:-false}" diff --git a/ci/scripts/run.sh b/ci/scripts/run.sh deleted file mode 100755 index 04ac8596d490..000000000000 --- a/ci/scripts/run.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash -# -# Copyright (c) The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -export LC_ALL=C.UTF-8 - -set -o errexit -o nounset -o pipefail -o xtrace - -[ "${CI_CONFIG+x}" ] && source "$CI_CONFIG" - -nix develop --ignore-environment --keep CI_CONFIG --keep CI_CLEAN "${NIX_ARGS[@]+"${NIX_ARGS[@]}"}" -f shell.nix --command ci/scripts/ci.sh - -# Create a GC root for the shell closure so the cache-nix-action save step -# does not garbage-collect it. -if [ -n "${CI_CACHE_NIX_STORE-}" ]; then - nix-build shell.nix \ - -o "$CI_DIR/gcroot" \ - "${NIX_ARGS[@]+"${NIX_ARGS[@]}"}" - # Verify the closure is complete so the cache-nix-action save step has - # everything it needs. - nix-store --query --requisites "$CI_DIR/gcroot" >/dev/null -fi diff --git a/doc/design.md b/doc/design.md deleted file mode 100644 index 113cafc4af39..000000000000 --- a/doc/design.md +++ /dev/null @@ -1,227 +0,0 @@ -# libmultiprocess Design - -Given an interface description of an object with one or more methods, libmultiprocess generates: - -* A C++ `ProxyClient` class template specialization with an implementation of each interface method that sends a request over a socket, waits for a response, and returns the result. -* A C++ `ProxyServer` class template specialization that listens for requests over a socket and calls a wrapped C++ object implementing the same interface to actually execute the requests. - -The function call ⇆ request translation supports input and output arguments, standard types like `unique_ptr`, `vector`, `map`, and `optional`, and bidirectional calls between processes through interface pointer and `std::function` arguments. - -If the wrapped C++ object inherits from an abstract base class declaring virtual methods, the generated `ProxyClient` objects can inherit from the same class, allowing interprocess calls to replace local calls without changes to existing code. - -There is also optional support for thread mapping, so each thread making interprocess calls can have a dedicated thread processing requests from it, and callbacks from processing threads are executed on corresponding request threads (so recursive mutexes and thread names function as expected in callbacks). - -Libmultiprocess acts as a pure wrapper or layer over the underlying protocol. Clients and servers written in other languages, but using a shared capnproto schema can communicate with interprocess counterparties using libmultiprocess without having to use libmultiprocess themselves or having to know about the implementation details of libmultiprocess. - -## Core Architecture - -The `ProxyClient` and `ProxyServer` generated classes are not directly exposed to the user, as described in [usage.md](usage.md). Instead, they wrap C++ interfaces and appear to the user as pointers to an interface. They are first instantiated when calling `ConnectStream` and `ServeStream` respectively for creating the `InitInterface`. These methods establish connections through sockets, internally creating `Connection` objects wrapping a `capnp::RpcSystem` configured for client and server mode respectively. - -The `InitInterface` interface will typically have methods which return other interfaces, giving the connecting process the ability to call other functions in the serving process. Interfaces can also have methods accepting other interfaces as parameters, giving serving processes the ability to call back and invoke functions in connecting processes. Creating new interfaces does not create new connections, and typically many interface objects will share the same connection. - -Both `ConnectStream` and `ServeStream` also require an instantiation of the `EventLoop`. The `EventLoop` owns pending requests, notifies on request dispatch, allows clients from multiple threads to make synchronous calls, and handles some cleanup routines on exit. It must be run in a separate thread so it is always active and can process incoming requests from local clients and remote connections. - -When a generated method on the `ProxyClient` is called, it calls `clientInvoke` with the capnp-translated types. `clientInvoke` creates a self-executing promise (`kj::TaskSet`) that drives the execution of the request and gives ownership of it to the `EventLoop`. `clientInvoke` blocks until a response is received, or until there is a call from the server that needs to run on the same client thread, using a `Waiter` object. - -On the server side, the `capnp::RpcSystem` receives the capnp request and invokes the corresponding C++ method through the corresponding `ProxyServer` and the heavily templated `serverInvoke` triggering a `ServerCall`. The return values from the actual C++ methods are copied into capnp responses by `ServerRet` and exceptions are caught and copied by `ServerExcept`. The two are connected through `ServerField`. The main method driving execution of a request is `PassField`, which is invoked through `ServerField`. Instantiated interfaces, or capabilities in capnp speak, are tracked and owned by the server's `capnp::RpcSystem`. - -## Request and Response Flow - -Method parameters and return values are serialized using Cap'n Proto's Builder objects (for sending) and Reader objects (for receiving). Input parameters flow from the client to the server, while output parameters (return values) flow back from the server to the client. - -```mermaid -sequenceDiagram - participant clientInvoke - participant BuildField as BuildField
(Client) - participant ReadField_C as ReadField
(Client) - participant Request as Request
message - participant serverInvoke - participant ReadField as ReadField
(Server) - participant BuildField_S as BuildField
(Server) - participant Response as Response
message - - Note over clientInvoke,ReadField: Input Parameter Flow - clientInvoke->>BuildField: BuildField(input_arg) - BuildField->>Request: Serialize input - Request->>serverInvoke: Cap'n Proto message - serverInvoke->>ReadField: Deserialize input - - Note over clientInvoke,Response: Output Parameter Flow - serverInvoke-->>BuildField_S: BuildField(output) - BuildField_S-->Response: Serialize output - Response-->>ReadField_C: Cap'n Proto message - ReadField_C-->>clientInvoke: Deserialize output -``` - -### Detailed Serialization Mechanism - -Parameters are represented as Fields that must be set on Cap'n Proto Builder objects (for sending) and read from Reader objects (for receiving). - -#### Building Fields - -`BuildField` uses a generated parameter `Accessor` to set the appropriate field in the Cap'n Proto Builder object. - -```mermaid -sequenceDiagram - participant clientInvoke as clientInvoke or
serverInvoke - participant BuildField - participant Accessor - participant Builder as Params::Builder - - Note over clientInvoke,Builder: Serializing Parameters - clientInvoke->>BuildField: BuildField(param1) - BuildField->>Accessor: Use generated field accessor - Accessor->>Builder: builder.setField1(param1) - - clientInvoke->>BuildField: BuildField(param2) - BuildField->>Accessor: Use generated field Accessor - Accessor->>Builder: builder.setField2(param2) -``` - -#### Reading Fields - -`ReadField` uses a generated parameter `Accessor` to read the appropriate field from the Cap'n Proto Reader object and reconstruct C++ parameters. - -```mermaid -sequenceDiagram - participant serverInvoke as clientInvoke or
serverInvoke - participant ReadField - participant Accessor - participant Reader as Params::Reader - participant ServerCall - - Note over serverInvoke,ServerCall: Deserializing Parameters - serverInvoke->>ReadField: Read param1 - ReadField->>Accessor: Use generated field accessor - Accessor->>Reader: reader.getField1() - Reader-->>ServerCall: call function with param1 -``` - -## Server-Side Request Processing - -The generated server code uses a Russian nesting doll structure to process method fields. Each `ServerField` wraps another `ServerField` (for the next parameter), or wraps `ServerRet` (for the return value), which finally wraps `ServerCall` (which invokes the actual C++ method). - -Each `ServerField` invokes `PassField`, which: -1. Calls `ReadField` to deserialize the parameter from the `Params::Reader` -2. Calls the next nested layer's `invoke()` with the accumulated parameters -3. Calls `BuildField` to serialize the parameter back if it's an output parameter - -`ServerRet` invokes the next layer (typically `ServerCall`), stores the result, and calls `BuildField` to serialize it into the `Results::Builder`. - -`ServerCall` uses the generated `ProxyMethod::impl` pointer-to-member to invoke the actual C++ method on the wrapped implementation object. - -```mermaid -sequenceDiagram - participant serverInvoke - participant SF1 as ServerField
(param 1) - participant SF2 as ServerField
(param 2) - participant SR as ServerRet
(return value) - participant SC as ServerCall - participant PMT as ProxyMethodTraits - participant Impl as Actual C++ Method - - serverInvoke->>SF1: SF1::invoke - SF1->>SF2: SF2::invoke - SF2->>SR: SR::invoke - SR->>SC: SC::invoke - SC->>PMT: PMT::invoke - PMT->>Impl: Call impl method - Impl->>PMT: return - PMT->>SC: return - SC->>SR: return - SR->>SF2: return - SF2->>SF1: return - SF1->>serverInvoke: return -``` - -## Advanced Features - -### Callbacks - -Callbacks (passed as `std::function` arguments) are intercepted by `CustomBuildField` and converted into Cap'n Proto capabilities that can be invoked across process boundaries. On the receiving end, `CustomReadField` intercepts the capability and constructs a `ProxyCallFn` object with an `operator()` that sends function calls back over the socket to invoke the original callback. - -```mermaid -sequenceDiagram - participant CT as Client Thread - participant C as clientInvoke - participant CBF1 as CustomBuildField (Client) - participant S as Socket - participant CRF1 as CustomReadField (Server) - participant Srv as Server Code - participant PCF as ProxyCallFn - - C->>CBF1: send function parameter - CBF1->>S: creates a Server for the function and sends a capability - S->>CRF1: receives a capability and creates ProxyCallFn - CRF1->>Srv: - Srv->>PCF: call the callback - PCF-->>CT: sends request to Client -``` - -### Thread Mapping - -Thread mapping enables each client thread to have a dedicated server thread processing its requests, preserving thread-local state and allowing recursive mutex usage across process boundaries. - -Thread mapping is initialized by defining an interface method with a `ThreadMap` parameter and/or response. The example below adds `ThreadMap` to the `construct` method because libmultiprocess calls the `construct` method automatically. - -```capnp -interface InitInterface $Proxy.wrap("Init") { - construct @0 (threadMap: Proxy.ThreadMap) -> (threadMap :Proxy.ThreadMap); -} -``` - -- **ThreadMap in parameter**: The client's `CustomBuildField` creates a `ThreadMap::Server` capability and sends it to the server, where `CustomReadField` stores the `ThreadMap::Client` in `connection.m_thread_map` -- **ThreadMap in response**: The server's `CustomBuildField` creates a `ThreadMap::Server` capability and sends it to the client, where `CustomReadField` stores the `ThreadMap::Client` in `connection.m_thread_map` - -You can specify ThreadMap in the parameter only, response only, or both: -- **Parameter only**: Server can create threads on the client -- **Response only**: Client can create threads on the server -- **Both (as shown)**: Bidirectional thread creation - -When both parameter and response include ThreadMap, both processes end up with `ThreadMap::Client` capabilities pointing to each other's `ThreadMap::Server`, allowing both sides to create threads on the other process. - -### Async Processing with Context - -By adding a `Context` parameter to a method in the capnp interface file, you enable async processing where the client tells the server to execute the request in a separate worker thread. For example: - -```capnp -processData @5 (context :Proxy.Context, data :Data) -> (result :Result); -``` - -If a method does not have a `Context` parameter, then libmultiprocess will execute IPC requests invoking that method on the I/O event loop thread. This is fine for fast and non-blocking methods, but should be avoided for any methods that are slow or blocking or make any IPC calls(including callbacks to the client), since as long as the method is executing, the Cap'n Proto event loop will not be able to perform any I/O. - -When a method has a `Context` parameter: - -**Client side** (`CustomBuildField`): -If this is the first asynchronous request made from the current client thread, `CustomBuildField` will: -1. Call `connection.m_thread_map.makeThreadRequest()` to request a dedicated worker thread on the server (stored in `request_threads` map) -2. Set the remote thread capability in `Context.thread` -3. Create a local `Thread::Server` object for the current thread (stored in `callback_threads` map) -4. Set the local thread capability in `Context.callbackThread` - -Subsequent requests will reuse the existing thread capabilities held in `callback_threads` and `request_threads`. - -**Server side** (`PassField`): -1. Looks up the local `Thread::Server` object specified by `context.thread` -2. The worker thread: - - Stores `context.callbackThread` in its `request_threads` map (so callbacks go to the right client thread) - - Posts the work lambda to that thread's queue via `waiter->post(invoke)` - - Cleans up the `request_threads` entry - -## Interface Definitions - -As explained in the [usage](usage.md) document, interface descriptions need to be consumed both by the _libmultiprocess_ code generator, and by C++ code that calls and implements the interfaces. The C++ code only needs to know about C++ arguments and return types, while the code generator only needs to know about capnp arguments and return types, but both need to know class and method names, so the corresponding `.h` and `.capnp` source files contain some of the same information, and have to be kept in sync manually when methods or parameters change. Despite the redundancy, reconciling the interface definitions is designed to be _straightforward_ and _safe_. _Straightforward_ because there is no need to write manual serialization code or use awkward intermediate types like [`UniValue`](https://github.com/bitcoin/bitcoin/blob/master/src/univalue/include/univalue.h) instead of native types. _Safe_ because if there are any inconsistencies between API and data definitions (even minor ones like using a narrow int data type for a wider int API input), there are errors at build time instead of errors or bugs at runtime. - -In the future, it would be possible to combine API and data definitions together using [C++ attributes](https://en.cppreference.com/w/cpp/language/attributes). To do this we would add attributes to the API definition files, and then generate the data definitions from the API definitions and attributes. I didn't take this approach mostly because it would be extra work, but also because until C++ standardizes reflection, this would require either hooking into compiler APIs like https://github.com/RosettaCommons/binder, or parsing C++ code manually like http://www.swig.org/. - -## What is `kj`? - -KJ is a concurrency framework [bundled with -capnproto](https://capnproto.org/cxxrpc.html#kj-concurrency-framework); it is used as a -basis in this library to construct the event-loop necessary to service IPC requests. - -## Future directions - -_libmultiprocess_ uses the [Cap'n Proto](https://capnproto.org) interface description language and protocol, but it could be extended or changed to use a different IDL/protocol like [gRPC](https://grpc.io). The nice thing about _Cap'n Proto_ compared to _gRPC_ and most other lower level protocols is that it allows interface pointers (_Services_ in gRPC parlance) to be passed as method arguments and return values, so object references and bidirectional requests work out of the box. Supporting a lower-level protocol would require adding maps and tracking code to proxy objects. - -_libmultiprocess_ is currently compatible with sandboxing but could add platform-specific sandboxing support or integration with a sandboxing library like [SAPI](https://github.com/google/sandboxed-api). diff --git a/doc/install.md b/doc/install.md deleted file mode 100644 index ac2f7f6a777c..000000000000 --- a/doc/install.md +++ /dev/null @@ -1,52 +0,0 @@ -# libmultiprocess Installation - -Installation currently requires Cap'n Proto 0.7 or higher: - -```sh -apt install libcapnp-dev capnproto -brew install capnp cmake -dnf install capnproto -``` - -Installation steps are: - -```sh -mkdir build -cd build -cmake .. -make -make check # Optionally build and run tests -make install -``` - -To build with libmultiprocess in a CMake project can specify: - -```cmake -find_package(Libmultiprocess) -target_capnp_sources(mytarget ${CMAKE_CURRENT_SOURCE_DIR} myschema.capnp) -``` - -Which will locate the libmultiprocess cmake package, and call the -`target_capnp_sources` function to generate C++ files and link them into a -library or executable target. See `example/CMakeLists.txt` for a complete -example. - -To build with libmultiprocess in a non-CMake project can use installed -`/include/mpgen.mk` Makefile rule to generate C++ files, and -`/lib/pkgconfig/libmultiprocess.pc` pkg-config definition to link -against the runtime library. - -For cross-compilation, it may be useful to build the runtime library and code -generation binaries separately, which can be done with: - -```sh -make install-bin # install bin/mpgen and related files -make install-lib # install lib/libmultiprocess.a and related files -``` - -It is also possible to import CMake targets separately with: - -```cmake -find_package(Libmultiprocess COMPONENTS Bin) -find_package(Libmultiprocess COMPONENTS Lib) -``` diff --git a/doc/usage.md b/doc/usage.md deleted file mode 100644 index f387db4d8d8a..000000000000 --- a/doc/usage.md +++ /dev/null @@ -1,27 +0,0 @@ -# libmultiprocess Usage - -## Overview - -_libmultiprocess_ is a library and code generator that allows calling C++ class interfaces across different processes. For an interface to be available from other processes, it needs two definitions: - -- An **API definition** declaring how the interface is called. Included examples: [calculator.h](../example/calculator.h), [printer.h](../example/printer.h), [init.h](../example/init.h). Bitcoin examples: [node.h](https://github.com/bitcoin/bitcoin/blob/master/src/interfaces/node.h), [wallet.h](https://github.com/bitcoin/bitcoin/blob/master/src/interfaces/wallet.h), [echo.h](https://github.com/bitcoin/bitcoin/blob/master/src/interfaces/echo.h), [init.h](https://github.com/bitcoin/bitcoin/blob/master/src/interfaces/init.h). - -- A **data definition** declaring how interface calls get sent across the wire. Included examples: [calculator.capnp](../example/calculator.capnp), [printer.capnp](../example/printer.capnp), [init.capnp](../example/init.capnp). Bitcoin examples: [node.capnp](https://github.com/ryanofsky/bitcoin/blob/ipc-export/src/ipc/capnp/node.capnp), [wallet.capnp](https://github.com/ryanofsky/bitcoin/blob/ipc-export/src/ipc/capnp/wallet.capnp), [echo.capnp](https://github.com/bitcoin/bitcoin/blob/master/src/ipc/capnp/echo.capnp), [init.capnp](https://github.com/bitcoin/bitcoin/blob/master/src/ipc/capnp/init.capnp). - -The `*.capnp` data definition files are consumed by the _libmultiprocess_ code generator and each `X.capnp` file generates `X.capnp.c++`, `X.capnp.h`, `X.capnp.proxy-client.c++`, `X.capnp.proxy-server.c++`, `X.capnp.proxy-types.c++`, `X.capnp.proxy-types.h`, and `X.capnp.proxy.h` output files. The generated files include `mp::ProxyClient` and `mp::ProxyServer` class specializations for all the interfaces in the `.capnp` files. These allow methods on C++ objects in one process to be called from other processes over IPC sockets. - -The `ProxyServer` objects help translate IPC requests from a socket to method calls on a local object. The `ProxyServer` objects are just used internally by the `mp::ServeStream(loop, socket, wrapped_object)` and `mp::ListenConnections(loop, socket, wrapped_object)` functions, and aren't exposed externally. The `ProxyClient` classes are exposed, and returned from the `mp::ConnectStream(loop, socket)` function and meant to be used directly. The classes implement methods described in `.capnp` definitions, and whenever any method is called, a request with the method arguments is sent over the associated IPC connection, and the corresponding `wrapped_object` method on the other end of the connection is called, with the `ProxyClient` method blocking until it returns and forwarding back any return value to the `ProxyClient` method caller. - -## Example - -A simple interface description can be found at [test/mp/test/foo.capnp](../test/mp/test/foo.capnp), implementation in [test/mp/test/foo.h](../test/mp/test/foo.h), and usage in [test/mp/test/test.cpp](../test/mp/test/test.cpp). - -A more complete example can be found in [example](../example/) and run with: - -```sh -mkdir build -cd build -cmake .. -make mpexamples -example/mpexample -``` diff --git a/doc/versions.md b/doc/versions.md deleted file mode 100644 index 3cfa28e36fa8..000000000000 --- a/doc/versions.md +++ /dev/null @@ -1,83 +0,0 @@ -# libmultiprocess Versions - -Library versions are tracked with simple -[tags](https://github.com/bitcoin-core/libmultiprocess/tags) and -[branches](https://github.com/bitcoin-core/libmultiprocess/branches). - -Versioning policy is described in the [version.h](../include/mp/version.h) -include. - -## v11 -- Current unstable version. - -## [v10.0](https://github.com/bitcoin-core/libmultiprocess/commits/v10.0) -- Increases spawn test timeout to avoid spurious failures. -- Uses `throwRecoverableException` instead of raw `throw` to improve runtime error messages in macOS builds. -- Used in Bitcoin Core master branch, pulled in by [#34977](https://github.com/bitcoin/bitcoin/pull/34977). Also pulled into Bitcoin Core 31.x stable branch by [#35028](https://github.com/bitcoin/bitcoin/pull/35028). - -## [v9.0](https://github.com/bitcoin-core/libmultiprocess/commits/v9.0) -- Fixes race conditions where worker thread could be used after destruction, where getParams() could be called after request cancel, and where m_on_cancel could be called after request finishes. -- Adds `CustomHasField` hook to map Cap'n Proto null values to C++ null values. -- Improves `CustomBuildField` for `std::optional` to use move semantics. -- Adds LLVM 22 compatibility fix in type-map. -- Used in Bitcoin Core master branch, pulled in by [#34804](https://github.com/bitcoin/bitcoin/pull/34804). Also pulled into Bitcoin Core 31.x stable branch by [#34952](https://github.com/bitcoin/bitcoin/pull/34952). - -## [v8.0](https://github.com/bitcoin-core/libmultiprocess/commits/v8.0) -- Better support for non-libmultiprocess IPC clients: avoiding errors on unclean disconnects, and allowing simultaneous requests to worker threads which previously triggered "thread busy" errors. -- Intermediate version used in Bitcoin Core master branch between 30.x and 31.x branches, pulled in by [#34422](https://github.com/bitcoin/bitcoin/pull/34422). - -## [v7.0](https://github.com/bitcoin-core/libmultiprocess/commits/v7.0) -- Adds SpawnProcess race fix, cmake `target_capnp_sources` option, ci and documentation improvements. Adds `version.h` header declaring major and minor version numbers. -- Intermediate version used in Bitcoin Core master branch between 30.x and 31.x branches, pulled in by [#34363](https://github.com/bitcoin/bitcoin/pull/34363). - -## [v7.0-pre2](https://github.com/bitcoin-core/libmultiprocess/commits/v7.0-pre2) -- Fixes intermittent mptest hang and makes other minor improvements. -- Used in Bitcoin Core 30.1 and 30.2 releases and 30.x branch, pulled in by [#33518](https://github.com/bitcoin/bitcoin/pull/33518) and [#33519](https://github.com/bitcoin/bitcoin/pull/33519). - -## [v7.0-pre1](https://github.com/bitcoin-core/libmultiprocess/commits/v7.0-pre1) -- Adds support for log levels to reduce logging and "thread busy" error to avoid a crash on misuse. -- Minimum required version since Bitcoin Core 30.1, pulled in by [#33412](https://github.com/bitcoin/bitcoin/pull/33412), [#33518](https://github.com/bitcoin/bitcoin/pull/33518), and [#33519](https://github.com/bitcoin/bitcoin/pull/33519). - -## [v6.0](https://github.com/bitcoin-core/libmultiprocess/commits/v6.0) -- Adds CI scripts and build and test fixes. -- Used in Bitcoin Core 30.0 release, pulled in by [#32345](https://github.com/bitcoin/bitcoin/pull/32345), [#33241](https://github.com/bitcoin/bitcoin/pull/33241), and [#33322](https://github.com/bitcoin/bitcoin/pull/33322). - -## [v6.0-pre1](https://github.com/bitcoin-core/libmultiprocess/commits/v6.0-pre1) -- Adds fixes for unclean shutdowns and thread sanitizer issues. -- Drops `EventLoop::addClient` and `EventLoop::removeClient` methods, - requiring clients to use new `EventLoopRef` class instead. -- Minimum required version for Bitcoin Core 30.0 release, pulled in by [#31741](https://github.com/bitcoin/bitcoin/pull/31741), [#32641](https://github.com/bitcoin/bitcoin/pull/32641), and [#32345](https://github.com/bitcoin/bitcoin/pull/32345). - -## [v5.0](https://github.com/bitcoin-core/libmultiprocess/commits/v5.0) -- Adds build improvements and tidy/warning fixes. -- Used in Bitcoin Core 29 releases, pulled in by [#31945](https://github.com/bitcoin/bitcoin/pull/31945). - -## [v5.0-pre1](https://github.com/bitcoin-core/libmultiprocess/commits/v5.0-pre1) -- Adds many improvements to Bitcoin Core mining interface: splitting up type headers, fixing shutdown bugs, adding subtree build support. -- Broke up `proxy-types.h` into `type-*.h` files requiring clients to explicitly - include overloads needed for C++ ↔️ Cap'n Proto type conversions. -- Now requires C++ 20 support. -- Minimum required version for Bitcoin Core 29 releases, pulled in by [#30509](https://github.com/bitcoin/bitcoin/pull/30509), [#30510](https://github.com/bitcoin/bitcoin/pull/30510), [#31105](https://github.com/bitcoin/bitcoin/pull/31105), [#31740](https://github.com/bitcoin/bitcoin/pull/31740). - -## [v4.0](https://github.com/bitcoin-core/libmultiprocess/commits/v4.0) -- Added better cmake support, installing cmake package files so clients do not - need to use pkgconfig. -- Used in Bitcoin Core 28 releases, pulled in by [#30490](https://github.com/bitcoin/bitcoin/pull/30490) and [#30513](https://github.com/bitcoin/bitcoin/pull/30513). - -## [v3.0](https://github.com/bitcoin-core/libmultiprocess/commits/v3.0) -- Dropped compatibility with Cap'n Proto versions before 0.7. -- Used in Bitcoin Core 27 releases, pulled in by [#28735](https://github.com/bitcoin/bitcoin/pull/28735), [#28907](https://github.com/bitcoin/bitcoin/pull/28907), and [#29276](https://github.com/bitcoin/bitcoin/pull/29276). - -## [v2.0](https://github.com/bitcoin-core/libmultiprocess/commits/v2.0) -- Changed `PassField` function signature. -- Now requires C++17 support. -- Used in Bitcoin Core 25 and 26 releases, pulled in by [#26672](https://github.com/bitcoin/bitcoin/pull/26672). - -## [v1.0](https://github.com/bitcoin-core/libmultiprocess/commits/v1.0) -- Dropped hardcoded includes in generated files, now requiring `include` and - `includeTypes` annotations. -- Used in Bitcoin Core 22, 23, and 24 releases, pulled in by [#19160](https://github.com/bitcoin/bitcoin/pull/19160). - -## [v0.0](https://github.com/bitcoin-core/libmultiprocess/commits/v0.0) -- Initial version used in a downstream release. -- Used in Bitcoin Core 21 releases, pulled in by [#16367](https://github.com/bitcoin/bitcoin/pull/16367), [#18588](https://github.com/bitcoin/bitcoin/pull/18588), and [#18677](https://github.com/bitcoin/bitcoin/pull/18677). diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt deleted file mode 100644 index 7da049c3a3f7..000000000000 --- a/example/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (c) The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -include(${PROJECT_SOURCE_DIR}/cmake/TargetCapnpSources.cmake) - -add_executable(mpcalculator - calculator.cpp -) -target_capnp_sources(mpcalculator ${CMAKE_CURRENT_SOURCE_DIR} init.capnp calculator.capnp printer.capnp) -target_include_directories(mpcalculator PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(mpcalculator PRIVATE Threads::Threads) - -add_executable(mpprinter - printer.cpp -) -target_capnp_sources(mpprinter ${CMAKE_CURRENT_SOURCE_DIR} init.capnp calculator.capnp printer.capnp) -target_include_directories(mpprinter PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(mpprinter PRIVATE Threads::Threads) - -add_executable(mpexample - example.cpp -) -target_capnp_sources(mpexample ${CMAKE_CURRENT_SOURCE_DIR} init.capnp calculator.capnp printer.capnp) -target_include_directories(mpexample PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(mpexample PRIVATE Threads::Threads) - -add_custom_target(mpexamples DEPENDS mpexample mpcalculator mpprinter) diff --git a/example/calculator.capnp b/example/calculator.capnp deleted file mode 100644 index 945518836016..000000000000 --- a/example/calculator.capnp +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -@0xb67dbf34061180a9; - -using Cxx = import "/capnp/c++.capnp"; -using Proxy = import "/mp/proxy.capnp"; - -$Proxy.include("calculator.h"); -$Proxy.includeTypes("types.h"); - -interface CalculatorInterface $Proxy.wrap("Calculator") { - destroy @0 (context :Proxy.Context) -> (); - solveEquation @1 (context :Proxy.Context, eqn: Text) -> (); -} diff --git a/example/calculator.cpp b/example/calculator.cpp deleted file mode 100644 index 86ce388b0cf9..000000000000 --- a/example/calculator.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include -#include -#include // NOLINT(misc-include-cleaner) // IWYU pragma: keep - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class CalculatorImpl : public Calculator -{ -public: - CalculatorImpl(std::unique_ptr printer) : m_printer(std::move(printer)) {} - void solveEquation(const std::string& eqn) override { m_printer->print("Wow " + eqn + ", that's a tough one.\n"); } - std::unique_ptr m_printer; -}; - -class InitImpl : public Init -{ -public: - std::unique_ptr makeCalculator(std::unique_ptr printer) override - { - return std::make_unique(std::move(printer)); - } -}; - -// Exercises deprecated log callback signature -static void LogPrint(bool raise, const std::string& message) -{ - if (raise) throw std::runtime_error(message); - std::ofstream("debug.log", std::ios_base::app) << message << std::endl; -} - -int main(int argc, char** argv) -{ - if (argc != 2) { - std::cout << "Usage: mpcalculator \n"; - return 1; - } - int fd; - if (std::from_chars(argv[1], argv[1] + strlen(argv[1]), fd).ec != std::errc{}) { - std::cerr << argv[1] << " is not a number or is larger than an int\n"; - return 1; - } - mp::EventLoop loop("mpcalculator", LogPrint); - std::unique_ptr init = std::make_unique(); - mp::ServeStream(loop, fd, *init); - loop.loop(); - return 0; -} diff --git a/example/calculator.h b/example/calculator.h deleted file mode 100644 index 342a3c1d154a..000000000000 --- a/example/calculator.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef EXAMPLE_CALCULATOR_H -#define EXAMPLE_CALCULATOR_H - -#include - -class Calculator -{ -public: - virtual ~Calculator() = default; - virtual void solveEquation(const std::string& eqn) = 0; -}; - -#endif // EXAMPLE_CALCULATOR_H diff --git a/example/example.cpp b/example/example.cpp deleted file mode 100644 index 3831397781ce..000000000000 --- a/example/example.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include -#include - -#include // IWYU pragma: keep -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace fs = std::filesystem; - -static auto Spawn(mp::EventLoop& loop, const std::string& process_argv0, const std::string& new_exe_name) -{ - int pid; - const int fd = mp::SpawnProcess(pid, [&](int fd) -> std::vector { - fs::path path = process_argv0; - path.remove_filename(); - path.append(new_exe_name); - return {path.string(), std::to_string(fd)}; - }); - return std::make_tuple(mp::ConnectStream(loop, fd), pid); -} - -static void LogPrint(mp::LogMessage log_data) -{ - if (log_data.level == mp::Log::Raise) throw std::runtime_error(log_data.message); - std::ofstream("debug.log", std::ios_base::app) << log_data.message << std::endl; -} - -int main(int argc, char** argv) -{ - if (argc != 1) { - std::cout << "Usage: mpexample\n"; - return 1; - } - - std::promise promise; - std::thread loop_thread([&] { - mp::EventLoop loop("mpexample", LogPrint); - promise.set_value(&loop); - loop.loop(); - }); - mp::EventLoop* loop = promise.get_future().get(); - - auto [printer_init, printer_pid] = Spawn(*loop, argv[0], "mpprinter"); - auto [calc_init, calc_pid] = Spawn(*loop, argv[0], "mpcalculator"); - auto calc = calc_init->makeCalculator(printer_init->makePrinter()); - while (true) { - std::string eqn; - std::cout << "Enter the equation, or \"exit\" to quit: "; - std::getline(std::cin, eqn); - if (eqn == "exit") break; - calc->solveEquation(eqn); - } - calc.reset(); - calc_init.reset(); - mp::WaitProcess(calc_pid); - printer_init.reset(); - mp::WaitProcess(printer_pid); - loop_thread.join(); - std::cout << "Bye!" << std::endl; - return 0; -} diff --git a/example/init.capnp b/example/init.capnp deleted file mode 100644 index 01897f13dca4..000000000000 --- a/example/init.capnp +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (c) The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -@0xba5a7448664901b1; - -using Cxx = import "/capnp/c++.capnp"; -using Proxy = import "/mp/proxy.capnp"; -using Calculator = import "calculator.capnp"; -using Printer = import "printer.capnp"; - -$Proxy.include("calculator.h"); -$Proxy.include("init.h"); -$Proxy.include("printer.h"); -$Proxy.includeTypes("types.h"); - -interface InitInterface $Proxy.wrap("Init") { - construct @0 (threadMap: Proxy.ThreadMap) -> (threadMap :Proxy.ThreadMap); - makeCalculator @1 (context :Proxy.Context, print :Printer.PrinterInterface) -> (result :Calculator.CalculatorInterface); - makePrinter @2 (context :Proxy.Context) -> (result :Printer.PrinterInterface); -} diff --git a/example/init.h b/example/init.h deleted file mode 100644 index 54e36da8db1d..000000000000 --- a/example/init.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef EXAMPLE_INIT_H -#define EXAMPLE_INIT_H - -#include -#include -#include - -class Init -{ -public: - virtual ~Init() = default; - virtual std::unique_ptr makePrinter() { return nullptr; } - virtual std::unique_ptr makeCalculator(std::unique_ptr printer) { return nullptr; } -}; - -#endif // EXAMPLE_INIT_H diff --git a/example/printer.capnp b/example/printer.capnp deleted file mode 100644 index 0f407b771411..000000000000 --- a/example/printer.capnp +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. - -@0x893db95f456ed0e3; - -using Cxx = import "/capnp/c++.capnp"; -using Proxy = import "/mp/proxy.capnp"; - -$Proxy.include("printer.h"); -$Proxy.includeTypes("types.h"); - -interface PrinterInterface $Proxy.wrap("Printer") { - destroy @0 (context :Proxy.Context) -> (); - print @1 (context :Proxy.Context, text: Text) -> (); -} diff --git a/example/printer.cpp b/example/printer.cpp deleted file mode 100644 index 9150d59b5d30..000000000000 --- a/example/printer.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include - -#include -#include // NOLINT(misc-include-cleaner) // IWYU pragma: keep - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class PrinterImpl : public Printer -{ -public: - void print(const std::string& message) override { std::cout << "mpprinter: " << message << std::endl; } -}; - -class InitImpl : public Init -{ -public: - std::unique_ptr makePrinter() override { return std::make_unique(); } -}; - -static void LogPrint(mp::LogMessage log_data) -{ - if (log_data.level == mp::Log::Raise) throw std::runtime_error(log_data.message); - std::ofstream("debug.log", std::ios_base::app) << log_data.message << std::endl; -} - -int main(int argc, char** argv) -{ - if (argc != 2) { - std::cout << "Usage: mpprinter \n"; - return 1; - } - int fd; - if (std::from_chars(argv[1], argv[1] + strlen(argv[1]), fd).ec != std::errc{}) { - std::cerr << argv[1] << " is not a number or is larger than an int\n"; - return 1; - } - mp::EventLoop loop("mpprinter", LogPrint); - std::unique_ptr init = std::make_unique(); - mp::ServeStream(loop, fd, *init); - loop.loop(); - return 0; -} diff --git a/example/printer.h b/example/printer.h deleted file mode 100644 index fbdb35c057ea..000000000000 --- a/example/printer.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef EXAMPLE_PRINTER_H -#define EXAMPLE_PRINTER_H - -#include - -class Printer -{ -public: - virtual ~Printer() = default; - virtual void print(const std::string& message) = 0; -}; - -#endif // EXAMPLE_PRINTER_H diff --git a/example/types.h b/example/types.h deleted file mode 100644 index c926a00b40df..000000000000 --- a/example/types.h +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) The Bitcoin Core developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef EXAMPLE_TYPES_H -#define EXAMPLE_TYPES_H - -#include -#include - -// IWYU pragma: begin_exports -#include -#include -#include -#include -#include -// IWYU pragma: end_exports - -struct InitInterface; // IWYU pragma: export -struct CalculatorInterface; // IWYU pragma: export -struct PrinterInterface; // IWYU pragma: export - -#endif // EXAMPLE_TYPES_H diff --git a/shell.nix b/shell.nix deleted file mode 100644 index 9ebbc0a034e9..000000000000 --- a/shell.nix +++ /dev/null @@ -1,84 +0,0 @@ -{ pkgs ? import {} -, crossPkgs ? import {} -, enableLibcxx ? false # Whether to use libc++ toolchain and libraries instead of libstdc++ -, minimal ? false # Whether to create minimal shell without extra tools (faster when cross compiling) -, capnprotoVersion ? null -, capnprotoSanitizers ? null # Optional sanitizers to build cap'n proto with -, cmakeVersion ? null -, libcxxSanitizers ? null # Optional LLVM_USE_SANITIZER value to use for libc++, see https://llvm.org/docs/CMake.html -}: - -let - lib = pkgs.lib; - llvmBase = crossPkgs.llvmPackages_21; - llvm = llvmBase // lib.optionalAttrs (libcxxSanitizers != null) { - libcxx = llvmBase.libcxx.override { - devExtraCmakeFlags = [ "-DLLVM_USE_SANITIZER=${libcxxSanitizers}" ]; - }; - }; - capnprotoHashes = { - "0.7.0" = "sha256-Y/7dUOQPDHjniuKNRw3j8dG1NI9f/aRWpf8V0WzV9k8="; - "0.7.1" = "sha256-3cBpVmpvCXyqPUXDp12vCFCk32ZXWpkdOliNH37UwWE="; - "0.8.0" = "sha256-rfiqN83begjJ9eYjtr21/tk1GJBjmeVfa3C3dZBJ93w="; - "0.8.1" = "sha256-OZqNVYdyszro5rIe+w6YN00g6y8U/1b8dKYc214q/2o="; - "0.9.0" = "sha256-yhbDcWUe6jp5PbIXzn5EoKabXiWN8lnS08hyfxUgEQ0="; - "0.9.2" = "sha256-BspWOPZcP5nCTvmsDE62Zutox+aY5pw42d6hpH3v4cM="; - "0.10.0" = "sha256-++F4l54OMTDnJ+FO3kV/Y/VLobKVRk461dopanuU3IQ="; - "0.10.4" = "sha256-45sxnVyyYIw9i3sbFZ1naBMoUzkpP21WarzR5crg4X8="; - "1.0.0" = "sha256-NLTFJdeOzqhk4ATvkc17Sh6g/junzqYBBEoXYGH/czo="; - "1.0.2" = "sha256-LVdkqVBTeh8JZ1McdVNtRcnFVwEJRNjt0JV2l7RkuO8="; - "1.1.0" = "sha256-gxkko7LFyJNlxpTS+CWOd/p9x/778/kNIXfpDGiKM2A="; - "1.2.0" = "sha256-aDcn4bLZGq8915/NPPQsN5Jv8FRWd8cAspkG3078psc="; - }; - capnprotoBase = if capnprotoVersion == null then crossPkgs.capnproto else crossPkgs.capnproto.overrideAttrs (old: { - version = capnprotoVersion; - src = crossPkgs.fetchFromGitHub { - owner = "capnproto"; - repo = "capnproto"; - rev = "v${capnprotoVersion}"; - hash = lib.attrByPath [capnprotoVersion] "" capnprotoHashes; - }; - patches = lib.optionals (lib.versionAtLeast capnprotoVersion "0.9.0" && lib.versionOlder capnprotoVersion "0.10.4") [ ./ci/patches/spaceship.patch ]; - } // (lib.optionalAttrs (lib.versionOlder capnprotoVersion "0.10") { - env = { }; # Drop -std=c++20 flag forced by nixpkgs - })); - capnproto = (capnprotoBase.overrideAttrs (old: lib.optionalAttrs (capnprotoSanitizers != null) { - env = (old.env or { }) // { - CXXFLAGS = - lib.concatStringsSep " " [ - (old.env.CXXFLAGS or "") - "-fsanitize=${capnprotoSanitizers}" - "-fno-omit-frame-pointer" - "-g" - ]; - }; - })).override (lib.optionalAttrs enableLibcxx { clangStdenv = llvm.libcxxStdenv; }); - clang = if enableLibcxx then llvm.libcxxClang else llvm.clang; - clang-tools = llvm.clang-tools.override { inherit enableLibcxx; }; - cmakeHashes = { - "3.12.4" = "sha256-UlVYS/0EPrcXViz/iULUcvHA5GecSUHYS6raqbKOMZQ="; - }; - cmakeBuild = if cmakeVersion == null then pkgs.cmake else (pkgs.cmake.overrideAttrs (old: { - version = cmakeVersion; - src = pkgs.fetchurl { - url = "https://cmake.org/files/v${lib.versions.majorMinor cmakeVersion}/cmake-${cmakeVersion}.tar.gz"; - hash = lib.attrByPath [cmakeVersion] "" cmakeHashes; - }; - patches = []; - })).override { isMinimalBuild = true; }; -in crossPkgs.mkShell { - buildInputs = [ - capnproto - ]; - nativeBuildInputs = with pkgs; [ - cmakeBuild - include-what-you-use - ninja - ] ++ lib.optionals (!minimal) [ - clang - clang-tools - ]; - - # Tell IWYU where its libc++ mapping lives - IWYU_MAPPING_FILE = if enableLibcxx then "${llvm.libcxx.dev}/include/c++/v1/libcxx.imp" else null; -} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 1f21ba44ca04..097bc8c5b58d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -29,7 +29,7 @@ if(BUILD_TESTING AND TARGET CapnProto::kj-test) mp/test/spawn_tests.cpp mp/test/test.cpp ) - include(${PROJECT_SOURCE_DIR}/cmake/TargetCapnpSources.cmake) + target_capnp_sources(mptest ${CMAKE_CURRENT_SOURCE_DIR} mp/test/foo.capnp) target_include_directories(mptest PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(mptest PRIVATE CapnProto::kj-test) From 43ea65183bd38eacc5e75c859e690cbe35349d53 Mon Sep 17 00:00:00 2001 From: Sjors Provoost Date: Tue, 12 May 2026 10:08:42 +0200 Subject: [PATCH 4/6] doc: pull libmultiprocess subtree from the 'lib' branch The libmultiprocess upstream now publishes a 'lib' branch produced via 'git subtree split --prefix=lib' of master. The branch contains only the files needed to do a full build (regular and via depends); CI, documentation, README and other upstream-only files are excluded. --- doc/developer-notes.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/developer-notes.md b/doc/developer-notes.md index d838ddff4b04..a05152396835 100644 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -1136,9 +1136,15 @@ To update the subtree: ```sh git fetch libmultiprocess -git subtree pull --prefix=src/ipc/libmultiprocess libmultiprocess master --squash +git subtree pull --prefix=src/ipc/libmultiprocess libmultiprocess lib --squash ``` +The `lib` branch is published by libmultiprocess upstream and contains +only the files needed to do a full build (regular and via `depends`). It +is produced from `master` with `git subtree split --prefix=lib`; CI +scripts, documentation, and other upstream-only files are intentionally +excluded from the subtree. + The ultimate upstream of the few externally managed subtrees are: - src/leveldb From c13d3a4f20c08e529317d24948f5c0f9bfd9de82 Mon Sep 17 00:00:00 2001 From: Sjors Provoost Date: Tue, 12 May 2026 10:10:04 +0200 Subject: [PATCH 5/6] lint: verify split subtrees against upstream master Add a '-s SPLIT_PREFIX' option to test/lint/git-subtree-check.sh that re-runs 'git subtree split --prefix=SPLIT_PREFIX' locally on FETCH_HEAD and confirms the recorded subtree commit is reachable from the result. This catches a malicious upstream publishing a tampered split branch that does not match what 'git subtree split' would produce from master. Register libmultiprocess as a split subtree in lint_repo_hygiene so the default 'lint_subtree' runner fetches upstream master and runs the verification automatically. See script header for the full rationale. --- test/lint/git-subtree-check.sh | 71 ++++++++++++++++++- .../lint/test_runner/src/lint_repo_hygiene.rs | 27 ++++++- test/lint/test_runner/src/util.rs | 32 +++++++++ 3 files changed, 127 insertions(+), 3 deletions(-) diff --git a/test/lint/git-subtree-check.sh b/test/lint/git-subtree-check.sh index 534fadbad710..f704d6e01a12 100755 --- a/test/lint/git-subtree-check.sh +++ b/test/lint/git-subtree-check.sh @@ -2,14 +2,31 @@ # Copyright (c) 2015-present The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. +# +# The default check (no flags) verifies that the subtree directory has not +# been touched outside of a subtree merge. With -r, it additionally verifies +# that the recorded subtree commit exists in the local repository and that +# its tree matches what is checked in (assumes the upstream remote has been +# fetched). +# +# With -s, for subtrees imported from a 'git subtree split' branch (rather +# than upstream master directly), it re-runs the deterministic split locally +# on FETCH_HEAD and confirms the recorded subtree commit is reachable from +# the result. This catches the case where a malicious upstream publishes a +# split branch with contents that don't match what 'git subtree split' would +# produce from master. 'git subtree split' is deterministic and incremental, +# so re-runs are cheap (cached under refs/subtree-cache/) and any honest +# split SHA from past upstream history will still be reachable from a fresh +# split of current master. export LC_ALL=C check_remote=0 -while getopts "?hr" opt; do +split_prefix= +while getopts "?hrs:" opt; do case $opt in '?' | h) - echo "Usage: $0 [-r] DIR [COMMIT]" + echo "Usage: $0 [-r] [-s SPLIT_PREFIX] DIR [COMMIT]" echo " $0 -?" echo "" echo "Checks that a certain prefix is pure subtree, and optionally whether the" @@ -23,11 +40,26 @@ while getopts "?hr" opt; do echo "" echo " git fetch https://github.com/bitcoin-core/secp256k1.git" echo " test/lint/git-subtree-check.sh -r src/secp256k1" + echo "" + echo "-s SPLIT_PREFIX" + echo " For subtrees imported from a 'git subtree split' branch (rather" + echo " than from upstream master directly), verify that the recorded" + echo " subtree commit could have been produced by" + echo " 'git subtree split --prefix=SPLIT_PREFIX' from upstream master." + echo " Implies -r. Requires upstream master to have been fetched into" + echo " FETCH_HEAD immediately before running this script. Example:" + echo "" + echo " git fetch https://github.com/example/foo.git master" + echo " test/lint/git-subtree-check.sh -s lib src/foo" exit 1 ;; r) check_remote=1 ;; + s) + split_prefix="${OPTARG%/}" + check_remote=1 + ;; esac done shift $((OPTIND-1)) @@ -130,4 +162,39 @@ if [ "$check_remote" != "0" ]; then fi fi +if [ -n "$split_prefix" ]; then + # See header comment for rationale. $rev is the subtree commit recorded + # in the latest squash; check that it is reachable from a fresh local + # split of upstream FETCH_HEAD at $split_prefix. + if [ "d$(git cat-file -t FETCH_HEAD 2>/dev/null)" != dcommit ]; then + echo "FETCH_HEAD unavailable: cannot verify split. Did you fetch upstream master?" >&2 + exit 1 + fi + upstream_commit=$(git rev-parse --verify "FETCH_HEAD^{commit}") + echo "verifying $rev was produced by 'git subtree split --prefix=$split_prefix' from FETCH_HEAD ($upstream_commit)" + + if ! split_head=$( + repo_root=$(pwd) + split_worktree=$(mktemp -d "${TMPDIR:-/tmp}/git-subtree-check.XXXXXX") || exit 1 + trap 'git -c safe.directory="$repo_root" worktree remove --force "$split_worktree" >/dev/null 2>&1 || rm -rf "$split_worktree"' EXIT HUP INT TERM + + # git-subtree before 2.54 (commit a606fcdceb) required --prefix to + # exist in the current worktree, even when splitting a different + # revision. Run the split inside a detached worktree at FETCH_HEAD so + # the prefix is always present regardless of the local git version. + git -c safe.directory="$repo_root" worktree add --quiet --detach "$split_worktree" "$upstream_commit" >/dev/null 2>&1 || exit 1 + git -c safe.directory="$repo_root" -c safe.directory="$split_worktree" -C "$split_worktree" subtree split --prefix="$split_prefix" HEAD 2>/dev/null + ); then + echo "FAIL: 'git subtree split --prefix=$split_prefix FETCH_HEAD' failed (does the prefix exist in FETCH_HEAD?)" >&2 + exit 1 + fi + + if ! git merge-base --is-ancestor "$rev" "$split_head"; then + echo "FAIL: subtree commit $rev is not reachable from 'git subtree split --prefix=$split_prefix FETCH_HEAD' ($split_head)" >&2 + echo " The split branch was not honestly produced from upstream master." >&2 + exit 1 + fi + echo "$rev is contained in 'git subtree split --prefix=$split_prefix FETCH_HEAD' ($split_head)" +fi + echo "GOOD" diff --git a/test/lint/test_runner/src/lint_repo_hygiene.rs b/test/lint/test_runner/src/lint_repo_hygiene.rs index d2fc07918daf..ae9b31ace7fd 100644 --- a/test/lint/test_runner/src/lint_repo_hygiene.rs +++ b/test/lint/test_runner/src/lint_repo_hygiene.rs @@ -4,7 +4,7 @@ use std::process::Command; -use crate::util::{commit_range, get_subtrees, LintResult}; +use crate::util::{commit_range, get_split_subtrees, get_subtrees, git, LintResult}; pub fn lint_subtree() -> LintResult { // This only checks that the trees are pure subtrees, it is not doing a full @@ -17,6 +17,31 @@ pub fn lint_subtree() -> LintResult { .expect("command_error") .success(); } + // For subtrees imported from a 'git subtree split' branch, additionally + // verify that the recorded subtree commit could have been produced by + // splitting upstream master at the documented prefix. This requires a + // network fetch into FETCH_HEAD, which git-subtree-check.sh -s reads. + for sub in get_split_subtrees() { + // Fetch the published split branch first so the recorded subtree + // commit exists locally for the implicit '-r' check. Then fetch the + // source branch so FETCH_HEAD points to what should be split. + for fetch_ref in sub + .upstream_split_ref + .into_iter() + .chain(std::iter::once(sub.upstream_ref)) + { + good &= git() + .args(["fetch", "--quiet", sub.upstream_url, fetch_ref]) + .status() + .expect("command_error") + .success(); + } + good &= Command::new("test/lint/git-subtree-check.sh") + .args(["-s", sub.split_prefix, sub.path]) + .status() + .expect("command_error") + .success(); + } if good { Ok(()) } else { diff --git a/test/lint/test_runner/src/util.rs b/test/lint/test_runner/src/util.rs index 11e332e4c5e0..45098726922e 100644 --- a/test/lint/test_runner/src/util.rs +++ b/test/lint/test_runner/src/util.rs @@ -72,6 +72,38 @@ pub fn get_subtrees() -> Vec<&'static str> { ] } +/// Description of a subtree imported via 'git subtree split'. +/// +/// Such subtrees are not pulled directly from upstream master; instead, upstream +/// publishes a 'split' branch produced by 'git subtree split --prefix=' +/// of master, and only that subdirectory is consumed here. To verify that the +/// split branch was honestly produced from master (and not tampered with), the +/// lint runner re-runs the deterministic split locally and confirms the +/// recorded subtree commit is reachable from the result. +pub struct SplitSubtree { + /// Path of the subtree within this repository. + pub path: &'static str, + /// Upstream repository URL to fetch from. + pub upstream_url: &'static str, + /// Branch on the upstream repository to fetch and split. + pub upstream_ref: &'static str, + /// Branch containing the published split history, if different. + pub upstream_split_ref: Option<&'static str>, + /// Prefix passed to 'git subtree split --prefix=' on the upstream side. + pub split_prefix: &'static str, +} + +/// Return all subtrees imported from a 'git subtree split' branch. +pub fn get_split_subtrees() -> Vec { + vec![SplitSubtree { + path: "src/ipc/libmultiprocess", + upstream_url: "https://github.com/bitcoin-core/libmultiprocess.git", + upstream_ref: "master", + upstream_split_ref: Some("lib"), + split_prefix: "lib", + }] +} + /// Return the pathspecs to exclude by default pub fn get_pathspecs_default_excludes() -> Vec { get_subtrees() From 7f2e0a716c0191b28fa8e2f73535b6696d085b71 Mon Sep 17 00:00:00 2001 From: Sjors Provoost Date: Tue, 12 May 2026 13:13:13 +0200 Subject: [PATCH 6/6] [do not merge] lint: point subtree check at Sjors libmultiprocess branch --- test/lint/test_runner/src/util.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/lint/test_runner/src/util.rs b/test/lint/test_runner/src/util.rs index 45098726922e..af1183ba6c30 100644 --- a/test/lint/test_runner/src/util.rs +++ b/test/lint/test_runner/src/util.rs @@ -97,8 +97,10 @@ pub struct SplitSubtree { pub fn get_split_subtrees() -> Vec { vec![SplitSubtree { path: "src/ipc/libmultiprocess", - upstream_url: "https://github.com/bitcoin-core/libmultiprocess.git", - upstream_ref: "master", + // Temporary [do not merge] override for PR branch validation until the + // split `lib` branch is pushed to bitcoin-core/libmultiprocess. + upstream_url: "https://github.com/Sjors/libmultiprocess.git", + upstream_ref: "2026/05/subtree-split", upstream_split_ref: Some("lib"), split_prefix: "lib", }]