g++-friendly 'Rework iothread_perform for void return types'

Allows iothread_perform to work with void return types on both
g++ and clang

This reverts commit 1040b255c7
and reintroduces ac9a0f0dbf
This commit is contained in:
ridiculousfish 2017-01-24 09:30:30 -08:00
parent ec19159580
commit a3dbca90d5
4 changed files with 38 additions and 12 deletions

View file

@ -1773,7 +1773,7 @@ void history_t::add_pending_with_file_detection(const wcstring &str) {
// Kick it off. Even though we haven't added the item yet, it updates the item on the main
// thread, so we can't race.
iothread_perform(threaded_perform_file_detection, perform_file_detection_done, context);
iothread_perform(&threaded_perform_file_detection, &perform_file_detection_done, context);
}
// Actually add the item to the history.

View file

@ -190,7 +190,7 @@ static void iothread_spawn() {
VOMIT_ON_FAILURE(pthread_sigmask(SIG_SETMASK, &saved_set, NULL));
}
int iothread_perform(void_function_t &&func, void_function_t &&completion) {
int iothread_perform_impl(void_function_t &&func, void_function_t &&completion) {
ASSERT_IS_MAIN_THREAD();
ASSERT_IS_NOT_FORKED_CHILD();
iothread_init();

View file

@ -26,16 +26,42 @@ void iothread_service_completion(void);
/// Waits for all iothreads to terminate.
void iothread_drain_all(void);
int iothread_perform(std::function<void(void)> &&func,
std::function<void(void)> &&completion = std::function<void(void)>());
// Internal implementation
int iothread_perform_impl(std::function<void(void)> &&func,
std::function<void(void)> &&completion);
// Variant that allows computing a value in func, and then passing it to the completion handler
// Template helpers
template<typename T>
int iothread_perform(std::function<T(void)> &&handler, std::function<void(T)> &&completion) {
T *result = new T();
return iothread_perform([=](){ *result = handler(); },
[=](){ completion(std::move(*result)); delete result; }
);
struct _iothread_trampoline {
template<typename HANDLER, typename COMPLETION>
static int perform(const HANDLER &handler, const COMPLETION &completion) {
T *result = new T();
return iothread_perform_impl([=](){ *result = handler(); },
[=](){ completion(std::move(*result)); delete result; });
}
};
// Void specialization
template<>
struct _iothread_trampoline<void> {
template<typename HANDLER, typename COMPLETION>
static int perform(const HANDLER &handler, const COMPLETION &completion) {
return iothread_perform_impl(handler, completion);
}
};
// iothread_perform invokes a handler on a background thread, and then a completion function
// on the main thread. The value returned from the handler is passed to the completion.
template<typename HANDLER, typename COMPLETION>
int iothread_perform(const HANDLER &handler, const COMPLETION &completion) {
return _iothread_trampoline<decltype(handler())>::perform(handler, completion);
}
// variant of iothread_perform without a completion handler
inline int iothread_perform(std::function<void(void)> &&func) {
return iothread_perform_impl(std::move(func),
std::function<void(void)>());
}
/// Legacy templates

View file

@ -1222,7 +1222,7 @@ static void update_autosuggestion(void) {
const editable_line_t *el = data->active_edit_line();
autosuggestion_context_t *ctx =
new autosuggestion_context_t(data->history, el->text, el->position);
iothread_perform(threaded_autosuggest, autosuggest_completed, ctx);
iothread_perform(&threaded_autosuggest, &autosuggest_completed, ctx);
}
}
@ -2178,7 +2178,7 @@ static void reader_super_highlight_me_plenty(int match_highlight_pos_adjust, boo
highlight_complete(ctx, result);
} else {
// Highlighting including I/O proceeds in the background.
iothread_perform(threaded_highlight, highlight_complete, ctx);
iothread_perform(&threaded_highlight, &highlight_complete, ctx);
}
highlight_search();