Branch data Line data Source code
1 : : // Copyright 2026 HPActor Contributors
2 : : //
3 : : // Licensed under the Apache License, Version 2.0 (the "License");
4 : : // you may not use this file except in compliance with the License.
5 : : // You may obtain a copy of the License at
6 : : //
7 : : // http://www.apache.org/licenses/LICENSE-2.0
8 : : //
9 : : // Unless required by applicable law or agreed to in writing, software
10 : : // distributed under the License is distributed on an "AS IS" BASIS,
11 : : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : : // See the License for the specific language governing permissions and
13 : : // limitations under the License.
14 : :
15 : : #include <hpactor/ref/actor_proxy.hpp>
16 : : #include <hpactor/spawn.hpp>
17 : :
18 : : namespace hpactor {
19 : :
20 : 1 : AsyncActor::AsyncActor()
21 : 1 : : mutex_(std::make_unique<std::mutex>()),
22 : 2 : cv_(std::make_unique<std::condition_variable>()) {}
23 : :
24 : 4 : AsyncActor::AsyncActor(EndPoint endpoint,
25 : 4 : std::chrono::milliseconds timeout)
26 : 4 : : endpoint_(endpoint), timeout_(timeout),
27 : 4 : mutex_(std::make_unique<std::mutex>()),
28 : 4 : cv_(std::make_unique<std::condition_variable>()) {}
29 : :
30 : 0 : AsyncActor::AsyncActor(AsyncActor&& other) noexcept
31 : 0 : : endpoint_(other.endpoint_), timeout_(other.timeout_),
32 : 0 : mutex_(std::move(other.mutex_)), cv_(std::move(other.cv_)),
33 : 0 : ready_(other.ready_), cancelled_(other.cancelled_),
34 : 0 : response_(other.response_) {}
35 : :
36 : 0 : AsyncActor& AsyncActor::operator=(AsyncActor&& other) noexcept {
37 : 0 : if (this != &other) {
38 : 0 : endpoint_ = other.endpoint_;
39 : 0 : timeout_ = other.timeout_;
40 : 0 : mutex_ = std::move(other.mutex_);
41 : 0 : cv_ = std::move(other.cv_);
42 : 0 : ready_ = other.ready_;
43 : 0 : cancelled_ = other.cancelled_;
44 : 0 : response_ = other.response_;
45 : : }
46 : 0 : return *this;
47 : : }
48 : :
49 : 3 : result<ActorRef> AsyncActor::get() {
50 : 3 : std::unique_lock<std::mutex> lock(*mutex_);
51 : 3 : if (cancelled_) {
52 : 3 : return result<ActorRef>::make(error(errors::unknown, "spawn "
53 : 1 : "cancelled"));
54 : : }
55 : :
56 : 5 : bool timed_out = !cv_->wait_for(lock, timeout_, [this] { return ready_; });
57 : 2 : if (timed_out) {
58 : 3 : return result<ActorRef>::make(error(errors::timeout, "spawn request "
59 : 1 : "timed out"));
60 : : }
61 : :
62 : 1 : if (response_.error_code != spawn_errors::success) {
63 : 0 : return result<ActorRef>::make(error(response_.error_code, "spawn "
64 : 0 : "failed"));
65 : : }
66 : :
67 : : // Create ActorProxy for the remote actor using stack allocation
68 : 1 : ActorProxy proxy(response_.actor_addr, static_cast<net::Transport*>(nullptr));
69 : 1 : ActorRef ref(std::move(proxy)); // NOLINT(performance-move-const-arg)
70 : 1 : return result<ActorRef>::make(std::move(ref));
71 : 3 : }
72 : :
73 : 4 : bool AsyncActor::ready() const {
74 : 4 : std::lock_guard<std::mutex> lock(*mutex_);
75 : 4 : return ready_ || cancelled_;
76 : 4 : }
77 : :
78 : 1 : void AsyncActor::cancel() {
79 : 1 : std::lock_guard<std::mutex> lock(*mutex_);
80 : 1 : cancelled_ = true;
81 : 1 : ready_ = true;
82 : 1 : cv_->notify_all();
83 : 1 : }
84 : :
85 : 1 : void AsyncActor::set_response(SpawnResponse response) {
86 : 1 : std::lock_guard<std::mutex> lock(*mutex_);
87 : 1 : response_ = response;
88 : 1 : ready_ = true;
89 : 1 : cv_->notify_all();
90 : 1 : }
91 : :
92 : : } // namespace hpactor
|