mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 04:43:10 +00:00
Make iothread's perform_on_main use std::function
This will allow clients to use lambdas instead of having to define an out-of-line function
This commit is contained in:
parent
7a76efa629
commit
e1adc3a6b2
2 changed files with 18 additions and 17 deletions
|
@ -49,12 +49,10 @@ struct spawn_request_t {
|
|||
};
|
||||
|
||||
struct main_thread_request_t {
|
||||
int (*handler)(void *) = NULL;
|
||||
void *context = NULL;
|
||||
volatile int handler_result = -1;
|
||||
volatile bool done = false;
|
||||
std::function<void(void)> func;
|
||||
|
||||
main_thread_request_t() {}
|
||||
main_thread_request_t(std::function<void(void)> &&f) : func(f) {}
|
||||
|
||||
// No moving OR copying
|
||||
// main_thread_requests are always stack allocated, and we deal in pointers to them
|
||||
|
@ -305,7 +303,7 @@ static void iothread_service_main_thread_requests(void) {
|
|||
while (!request_queue.empty()) {
|
||||
main_thread_request_t *req = request_queue.front();
|
||||
request_queue.pop();
|
||||
req->handler_result = req->handler(req->context);
|
||||
req->func();
|
||||
req->done = true;
|
||||
}
|
||||
|
||||
|
@ -342,16 +340,14 @@ static void iothread_service_result_queue() {
|
|||
}
|
||||
}
|
||||
|
||||
int iothread_perform_on_main_base(int (*handler)(void *), void *context) {
|
||||
// If this is the main thread, just do it.
|
||||
void iothread_perform_on_main(std::function<void(void)> &&func) {
|
||||
if (is_main_thread()) {
|
||||
return handler(context);
|
||||
func();
|
||||
return;
|
||||
}
|
||||
|
||||
// Make a new request. Note we are synchronous, so this can be stack allocated!
|
||||
main_thread_request_t req;
|
||||
req.handler = handler;
|
||||
req.context = context;
|
||||
main_thread_request_t req(std::move(func));
|
||||
|
||||
// Append it. Do not delete the nested scope as it is crucial to the proper functioning of this
|
||||
// code by virtue of the lock management.
|
||||
|
@ -370,10 +366,9 @@ int iothread_perform_on_main_base(int (*handler)(void *), void *context) {
|
|||
// It would be nice to support checking for cancellation here, but the clients need a
|
||||
// deterministic way to clean up to avoid leaks
|
||||
VOMIT_ON_FAILURE(
|
||||
pthread_cond_wait(&s_main_thread_performer_cond, &s_main_thread_performer_lock));
|
||||
pthread_cond_wait(&s_main_thread_performer_cond, &s_main_thread_performer_lock));
|
||||
}
|
||||
|
||||
// Ok, the request must now be done.
|
||||
assert(req.done);
|
||||
return req.handler_result;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#ifndef FISH_IOTHREAD_H
|
||||
#define FISH_IOTHREAD_H
|
||||
|
||||
#include <functional>
|
||||
|
||||
/// Runs a command on a thread.
|
||||
///
|
||||
/// \param handler The function to execute on a background thread. Accepts an arbitrary context
|
||||
|
@ -24,9 +26,6 @@ void iothread_service_completion(void);
|
|||
/// Waits for all iothreads to terminate.
|
||||
void iothread_drain_all(void);
|
||||
|
||||
/// Performs a function on the main thread, blocking until it completes.
|
||||
int iothread_perform_on_main_base(int (*handler)(void *), void *context);
|
||||
|
||||
/// Helper templates.
|
||||
template <typename T>
|
||||
int iothread_perform(int (*handler)(T *), void (*completion)(T *, int), T *context) {
|
||||
|
@ -42,9 +41,16 @@ int iothread_perform(int (*handler)(T *), T *context) {
|
|||
static_cast<void *>(context));
|
||||
}
|
||||
|
||||
/// Performs a function on the main thread, blocking until it completes.
|
||||
void iothread_perform_on_main(std::function<void(void)> &&func);
|
||||
|
||||
template <typename T>
|
||||
int iothread_perform_on_main(int (*handler)(T *), T *context) {
|
||||
return iothread_perform_on_main_base((int (*)(void *))handler, (void *)(context));
|
||||
int result = 0;
|
||||
iothread_perform_on_main([&result,handler,context](){
|
||||
result = handler(context);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue