mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-12-01 23:24:21 +08:00
ecf1676601
This allows the rust code to free up C++ resources allocated for a callback even when the callback isn't executed (as opposed to requiring the callback to run and at the end of the callback cleaning up all allocated resources). Also add type-erased destructor registration to callback_t. This allows for freeing variables allocated by the callback for debounce_t's perform_with_callback() that don't end up having their completion called due to a timeout.
85 lines
2.9 KiB
C++
85 lines
2.9 KiB
C++
#pragma once
|
|
|
|
#include <cassert>
|
|
|
|
#include "callback.h"
|
|
#include "threads.rs.h"
|
|
|
|
// iothread_perform invokes a handler on a background thread.
|
|
inline void iothread_perform(std::function<void()> &&func) {
|
|
std::shared_ptr<callback_t> callback = std::make_shared<callback_t>([=](const void *) {
|
|
func();
|
|
return nullptr;
|
|
});
|
|
|
|
iothread_perform(callback);
|
|
}
|
|
|
|
/// Variant of iothread_perform that disrespects the thread limit.
|
|
/// It does its best to spawn a new thread if all other threads are occupied.
|
|
/// This is for cases where deferring a new thread might lead to deadlock.
|
|
inline void iothread_perform_cantwait(std::function<void()> &&func) {
|
|
std::shared_ptr<callback_t> callback = std::make_shared<callback_t>([=](const void *) {
|
|
func();
|
|
return nullptr;
|
|
});
|
|
|
|
iothread_perform_cantwait(callback);
|
|
}
|
|
|
|
inline uint64_t debounce_perform(const debounce_t &debouncer, const std::function<void()> &func) {
|
|
std::shared_ptr<callback_t> callback = std::make_shared<callback_t>([=](const void *) {
|
|
func();
|
|
return nullptr;
|
|
});
|
|
|
|
return debouncer.perform(callback);
|
|
}
|
|
|
|
template <typename R>
|
|
inline void debounce_perform_with_completion(const debounce_t &debouncer, std::function<R()> &&func,
|
|
std::function<void(R)> &&completion) {
|
|
std::shared_ptr<callback_t> callback2 = std::make_shared<callback_t>([=](const void *r) {
|
|
assert(r != nullptr && "callback1 result was null!");
|
|
const R *result = (const R *)r;
|
|
completion(*result);
|
|
return nullptr;
|
|
});
|
|
|
|
std::shared_ptr<callback_t> callback1 = std::make_shared<callback_t>([=](const void *) {
|
|
const R *result = new R(func());
|
|
callback2->cleanups.push_back([result]() { delete result; });
|
|
return (void *)result;
|
|
});
|
|
|
|
debouncer.perform_with_completion(callback1, callback2);
|
|
}
|
|
|
|
template <typename R>
|
|
inline void debounce_perform_with_completion(const debounce_t &debouncer, std::function<R()> &&func,
|
|
std::function<void(const R &)> &&completion) {
|
|
std::shared_ptr<callback_t> callback2 = std::make_shared<callback_t>([=](const void *r) {
|
|
assert(r != nullptr && "callback1 result was null!");
|
|
const R *result = (const R *)r;
|
|
completion(*result);
|
|
return nullptr;
|
|
});
|
|
|
|
std::shared_ptr<callback_t> callback1 = std::make_shared<callback_t>([=](const void *) {
|
|
const R *result = new R(func());
|
|
callback2->cleanups.push_back([result]() { delete result; });
|
|
return (void *)result;
|
|
});
|
|
|
|
debouncer.perform_with_completion(callback1, callback2);
|
|
}
|
|
|
|
inline bool make_detached_pthread(const std::function<void()> &func) {
|
|
std::shared_ptr<callback_t> callback = std::make_shared<callback_t>([=](const void *) {
|
|
func();
|
|
return nullptr;
|
|
});
|
|
|
|
return make_detached_pthread(callback);
|
|
}
|