mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 10:18:11 +00:00
LibThread: Introduce a new threading library
This library is meant to provide C++-style wrappers over lower level APIs such as syscalls and pthread_* functions, as well as utilities for easily running pieces of logic on different threads.
This commit is contained in:
parent
d5f3487203
commit
e1a6f8a27d
9 changed files with 211 additions and 3 deletions
75
Libraries/LibThread/BackgroundAction.h
Normal file
75
Libraries/LibThread/BackgroundAction.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <AK/NonnullRefPtr.h>
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/Queue.h>
|
||||
#include <AK/RefCounted.h>
|
||||
#include <LibCore/CEventLoop.h>
|
||||
#include <LibCore/CLock.h>
|
||||
#include <LibCore/CObject.h>
|
||||
#include <LibThread/Thread.h>
|
||||
|
||||
namespace LibThread {
|
||||
|
||||
template<typename Result>
|
||||
class BackgroundAction;
|
||||
|
||||
class BackgroundActionBase {
|
||||
template<typename Result>
|
||||
friend class BackgroundAction;
|
||||
|
||||
private:
|
||||
BackgroundActionBase() {}
|
||||
|
||||
static CLockable<Queue<Function<void()>>>& all_actions();
|
||||
static Thread& background_thread();
|
||||
};
|
||||
|
||||
template<typename Result>
|
||||
class BackgroundAction final : public CObject
|
||||
, public RefCounted<BackgroundAction<Result>>
|
||||
, private BackgroundActionBase {
|
||||
|
||||
C_OBJECT(BackgroundAction);
|
||||
|
||||
public:
|
||||
static NonnullRefPtr<BackgroundAction<Result>> create(
|
||||
Function<Result()> action,
|
||||
Function<void(Result)> on_complete = nullptr
|
||||
)
|
||||
{
|
||||
return adopt(*new BackgroundAction(move(action), move(on_complete)));
|
||||
}
|
||||
|
||||
virtual ~BackgroundAction() {}
|
||||
|
||||
private:
|
||||
|
||||
BackgroundAction(Function<Result()> action, Function<void(Result)> on_complete)
|
||||
: CObject(background_thread())
|
||||
, m_action(move(action))
|
||||
, m_on_complete(move(on_complete))
|
||||
{
|
||||
LOCKER(all_actions().lock());
|
||||
|
||||
this->ref();
|
||||
all_actions().resource().enqueue([this] {
|
||||
m_result = m_action();
|
||||
if (m_on_complete) {
|
||||
CEventLoop::main().post_event(*this, make<CDeferredInvocationEvent>([this](CObject&) {
|
||||
m_on_complete(m_result.release_value());
|
||||
this->deref();
|
||||
}));
|
||||
CEventLoop::main().wake();
|
||||
} else
|
||||
this->deref();
|
||||
});
|
||||
}
|
||||
|
||||
Function<Result()> m_action;
|
||||
Function<void(Result)> m_on_complete;
|
||||
Optional<Result> m_result;
|
||||
};
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue