Skip to content

Commit 8db8bf0

Browse files
committed
Merge bitcoin-core/libmultiprocess#231 (Add windows support)
2 parents 7993dbe + f237632 commit 8db8bf0

19 files changed

Lines changed: 517 additions & 152 deletions

File tree

src/ipc/libmultiprocess/.github/workflows/bitcoin-core-ci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ concurrency:
1818

1919
env:
2020
BITCOIN_REPO: bitcoin/bitcoin
21+
# Temporary: use PR #35084 until it merges; revert to refs/heads/master after
22+
BITCOIN_CORE_REF: refs/pull/35084/merge
2123
LLVM_VERSION: 22
2224
LIBCXX_DIR: /tmp/libcxx-build/
2325

@@ -79,6 +81,7 @@ jobs:
7981
uses: actions/checkout@v4
8082
with:
8183
repository: ${{ env.BITCOIN_REPO }}
84+
ref: ${{ env.BITCOIN_CORE_REF }}
8285
fetch-depth: 1
8386

8487
- name: Checkout libmultiprocess
@@ -195,6 +198,7 @@ jobs:
195198
uses: actions/checkout@v4
196199
with:
197200
repository: ${{ env.BITCOIN_REPO }}
201+
ref: ${{ env.BITCOIN_CORE_REF }}
198202
fetch-depth: 1
199203

200204
- name: Checkout libmultiprocess

src/ipc/libmultiprocess/CMakeLists.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ endif()
1313
include("cmake/compat_find.cmake")
1414

1515
find_package(Threads REQUIRED)
16-
find_package(CapnProto 0.7 QUIET NO_MODULE)
16+
find_package(CapnProto 0.9 QUIET NO_MODULE)
1717
if(NOT CapnProto_FOUND)
1818
message(FATAL_ERROR
1919
"Cap'n Proto is required but was not found.\n"
@@ -203,6 +203,10 @@ target_link_libraries(mpgen PRIVATE CapnProto::capnp-rpc)
203203
target_link_libraries(mpgen PRIVATE CapnProto::capnpc)
204204
target_link_libraries(mpgen PRIVATE CapnProto::kj)
205205
target_link_libraries(mpgen PRIVATE Threads::Threads)
206+
target_compile_definitions(mpgen PRIVATE
207+
"CAPNP_EXECUTABLE=\"$<TARGET_FILE:CapnProto::capnp_tool>\""
208+
"CAPNPC_CXX_EXECUTABLE=\"$<TARGET_FILE:CapnProto::capnpc_cpp>\""
209+
"CAPNP_INCLUDE_DIRS=\"${CAPNP_INCLUDE_DIRS}\"")
206210
set_target_properties(mpgen PROPERTIES
207211
INSTALL_RPATH_USE_LINK_PATH TRUE)
208212
set_target_properties(mpgen PROPERTIES
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
CI_DESC="CI job using old Cap'n Proto and cmake versions"
22
CI_DIR=build-olddeps
33
export CXXFLAGS="-Werror -Wall -Wextra -Wpedantic -Wno-unused-parameter -Wno-error=array-bounds"
4-
NIX_ARGS=(--argstr capnprotoVersion "0.7.1" --argstr cmakeVersion "3.12.4")
4+
NIX_ARGS=(--argstr capnprotoVersion "0.9.2" --argstr cmakeVersion "3.12.4")
55
BUILD_ARGS=(-k)

src/ipc/libmultiprocess/cmake/compat_config.cmake

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,75 @@ if (NOT DEFINED capnp_PREFIX AND DEFINED CAPNP_INCLUDE_DIRS)
1212
get_filename_component(capnp_PREFIX "${CAPNP_INCLUDE_DIRS}" DIRECTORY)
1313
endif()
1414

15+
if (NOT DEFINED CAPNP_INCLUDE_DIRS AND DEFINED capnp_PREFIX)
16+
set(CAPNP_INCLUDE_DIRS "${capnp_PREFIX}/include")
17+
endif()
18+
19+
if (NOT TARGET CapnProto::capnp_tool)
20+
if (DEFINED CAPNP_EXECUTABLE)
21+
add_executable(CapnProto::capnp_tool IMPORTED GLOBAL)
22+
set_target_properties(CapnProto::capnp_tool PROPERTIES IMPORTED_LOCATION "${CAPNP_EXECUTABLE}")
23+
elseif (DEFINED capnp_PREFIX)
24+
add_executable(CapnProto::capnp_tool IMPORTED GLOBAL)
25+
set_target_properties(CapnProto::capnp_tool PROPERTIES IMPORTED_LOCATION "${capnp_PREFIX}/bin/capnp")
26+
endif()
27+
endif()
28+
29+
if (NOT TARGET CapnProto::capnpc_cpp)
30+
if (DEFINED CAPNPC_CXX_EXECUTABLE)
31+
add_executable(CapnProto::capnpc_cpp IMPORTED GLOBAL)
32+
set_target_properties(CapnProto::capnpc_cpp PROPERTIES IMPORTED_LOCATION "${CAPNPC_CXX_EXECUTABLE}")
33+
elseif (DEFINED capnp_PREFIX)
34+
add_executable(CapnProto::capnpc_cpp IMPORTED GLOBAL)
35+
set_target_properties(CapnProto::capnpc_cpp PROPERTIES IMPORTED_LOCATION "${capnp_PREFIX}/bin/capnpc-c++")
36+
endif()
37+
endif()
38+
39+
# Validate CapnProto tool target locations and fix if broken.
40+
# Some packaged capnproto versions (e.g., Ubuntu Noble libcapnp-dev 1.0.1)
41+
# have incorrect IMPORTED_LOCATION paths due to a packaging bug where the cmake
42+
# config file is installed under /usr/lib/.../cmake/ but the _IMPORT_PREFIX
43+
# calculation goes up too few directory levels, yielding /usr/lib/bin/capnp
44+
# instead of the correct /usr/bin/capnp.
45+
foreach(_mp_tool IN ITEMS capnp_tool capnpc_cpp)
46+
if (TARGET "CapnProto::${_mp_tool}")
47+
get_target_property(_mp_configs "CapnProto::${_mp_tool}" IMPORTED_CONFIGURATIONS)
48+
set(_mp_valid FALSE)
49+
foreach(_mp_cfg IN LISTS _mp_configs)
50+
get_target_property(_mp_loc "CapnProto::${_mp_tool}" "IMPORTED_LOCATION_${_mp_cfg}")
51+
if (EXISTS "${_mp_loc}")
52+
set(_mp_valid TRUE)
53+
break()
54+
endif()
55+
endforeach()
56+
if (NOT _mp_valid)
57+
get_target_property(_mp_loc "CapnProto::${_mp_tool}" IMPORTED_LOCATION)
58+
if (EXISTS "${_mp_loc}")
59+
set(_mp_valid TRUE)
60+
endif()
61+
endif()
62+
if (NOT _mp_valid)
63+
if ("${_mp_tool}" STREQUAL "capnp_tool")
64+
find_program(_mp_fixed capnp HINTS "${capnp_PREFIX}/bin")
65+
else()
66+
find_program(_mp_fixed capnpc-c++ HINTS "${capnp_PREFIX}/bin")
67+
endif()
68+
if (_mp_fixed)
69+
foreach(_mp_cfg IN LISTS _mp_configs)
70+
set_target_properties("CapnProto::${_mp_tool}" PROPERTIES "IMPORTED_LOCATION_${_mp_cfg}" "${_mp_fixed}")
71+
endforeach()
72+
set_target_properties("CapnProto::${_mp_tool}" PROPERTIES IMPORTED_LOCATION "${_mp_fixed}")
73+
endif()
74+
unset(_mp_fixed CACHE)
75+
endif()
76+
endif()
77+
endforeach()
78+
unset(_mp_tool)
79+
unset(_mp_configs)
80+
unset(_mp_valid)
81+
unset(_mp_cfg)
82+
unset(_mp_loc)
83+
1584
if (NOT DEFINED CAPNPC_OUTPUT_DIR)
1685
set(CAPNPC_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
1786
endif()

src/ipc/libmultiprocess/doc/design.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ sequenceDiagram
120120
participant PMT as ProxyMethodTraits
121121
participant Impl as Actual C++ Method
122122
123-
serverInvoke->>SF1: SF1::invoke
123+
serverInvoke->>SF1: SF1::invoke
124124
SF1->>SF2: SF2::invoke
125125
SF2->>SR: SR::invoke
126126
SR->>SC: SC::invoke
@@ -165,7 +165,7 @@ Thread mapping enables each client thread to have a dedicated server thread proc
165165
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.
166166

167167
```capnp
168-
interface InitInterface $Proxy.wrap("Init") {
168+
interface InitInterface $Proxy.wrap("Init") {
169169
construct @0 (threadMap: Proxy.ThreadMap) -> (threadMap :Proxy.ThreadMap);
170170
}
171171
```

src/ipc/libmultiprocess/doc/versions.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,17 @@ Library versions are tracked with simple
77
Versioning policy is described in the [version.h](../include/mp/version.h)
88
include.
99

10-
## v10
10+
## v12
1111
- Current unstable version.
12+
- Adds support for nonunix platforms, making API changes that are not backwards compatible.
13+
14+
## [v11.0](https://github.com/bitcoin-core/libmultiprocess/commits/v11.0)
15+
- Improves debug output if EventLoop::post callback fails.
16+
17+
## [v10.0](https://github.com/bitcoin-core/libmultiprocess/commits/v10.0)
18+
- Increases spawn test timeout to avoid spurious failures.
19+
- Uses `throwRecoverableException` instead of raw `throw` to improve runtime error messages in macOS builds.
20+
- 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).
1221

1322
## [v9.0](https://github.com/bitcoin-core/libmultiprocess/commits/v9.0)
1423
- 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.

src/ipc/libmultiprocess/example/calculator.cpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
#include <init.capnp.h>
77
#include <init.capnp.proxy.h> // NOLINT(misc-include-cleaner) // IWYU pragma: keep
88

9-
#include <charconv>
10-
#include <cstring>
9+
#include <cstring> // IWYU pragma: keep
1110
#include <fstream>
1211
#include <functional>
1312
#include <iostream>
@@ -16,9 +15,9 @@
1615
#include <kj/memory.h>
1716
#include <memory>
1817
#include <mp/proxy-io.h>
18+
#include <mp/util.h>
1919
#include <stdexcept>
2020
#include <string>
21-
#include <system_error>
2221
#include <utility>
2322

2423
class CalculatorImpl : public Calculator
@@ -51,14 +50,10 @@ int main(int argc, char** argv)
5150
std::cout << "Usage: mpcalculator <fd>\n";
5251
return 1;
5352
}
54-
int fd;
55-
if (std::from_chars(argv[1], argv[1] + strlen(argv[1]), fd).ec != std::errc{}) {
56-
std::cerr << argv[1] << " is not a number or is larger than an int\n";
57-
return 1;
58-
}
53+
mp::SocketId socket{mp::StartSpawned(argv[1])};
5954
mp::EventLoop loop("mpcalculator", LogPrint);
6055
std::unique_ptr<Init> init = std::make_unique<InitImpl>();
61-
mp::ServeStream<InitInterface>(loop, fd, *init);
56+
mp::ServeStream<InitInterface>(loop, mp::MakeStream(loop.m_io_context, socket), *init);
6257
loop.loop();
6358
return 0;
6459
}

src/ipc/libmultiprocess/example/example.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,20 @@
1919
#include <string>
2020
#include <thread>
2121
#include <tuple>
22+
#include <utility>
2223
#include <vector>
2324

2425
namespace fs = std::filesystem;
2526

2627
static auto Spawn(mp::EventLoop& loop, const std::string& process_argv0, const std::string& new_exe_name)
2728
{
28-
int pid;
29-
const int fd = mp::SpawnProcess(pid, [&](int fd) -> std::vector<std::string> {
29+
const auto [pid, socket] = mp::SpawnProcess([&](mp::ConnectInfo info) -> std::vector<std::string> {
3030
fs::path path = process_argv0;
3131
path.remove_filename();
3232
path.append(new_exe_name);
33-
return {path.string(), std::to_string(fd)};
33+
return {path.string(), std::move(info)};
3434
});
35-
return std::make_tuple(mp::ConnectStream<InitInterface>(loop, fd), pid);
35+
return std::make_tuple(mp::ConnectStream<InitInterface>(loop, mp::MakeStream(loop.m_io_context, socket)), pid);
3636
}
3737

3838
static void LogPrint(mp::LogMessage log_data)

src/ipc/libmultiprocess/example/printer.cpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,17 @@
77
#include <init.capnp.h>
88
#include <init.capnp.proxy.h> // NOLINT(misc-include-cleaner) // IWYU pragma: keep
99

10-
#include <charconv>
11-
#include <cstring>
10+
#include <cstring> // IWYU pragma: keep
1211
#include <fstream>
1312
#include <iostream>
1413
#include <kj/async.h>
1514
#include <kj/common.h>
1615
#include <kj/memory.h>
1716
#include <memory>
1817
#include <mp/proxy-io.h>
18+
#include <mp/util.h>
1919
#include <stdexcept>
2020
#include <string>
21-
#include <system_error>
2221

2322
class PrinterImpl : public Printer
2423
{
@@ -44,14 +43,10 @@ int main(int argc, char** argv)
4443
std::cout << "Usage: mpprinter <fd>\n";
4544
return 1;
4645
}
47-
int fd;
48-
if (std::from_chars(argv[1], argv[1] + strlen(argv[1]), fd).ec != std::errc{}) {
49-
std::cerr << argv[1] << " is not a number or is larger than an int\n";
50-
return 1;
51-
}
46+
mp::SocketId socket{mp::StartSpawned(argv[1])};
5247
mp::EventLoop loop("mpprinter", LogPrint);
5348
std::unique_ptr<Init> init = std::make_unique<InitImpl>();
54-
mp::ServeStream<InitInterface>(loop, fd, *init);
49+
mp::ServeStream<InitInterface>(loop, mp::MakeStream(loop.m_io_context, socket), *init);
5550
loop.loop();
5651
return 0;
5752
}

src/ipc/libmultiprocess/include/mp/config.h.in

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
#define MP_CONFIG_H
77

88
#cmakedefine CMAKE_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@"
9-
#cmakedefine capnp_PREFIX "@capnp_PREFIX@"
109
#cmakedefine HAVE_KJ_FILESYSTEM
1110

1211
#cmakedefine HAVE_PTHREAD_GETNAME_NP @HAVE_PTHREAD_GETNAME_NP@

0 commit comments

Comments
 (0)