diff --git a/builtin-functions/kphp-light/stdlib/fork-functions.txt b/builtin-functions/kphp-light/stdlib/fork-functions.txt index 059ea024c3..2c4891d3d7 100644 --- a/builtin-functions/kphp-light/stdlib/fork-functions.txt +++ b/builtin-functions/kphp-light/stdlib/fork-functions.txt @@ -9,6 +9,9 @@ function get_running_fork_id() ::: future ; /** @kphp-extern-func-info can_throw interruptible cpp_template_call */ function wait(future | false $id, float $timeout = -1.0) ::: ^1[*] | null; +/** @kphp-extern-func-info can_throw interruptible cpp_template_call */ +function wait_synchronously (future | false $id) ::: ^1[*] | null; + /** @kphp-extern-func-info interruptible */ function wait_concurrently ($id ::: future): bool; diff --git a/runtime-light/stdlib/fork/fork-functions.h b/runtime-light/stdlib/fork/fork-functions.h index 01eb3658c3..fd2c4de625 100644 --- a/runtime-light/stdlib/fork/fork-functions.h +++ b/runtime-light/stdlib/fork/fork-functions.h @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -73,7 +74,8 @@ auto wait(int64_t fork_id, duration_type timeout) noexcept -> kphp::coro::task {}", fork_id); + // TODO: uncomment this warning after we stabilize K2 + // kphp::log::warning("fork does not exist or has already been awaited by another fork: id -> {}", fork_id); co_return std::nullopt; } @@ -122,18 +124,29 @@ auto wait(int64_t fork_id, duration_type timeout) noexcept -> kphp::coro::task -requires(is_optional::value || std::same_as || is_class_instance::value) -kphp::coro::task f$wait(int64_t fork_id, double timeout = -1.0) noexcept { - auto opt_result{co_await kphp::forks::id_managed( - kphp::forks::wait(fork_id, std::chrono::duration_cast(std::chrono::duration{timeout})))}; - co_return opt_result ? T{*std::move(opt_result)} : T{}; +template +requires(is_optional::value || std::same_as || is_class_instance::value) +kphp::coro::task f$wait(int64_t fork_id, double timeout = -1.0) noexcept { + auto opt_result{co_await kphp::forks::id_managed(kphp::forks::wait(fork_id, std::chrono::duration{timeout}))}; + co_return opt_result ? return_type{*std::move(opt_result)} : return_type{}; } -template -requires(is_optional::value || std::same_as || is_class_instance::value) -kphp::coro::task f$wait(Optional opt_fork_id, double timeout = -1.0) noexcept { - co_return co_await f$wait(opt_fork_id.has_value() ? opt_fork_id.val() : kphp::forks::INVALID_ID, timeout); +template +requires(is_optional::value || std::same_as || is_class_instance::value) +kphp::coro::task f$wait(Optional opt_fork_id, double timeout = -1.0) noexcept { + co_return co_await f$wait(opt_fork_id.has_value() ? opt_fork_id.val() : kphp::forks::INVALID_ID, timeout); +} + +template +requires(is_optional::value || std::same_as || is_class_instance::value) +kphp::coro::task f$wait_synchronously(int64_t fork_id) noexcept { + co_return co_await f$wait(fork_id); +} + +template +requires(is_optional::value || std::same_as || is_class_instance::value) +kphp::coro::task f$wait_synchronously(Optional opt_fork_id) noexcept { + co_return co_await f$wait(opt_fork_id); } // ================================================================================================ diff --git a/runtime-light/stdlib/fork/fork-state.h b/runtime-light/stdlib/fork/fork-state.h index fc9f64e703..d98eddccb5 100644 --- a/runtime-light/stdlib/fork/fork-state.h +++ b/runtime-light/stdlib/fork/fork-state.h @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -35,7 +36,7 @@ struct ForkInstanceState final : private vk::not_copyable { }; private: - static constexpr int64_t FORK_ID_INIT = 0; + static constexpr auto FORK_ID_INIT{std::numeric_limits::max()}; int64_t next_fork_id{FORK_ID_INIT}; // type erased tasks that represent forks @@ -64,7 +65,7 @@ struct ForkInstanceState final : private vk::not_copyable { co_return s; }}; - const int64_t fork_id{next_fork_id++}; + const int64_t fork_id{next_fork_id--}; auto fork_task{std::invoke(fork_coroutine, std::move(task), fork_id)}; forks.emplace( fork_id, diff --git a/tests/phpt/fork/001_basic.php b/tests/phpt/fork/001_basic.php index 99b6e9e19b..82a687de7d 100644 --- a/tests/phpt/fork/001_basic.php +++ b/tests/phpt/fork/001_basic.php @@ -88,7 +88,7 @@ function hash4($n) { return $q; } - +wait(false); $id2 = fork(hash2(10)); $id = fork(hash3(10)); diff --git a/tests/phpt/fork/012_exceptions.php b/tests/phpt/fork/012_exceptions.php index 18ea4aef1c..934b9edb2c 100644 --- a/tests/phpt/fork/012_exceptions.php +++ b/tests/phpt/fork/012_exceptions.php @@ -1,4 +1,4 @@ -@ok k2_skip +@ok