flatten 20260225
This commit is contained in:
140
tjp/core/threads/PinnedFutures.hpp
Executable file
140
tjp/core/threads/PinnedFutures.hpp
Executable file
@@ -0,0 +1,140 @@
|
||||
// TJP COPYRIGHT HEADER
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include <tjp/core/threads/Lock.hpp>
|
||||
#include <tjp/core/threads/UnlockGuard.hpp>
|
||||
#include <tjp/core/threads/Atomic.h>
|
||||
#include <tjp/core/threads/TestMutex.hpp>
|
||||
#include <tjp/core/containers/Function.hpp>
|
||||
|
||||
#include <queue>
|
||||
|
||||
namespace tjp::core::threads {
|
||||
|
||||
|
||||
// DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT
|
||||
// DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT DRAFT
|
||||
|
||||
struct PinnedFutures
|
||||
{
|
||||
std::thread thread;
|
||||
Event::Mutex mutex;
|
||||
Event event;
|
||||
std::queue<Function<void()>> events;
|
||||
bool running = false;
|
||||
|
||||
bool is_on_thread()
|
||||
{
|
||||
return thread.joinable() &&
|
||||
(std::this_thread::get_id() == thread.get_id());
|
||||
}
|
||||
|
||||
PinnedFutures(bool start_=true)
|
||||
{
|
||||
if (start_)
|
||||
start();
|
||||
}
|
||||
|
||||
~PinnedFutures()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
auto lock = lock_of(mutex);
|
||||
while (running)
|
||||
{
|
||||
if (events.empty())
|
||||
{
|
||||
event.wait(lock);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto fn = std::move(events.front());
|
||||
events.pop();
|
||||
|
||||
{
|
||||
auto unlock = unlock_of(mutex);
|
||||
fn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void start()
|
||||
{
|
||||
if (running)
|
||||
return;
|
||||
|
||||
running = true;
|
||||
thread = std::thread([this]() { run(); });
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
{
|
||||
auto lock = lock_of(mutex);
|
||||
running = false;
|
||||
}
|
||||
event.notify_all();
|
||||
if (thread.joinable())
|
||||
thread.join();
|
||||
}
|
||||
|
||||
template<typename V>
|
||||
Future<V> on_(Future<V> &f0)
|
||||
{
|
||||
Promise<V> p;
|
||||
|
||||
auto swizzle = f0.then([this, p](auto &&f) {
|
||||
auto lock = lock_of(mutex);
|
||||
events.push([p, f=std::move(f)]() {
|
||||
auto p_ = p;
|
||||
auto f_ = f;
|
||||
p_.consume([&](auto &&f) { return f.get(); }, f_);
|
||||
});
|
||||
|
||||
event.notify_one();
|
||||
});
|
||||
|
||||
return p.get_future().then([swizzle](auto &&f1) {
|
||||
return f1.get();
|
||||
});
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
auto run_(F &&f)
|
||||
{
|
||||
using R = decltype(f());
|
||||
Promise<R> p;
|
||||
|
||||
{
|
||||
auto lock = lock_of(mutex);
|
||||
events.push([&]() { p.consume(f); });
|
||||
event.notify_one();
|
||||
}
|
||||
|
||||
return p.get_future().get();
|
||||
}
|
||||
|
||||
template<typename V>
|
||||
Future<V> on(Future<V> &f)
|
||||
{
|
||||
return on_(f);
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
auto run(F &&f)
|
||||
{
|
||||
if (is_on_thread())
|
||||
return f();
|
||||
|
||||
return run_(std::forward<F>(f));
|
||||
}
|
||||
|
||||
} ;
|
||||
|
||||
} // namespace
|
||||
Reference in New Issue
Block a user