diff --git a/flake.lock b/flake.lock index 33af6ad86..848ce9d57 100644 --- a/flake.lock +++ b/flake.lock @@ -108,11 +108,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1758391731, - "narHash": "sha256-UuwQoPWv13DVKMveeev+F0OC/N95AOmAz6SzCuGhxjQ=", + "lastModified": 1757198069, + "narHash": "sha256-m3VUcOD4rTs8J7S+3dOjWMrAjw6RcITC3XYQ98zhEFs=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "3f00d36f15e16e0471d9ca1e8f88958941fa970a", + "rev": "0747026fc57ecb9c28901c7f7a2b5dc40e8af43c", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 58a699a28..97aea25f9 100644 --- a/flake.nix +++ b/flake.nix @@ -260,6 +260,15 @@ nativeBuildInputs = prevAttrs.nativeBuildInputs ++ [ final.buildPackages.bmake ]; postInstall = lib.replaceStrings [ "lowdown.so.1" ] [ "lowdown.so.2" ] prevAttrs.postInstall; }); + + capnproto = prev.capnproto.overrideAttrs (old: { + patches = old.patches or [ ] ++ [ + # backport of https://github.com/capnproto/capnproto/pull/1810 + ./misc/capnproto-promise-nodiscard.patch + # backport of https://github.com/capnproto/capnproto/pull/2296 + ./misc/capnproto-monotonic-clocks-are-a-lie.patch + ]; + }); }; in { diff --git a/misc/capnproto-monotonic-clocks-are-a-lie.patch b/misc/capnproto-monotonic-clocks-are-a-lie.patch new file mode 100644 index 000000000..ddf5052e1 --- /dev/null +++ b/misc/capnproto-monotonic-clocks-are-a-lie.patch @@ -0,0 +1,47 @@ +From 11375442cf591f055ca95902f27c68b0e983d371 Mon Sep 17 00:00:00 2001 +From: Fabio Rossetto +Date: Thu, 8 May 2025 18:18:10 +0200 +Subject: [PATCH] Remove check for monotonic time + +The check was disabled on Mac, but in #2261 it was reported also on +Linux. At this point, it makes more sense to remove the KJ_REQUIRE for +monotonicity alltogether. + +Backport of the original PR #2296 to v1.0.2. + +Signed-off-by: Raito Bezarius +Co-authored-by: Raito Bezarius +--- + c++/src/kj/timer.c++ | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + +diff --git a/c++/src/kj/timer.c++ b/c++/src/kj/timer.c++ +index e5cd2648..a659e5d0 100644 +--- a/c++/src/kj/timer.c++ ++++ b/c++/src/kj/timer.c++ +@@ -110,16 +110,13 @@ Maybe TimerImpl::timeoutToNextEvent(TimePoint start, Duration unit, ui + } + + void TimerImpl::advanceTo(TimePoint newTime) { +- // On Macs, it has been observed that clock_gettime +- // may return non monotonic time, even when CLOCK_MONOTONIC is used. +- // This workaround is to avoid the assert triggering if this happens. +- // See also https://github.com/capnproto/capnproto/issues/1693 +-#if __APPLE__ ++ // It has been observed that clock_gettime may return non monotonic time, ++ // even when CLOCK_MONOTONIC is used. ++ // We use std::max to guard against this rare issue. ++ // - on Mac: https://github.com/capnproto/capnproto/issues/1693 ++ // - on Linux: https://github.com/capnproto/capnproto/issues/2261 ++ + time = std::max(time, newTime); +-#else +- KJ_REQUIRE(newTime >= time, "can't advance backwards in time") { return; } +- time = newTime; +-#endif + + for (;;) { + auto front = impl->timers.begin(); +-- +2.49.0 + diff --git a/misc/capnproto-promise-nodiscard.patch b/misc/capnproto-promise-nodiscard.patch new file mode 100644 index 000000000..b361f7038 --- /dev/null +++ b/misc/capnproto-promise-nodiscard.patch @@ -0,0 +1,194 @@ +diff --git a/c++/src/kj/array.h b/c++/src/kj/array.h +index 3932f9f4..677c691a 100644 +--- a/c++/src/kj/array.h ++++ b/c++/src/kj/array.h +@@ -780,7 +780,7 @@ struct CopyConstructArray_ { + + static T* apply(T* __restrict__ pos, Iterator start, Iterator end) { + // Verify that T can be *implicitly* constructed from the source values. +- if (false) implicitCast(kj::mv(*start)); ++ if (false) (void)implicitCast(kj::mv(*start)); + + if (noexcept(T(kj::mv(*start)))) { + while (start != end) { +diff --git a/c++/src/kj/async-coroutine-test.c++ b/c++/src/kj/async-coroutine-test.c++ +index de767eca..d6ed1359 100644 +--- a/c++/src/kj/async-coroutine-test.c++ ++++ b/c++/src/kj/async-coroutine-test.c++ +@@ -288,5 +288,5 @@ KJ_TEST("Exceptions during suspended coroutine frame-unwind propagate via destru + WaitScope waitScope(loop); + + auto exception = KJ_ASSERT_NONNULL(kj::runCatchingExceptions([&]() { +- deferredThrowCoroutine(kj::NEVER_DONE); ++ (void)deferredThrowCoroutine(kj::NEVER_DONE); + })); + + KJ_EXPECT(exception.getDescription() == "thrown during unwind"); +diff --git a/c++/src/kj/async-io-test.c++ b/c++/src/kj/async-io-test.c++ +index e8892b79..dffcbb26 100644 +--- a/c++/src/kj/async-io-test.c++ ++++ b/c++/src/kj/async-io-test.c++ +@@ -1577,7 +1577,7 @@ KJ_TEST("Userland pipe pump into zero-limited pipe, no data to pump") { + auto pipe2 = newOneWayPipe(uint64_t(0)); + auto pumpPromise = KJ_ASSERT_NONNULL(pipe2.out->tryPumpFrom(*pipe.in)); + +- expectRead(*pipe2.in, ""); ++ expectRead(*pipe2.in, "").wait(ws); + pipe.out = nullptr; + KJ_EXPECT(pumpPromise.wait(ws) == 0); + } +@@ -1590,7 +1590,7 @@ KJ_TEST("Userland pipe pump into zero-limited pipe, data is pumped") { + auto pipe2 = newOneWayPipe(uint64_t(0)); + auto pumpPromise = KJ_ASSERT_NONNULL(pipe2.out->tryPumpFrom(*pipe.in)); + +- expectRead(*pipe2.in, ""); ++ expectRead(*pipe2.in, "").wait(ws); + auto writePromise = pipe.out->write("foo", 3); + KJ_EXPECT_THROW_RECOVERABLE_MESSAGE("abortRead() has been called", pumpPromise.wait(ws)); + } +diff --git a/c++/src/kj/async.h b/c++/src/kj/async.h +index 564b5171..d4f2d55c 100644 +--- a/c++/src/kj/async.h ++++ b/c++/src/kj/async.h +@@ -118,7 +118,7 @@ private: + // Promises + + template +-class Promise: protected _::PromiseBase { ++class [[nodiscard]] Promise: protected _::PromiseBase { + // The basic primitive of asynchronous computation in KJ. Similar to "futures", but designed + // specifically for event loop concurrency. Similar to E promises and JavaScript Promises/A. + // +diff --git a/c++/src/kj/common-test.c++ b/c++/src/kj/common-test.c++ +index 97856125..913a6be4 100644 +--- a/c++/src/kj/common-test.c++ ++++ b/c++/src/kj/common-test.c++ +@@ -573,7 +573,7 @@ TEST(Common, Downcast) { + + EXPECT_EQ(&bar, &downcast(foo)); + #if defined(KJ_DEBUG) && !KJ_NO_RTTI +- KJ_EXPECT_THROW_MESSAGE("Value cannot be downcast", downcast(foo)); ++ KJ_EXPECT_THROW_MESSAGE("Value cannot be downcast", (void)downcast(foo)); + #endif + + #if KJ_NO_RTTI +diff --git a/c++/src/kj/compat/http-test.c++ b/c++/src/kj/compat/http-test.c++ +index f10ff8d1..9003099d 100644 +--- a/c++/src/kj/compat/http-test.c++ ++++ b/c++/src/kj/compat/http-test.c++ +@@ -6553,7 +6553,7 @@ KJ_TEST("Simple CONNECT Server works") { + "\r\n" + "hello"_kj).wait(waitScope); + +- expectEnd(*pipe.ends[1]); ++ expectEnd(*pipe.ends[1]).wait(waitScope); + + listenTask.wait(waitScope); + +@@ -6628,7 +6628,7 @@ KJ_TEST("CONNECT Server (201 status)") { + "\r\n" + "hello"_kj).wait(waitScope); + +- expectEnd(*pipe.ends[1]); ++ expectEnd(*pipe.ends[1]).wait(waitScope); + + listenTask.wait(waitScope); + +@@ -6706,7 +6706,7 @@ KJ_TEST("CONNECT Server rejected") { + "\r\n" + "boom"_kj).wait(waitScope); + +- expectEnd(*pipe.ends[1]); ++ expectEnd(*pipe.ends[1]).wait(waitScope); + + listenTask.wait(waitScope); + +@@ -6774,7 +6774,7 @@ KJ_TEST("CONNECT Server cancels read") { + "HTTP/1.1 200 OK\r\n" + "\r\n"_kj).wait(waitScope); + +- expectEnd(*pipe.ends[1]); ++ expectEnd(*pipe.ends[1]).wait(waitScope); + + listenTask.wait(waitScope); + } +@@ -6840,7 +6840,7 @@ KJ_TEST("CONNECT Server cancels write") { + "HTTP/1.1 200 OK\r\n" + "\r\n"_kj).wait(waitScope); + +- expectEnd(*pipe.ends[1]); ++ expectEnd(*pipe.ends[1]).wait(waitScope); + + listenTask.wait(waitScope); + } +@@ -6913,7 +6913,7 @@ KJ_TEST("CONNECT rejects Transfer-Encoding") { + "\r\n" + "ERROR: Bad Request"_kj).wait(waitScope); + +- expectEnd(*pipe.ends[1]); ++ expectEnd(*pipe.ends[1]).wait(waitScope); + + listenTask.wait(waitScope); + } +@@ -6947,7 +6947,7 @@ KJ_TEST("CONNECT rejects Content-Length") { + "\r\n" + "ERROR: Bad Request"_kj).wait(waitScope); + +- expectEnd(*pipe.ends[1]); ++ expectEnd(*pipe.ends[1]).wait(waitScope); + + listenTask.wait(waitScope); + } +diff --git a/c++/src/kj/compat/tls-test.c++ b/c++/src/kj/compat/tls-test.c++ +index dddefa57..52ccc68a 100644 +--- a/c++/src/kj/compat/tls-test.c++ ++++ b/c++/src/kj/compat/tls-test.c++ +@@ -1037,15 +1037,15 @@ KJ_TEST("TLS receiver experiences pre-TLS error") { + TlsReceiverTest test; + + KJ_LOG(INFO, "Accepting before a bad connect"); +- auto promise = test.receiver->accept(); ++ auto acceptPromise = test.receiver->accept(); + + KJ_LOG(INFO, "Disappointing our server"); +- test.baseReceiver->badConnect(); ++ auto connectPromise = test.baseReceiver->badConnect(); + + // Can't use KJ_EXPECT_THROW_RECOVERABLE_MESSAGE because wait() that returns a value can't throw + // recoverable exceptions. Can't use KJ_EXPECT_THROW_MESSAGE because non-recoverable exceptions + // will fork() in -fno-exception which screws up our state. +- promise.then([](auto) { ++ acceptPromise.then([](auto) { + KJ_FAIL_EXPECT("expected exception"); + }, [](kj::Exception&& e) { + KJ_EXPECT(e.getDescription() == "Pipes are leaky"); +diff --git a/c++/src/kj/test.h b/c++/src/kj/test.h +index 5acbb00d..de5efec2 100644 +--- a/c++/src/kj/test.h ++++ b/c++/src/kj/test.h +@@ -92,6 +92,7 @@ private: + else KJ_FAIL_EXPECT("failed: expected " #cond, _kjCondition, ##__VA_ARGS__) + #endif + ++// TODO(msvc): cast results to void like non-MSVC versions do + #if _MSC_VER && !defined(__clang__) + #define KJ_EXPECT_THROW_RECOVERABLE(type, code, ...) \ + do { \ +@@ -115,7 +116,7 @@ private: + #else + #define KJ_EXPECT_THROW_RECOVERABLE(type, code, ...) \ + do { \ +- KJ_IF_MAYBE(e, ::kj::runCatchingExceptions([&]() { code; })) { \ ++ KJ_IF_MAYBE(e, ::kj::runCatchingExceptions([&]() { (void)({code}); })) { \ + KJ_EXPECT(e->getType() == ::kj::Exception::Type::type, \ + "code threw wrong exception type: " #code, *e, ##__VA_ARGS__); \ + } else { \ +@@ -125,7 +126,7 @@ private: + + #define KJ_EXPECT_THROW_RECOVERABLE_MESSAGE(message, code, ...) \ + do { \ +- KJ_IF_MAYBE(e, ::kj::runCatchingExceptions([&]() { code; })) { \ ++ KJ_IF_MAYBE(e, ::kj::runCatchingExceptions([&]() { (void)({code}); })) { \ + KJ_EXPECT(::kj::_::hasSubstring(e->getDescription(), message), \ + "exception description didn't contain expected substring", *e, ##__VA_ARGS__); \ + } else { \