Skip to content

Commit 5f67d23

Browse files
authored
[k2] fix wait (#1618)
* fix: wait(false) resulted in call to wait(0). was an ID of a main fork * add wait_synchronously * enable more fork tests
1 parent 77e8739 commit 5f67d23

6 files changed

Lines changed: 33 additions & 16 deletions

File tree

builtin-functions/kphp-light/stdlib/fork-functions.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ function get_running_fork_id() ::: future <void>;
99
/** @kphp-extern-func-info can_throw interruptible cpp_template_call */
1010
function wait(future<any> | false $id, float $timeout = -1.0) ::: ^1[*] | null;
1111

12+
/** @kphp-extern-func-info can_throw interruptible cpp_template_call */
13+
function wait_synchronously (future<any> | false $id) ::: ^1[*] | null;
14+
1215
/** @kphp-extern-func-info interruptible */
1316
function wait_concurrently ($id ::: future<any>): bool;
1417

runtime-light/stdlib/fork/fork-functions.h

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <algorithm>
88
#include <chrono>
9+
#include <concepts>
910
#include <cstdint>
1011
#include <functional>
1112
#include <optional>
@@ -73,7 +74,8 @@ auto wait(int64_t fork_id, duration_type timeout) noexcept -> kphp::coro::task<s
7374
auto& fork_instance_st{ForkInstanceState::get()};
7475
auto opt_info{fork_instance_st.get_info(fork_id)};
7576
if (!opt_info || !(*opt_info).get().opt_handle || (*opt_info).get().awaited) [[unlikely]] {
76-
kphp::log::warning("fork does not exist or has already been awaited by another fork: id -> {}", fork_id);
77+
// TODO: uncomment this warning after we stabilize K2
78+
// kphp::log::warning("fork does not exist or has already been awaited by another fork: id -> {}", fork_id);
7779
co_return std::nullopt;
7880
}
7981

@@ -122,18 +124,29 @@ auto wait(int64_t fork_id, duration_type timeout) noexcept -> kphp::coro::task<s
122124

123125
} // namespace kphp::forks
124126

125-
template<typename T>
126-
requires(is_optional<T>::value || std::same_as<T, mixed> || is_class_instance<T>::value)
127-
kphp::coro::task<T> f$wait(int64_t fork_id, double timeout = -1.0) noexcept {
128-
auto opt_result{co_await kphp::forks::id_managed(
129-
kphp::forks::wait<T>(fork_id, std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::duration<double>{timeout})))};
130-
co_return opt_result ? T{*std::move(opt_result)} : T{};
127+
template<std::default_initializable return_type>
128+
requires(is_optional<return_type>::value || std::same_as<return_type, mixed> || is_class_instance<return_type>::value)
129+
kphp::coro::task<return_type> f$wait(int64_t fork_id, double timeout = -1.0) noexcept {
130+
auto opt_result{co_await kphp::forks::id_managed(kphp::forks::wait<return_type>(fork_id, std::chrono::duration<double>{timeout}))};
131+
co_return opt_result ? return_type{*std::move(opt_result)} : return_type{};
131132
}
132133

133-
template<typename T>
134-
requires(is_optional<T>::value || std::same_as<T, mixed> || is_class_instance<T>::value)
135-
kphp::coro::task<T> f$wait(Optional<int64_t> opt_fork_id, double timeout = -1.0) noexcept {
136-
co_return co_await f$wait<T>(opt_fork_id.has_value() ? opt_fork_id.val() : kphp::forks::INVALID_ID, timeout);
134+
template<typename return_type>
135+
requires(is_optional<return_type>::value || std::same_as<return_type, mixed> || is_class_instance<return_type>::value)
136+
kphp::coro::task<return_type> f$wait(Optional<int64_t> opt_fork_id, double timeout = -1.0) noexcept {
137+
co_return co_await f$wait<return_type>(opt_fork_id.has_value() ? opt_fork_id.val() : kphp::forks::INVALID_ID, timeout);
138+
}
139+
140+
template<typename return_type>
141+
requires(is_optional<return_type>::value || std::same_as<return_type, mixed> || is_class_instance<return_type>::value)
142+
kphp::coro::task<return_type> f$wait_synchronously(int64_t fork_id) noexcept {
143+
co_return co_await f$wait<return_type>(fork_id);
144+
}
145+
146+
template<typename return_type>
147+
requires(is_optional<return_type>::value || std::same_as<return_type, mixed> || is_class_instance<return_type>::value)
148+
kphp::coro::task<return_type> f$wait_synchronously(Optional<int64_t> opt_fork_id) noexcept {
149+
co_return co_await f$wait<return_type>(opt_fork_id);
137150
}
138151

139152
// ================================================================================================

runtime-light/stdlib/fork/fork-state.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <cstdint>
88
#include <functional>
9+
#include <limits>
910
#include <optional>
1011
#include <utility>
1112

@@ -35,7 +36,7 @@ struct ForkInstanceState final : private vk::not_copyable {
3536
};
3637

3738
private:
38-
static constexpr int64_t FORK_ID_INIT = 0;
39+
static constexpr auto FORK_ID_INIT{std::numeric_limits<int64_t>::max()};
3940

4041
int64_t next_fork_id{FORK_ID_INIT};
4142
// type erased tasks that represent forks
@@ -64,7 +65,7 @@ struct ForkInstanceState final : private vk::not_copyable {
6465
co_return s;
6566
}};
6667

67-
const int64_t fork_id{next_fork_id++};
68+
const int64_t fork_id{next_fork_id--};
6869
auto fork_task{std::invoke(fork_coroutine, std::move(task), fork_id)};
6970
forks.emplace(
7071
fork_id,

tests/phpt/fork/001_basic.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ function hash4($n) {
8888
return $q;
8989
}
9090

91-
91+
wait(false);
9292

9393
$id2 = fork(hash2(10));
9494
$id = fork(hash3(10));

tests/phpt/fork/012_exceptions.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@ok k2_skip
1+
@ok
22
<?php
33
require_once 'kphp_tester_include.php';
44

tests/phpt/fork/017_exit_from_fork.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@ok k2_skip
1+
@ok
22
<?php
33

44
function function_return_void(string $msg) {

0 commit comments

Comments
 (0)