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 : : #pragma once
16 : : #include <chrono>
17 : : #include <condition_variable>
18 : : #include <cstddef>
19 : : #include <hpactor/actor/abstract_actor.hpp>
20 : : #include <memory>
21 : : #include <mutex>
22 : : #include <queue>
23 : :
24 : : namespace hpactor {
25 : :
26 : : // Forward declaration - full definition in mutex_mailbox.hpp
27 : : template <typename T> class MutexMailbox;
28 : :
29 : : template <typename T> class IMailbox {
30 : : public:
31 : 4 : virtual ~IMailbox() = default;
32 : :
33 : : // Hot path - marked noexcept for real-time guarantees
34 : : virtual void push(T&& msg) noexcept = 0;
35 : : virtual bool try_pop(T& out) noexcept = 0;
36 : :
37 : : // Blocking pop - may block, used for actor message processing loop
38 : : virtual bool pop(T& out) = 0;
39 : :
40 : : virtual size_t size() const = 0;
41 : : virtual bool empty() const = 0;
42 : : };
43 : :
44 : : // Default implementation selector
45 : : enum class MailboxType {
46 : : Mutex, // Thread-safe, slower
47 : : LockFree, // TODO: Implementation TBD after stress tests pass
48 : : };
49 : :
50 : : // Factory function
51 : : template <typename T, MailboxType Type = MailboxType::Mutex>
52 : 1 : std::unique_ptr<IMailbox<T>> create_mailbox() {
53 : : if constexpr (Type == MailboxType::Mutex) {
54 : 1 : return std::make_unique<MutexMailbox<T>>();
55 : : }
56 : : }
57 : :
58 : : // ActorBase - alias for AbstractActor (base class for all actors)
59 : : using ActorBase = AbstractActor;
60 : :
61 : : // ActorMailbox - mailbox with owner association for actor-specific features
62 : : template <typename T> class ActorMailbox : public IMailbox<T> {
63 : : public:
64 : 1 : ActorMailbox() = default;
65 : :
66 : 0 : void push(T&& msg) noexcept override {
67 : 0 : std::lock_guard<std::mutex> lock(mutex_);
68 : 0 : queue_.push(std::move(msg));
69 : 0 : cv_.notify_one();
70 : 0 : }
71 : :
72 : 0 : bool try_pop(T& out) noexcept override {
73 : 0 : std::lock_guard<std::mutex> lock(mutex_);
74 : 0 : if (queue_.empty()) {
75 : 0 : return false;
76 : : }
77 : 0 : out = std::move(queue_.front());
78 : 0 : queue_.pop();
79 : 0 : return true;
80 : 0 : }
81 : :
82 : 0 : bool pop(T& out) override {
83 : 0 : std::unique_lock<std::mutex> lock(mutex_);
84 : 0 : cv_.wait(lock, [this] { return !queue_.empty(); });
85 : 0 : out = std::move(queue_.front());
86 : 0 : queue_.pop();
87 : 0 : return true;
88 : 0 : }
89 : :
90 : 1 : size_t size() const override {
91 : 1 : std::lock_guard<std::mutex> lock(mutex_);
92 : 1 : return queue_.size();
93 : 1 : }
94 : :
95 : 1 : bool empty() const override {
96 : 1 : std::lock_guard<std::mutex> lock(mutex_);
97 : 1 : return queue_.empty();
98 : 1 : }
99 : :
100 : : bool pop_with_timeout(T& out, std::chrono::milliseconds timeout) {
101 : : std::unique_lock<std::mutex> lock(mutex_);
102 : : bool result =
103 : : cv_.wait_for(lock, timeout, [this] { return !queue_.empty(); });
104 : : if (result) {
105 : : out = std::move(queue_.front());
106 : : queue_.pop();
107 : : }
108 : : return result;
109 : : }
110 : :
111 : : void set_owner(ActorBase* owner) {
112 : : owner_ = owner;
113 : : }
114 : :
115 : : private:
116 : : mutable std::mutex mutex_;
117 : : std::queue<T> queue_;
118 : : std::condition_variable cv_;
119 : : ActorBase* owner_ = nullptr;
120 : : };
121 : :
122 : : } // namespace hpactor
|