1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 23:27:35 +00:00

LibCore+Userland: Allow canceling promises

To make EventLoop cancel its managed Promises, we need the ability to
cancel them in the first place.
This commit is contained in:
kleines Filmröllchen 2022-12-29 14:53:05 +01:00 committed by Linus Groh
parent afd0f941b7
commit bfd9f681f7
6 changed files with 48 additions and 35 deletions

View file

@ -10,6 +10,7 @@
#include <LibCore/Object.h>
namespace Core {
template<typename Result>
class Promise : public Object {
C_OBJECT(Promise);
@ -19,22 +20,33 @@ public:
void resolve(Result&& result)
{
m_pending = move(result);
m_pending_or_error = move(result);
if (on_resolved)
on_resolved(m_pending.value());
on_resolved(m_pending_or_error.value());
}
bool is_resolved()
void cancel(Error error)
{
return m_pending.has_value();
};
m_pending_or_error = move(error);
}
Result await()
bool is_canceled()
{
while (!is_resolved()) {
return m_pending_or_error.has_value() && m_pending_or_error->is_error();
}
bool is_resolved() const
{
return m_pending_or_error.has_value() && !m_pending_or_error->is_error();
}
ErrorOr<Result> await()
{
while (!m_pending_or_error.has_value())
Core::EventLoop::current().pump();
}
return m_pending.release_value();
return m_pending_or_error.release_value();
}
// Converts a Promise<A> to a Promise<B> using a function func: A -> B
@ -52,6 +64,7 @@ public:
private:
Promise() = default;
Optional<Result> m_pending;
Optional<ErrorOr<Result>> m_pending_or_error;
};
}

View file

@ -170,7 +170,7 @@ int Client::get_new_id()
Result Client::handle_promise(int id)
{
auto result = m_promises.get(id)->promise->await();
auto result = TRY(m_promises.get(id)->promise->await());
m_promises.remove(id);
return result;
}