Simplify main thread requests

This replaces the main_thread_request struct with just a simple
function.
This commit is contained in:
ridiculousfish 2021-02-26 15:46:33 -08:00
parent 05d8907071
commit abc66511f5
2 changed files with 15 additions and 30 deletions

View file

@ -56,23 +56,6 @@ struct work_request_t {
work_request_t(work_request_t &&) = default; work_request_t(work_request_t &&) = default;
}; };
struct main_thread_request_t {
// The function to execute.
void_function_t func;
// Set by the main thread when the work is done.
std::promise<void> done{};
explicit main_thread_request_t(void_function_t &&f) : func(f) {}
// No moving OR copying
// main_thread_requests are always stack allocated, and we deal in pointers to them
void operator=(const main_thread_request_t &) = delete;
void operator=(main_thread_request_t &&) = delete;
main_thread_request_t(const main_thread_request_t &) = delete;
main_thread_request_t(main_thread_request_t &&) = delete;
};
struct thread_pool_t { struct thread_pool_t {
struct data_t { struct data_t {
/// The queue of outstanding, unclaimed requests. /// The queue of outstanding, unclaimed requests.
@ -145,7 +128,7 @@ struct main_thread_queue_t {
// iothread_perform_on_main requests. // iothread_perform_on_main requests.
// Note this contains pointers to structs that are stack-allocated on the requesting thread. // Note this contains pointers to structs that are stack-allocated on the requesting thread.
std::vector<main_thread_request_t *> requests; std::vector<void_function_t> requests;
/// Transfer ownership of ourselves to a new queue and return it. /// Transfer ownership of ourselves to a new queue and return it.
/// 'this' is left empty. /// 'this' is left empty.
@ -355,29 +338,31 @@ void iothread_service_main() {
if (func) func(); if (func) func();
} }
// Perform each main thread request. Note we are NOT responsible for deleting these. They are // Perform each main thread request.
// stack allocated in their respective threads! for (const void_function_t &func : queue.requests) {
for (main_thread_request_t *req : queue.requests) { if (func) func();
req->func();
req->done.set_value();
} }
} }
void iothread_perform_on_main(void_function_t &&func) { void iothread_perform_on_main(const void_function_t &func) {
if (is_main_thread()) { if (is_main_thread()) {
func(); func();
return; return;
} }
// Make a new request. Note we are synchronous, so this can be stack allocated! // Make a new request. Note we are synchronous, so our closure can use references instead of
main_thread_request_t req(std::move(func)); // copying.
std::promise<void> wait_until_done;
auto handler = [&] {
func();
wait_until_done.set_value();
};
// Append it. Ensure we don't hold the lock after. // Append it. Ensure we don't hold the lock after.
s_main_thread_queue.acquire()->requests.push_back(&req); s_main_thread_queue.acquire()->requests.push_back(std::move(handler));
// Tell the signaller and then wait until our future is set. // Tell the signaller and then wait until our future is set.
get_notify_signaller().post(); get_notify_signaller().post();
req.done.get_future().wait(); wait_until_done.get_future().wait();
} }
bool make_detached_pthread(void *(*func)(void *), void *param) { bool make_detached_pthread(void *(*func)(void *), void *param) {

View file

@ -41,7 +41,7 @@ inline void iothread_perform_cantwait(std::function<void()> &&func) {
} }
/// Performs a function on the main thread, blocking until it completes. /// Performs a function on the main thread, blocking until it completes.
void iothread_perform_on_main(std::function<void()> &&func); void iothread_perform_on_main(const std::function<void()> &func);
/// Creates a pthread, manipulating the signal mask so that the thread receives no signals. /// Creates a pthread, manipulating the signal mask so that the thread receives no signals.
/// The thread is detached. /// The thread is detached.