Use a dedicated thread for dispatching callbacks

This isolates our backend thread from user code and the java VM.
This commit is contained in:
Mathias Agopian
2021-10-04 10:56:43 -07:00
committed by Mathias Agopian
parent 1c1cb11cf5
commit f7a630d614
2 changed files with 43 additions and 3 deletions
+34 -3
View File
@@ -39,9 +39,40 @@ namespace backend {
DriverBase::DriverBase(Dispatcher* dispatcher) noexcept
: mDispatcher(dispatcher) {
// This thread services user callbacks
mServiceThread = std::thread([this]() {
do {
auto& serviceThreadCondition = mServiceThreadCondition;
auto& serviceThreadCallbackQueue = mServiceThreadCallbackQueue;
// wait for some callbacks to dispatch
std::unique_lock<std::mutex> lock(mServiceThreadLock);
while (serviceThreadCallbackQueue.empty() && !mExitRequested) {
serviceThreadCondition.wait(lock);
}
if (mExitRequested) {
break;
}
// move the callbacks to a temporary vector
auto callbacks(std::move(serviceThreadCallbackQueue));
lock.unlock();
// and make sure to call them without our lock held
for (auto [handler, callback, user] : callbacks) {
handler->post(user, callback);
}
} while (true);
});
}
DriverBase::~DriverBase() noexcept {
// quit our service thread
std::unique_lock<std::mutex> lock(mServiceThreadLock);
mExitRequested = true;
mServiceThreadCondition.notify_one();
lock.unlock();
mServiceThread.join();
delete mDispatcher;
}
@@ -67,9 +98,9 @@ void DriverBase::CallbackData::release(CallbackData* data) {
void DriverBase::scheduleCallback(CallbackHandler* handler, void* user, CallbackHandler::Callback callback) {
if (handler) {
// TODO: since we're calling user-code here, we might want to do this from a
// dedicated thread, so they can't mess with our GL state for instance.
handler->post(user, callback);
std::lock_guard<std::mutex> lock(mServiceThreadLock);
mServiceThreadCallbackQueue.emplace_back(handler, callback, user);
mServiceThreadCondition.notify_one();
} else {
std::lock_guard<std::mutex> lock(mPurgeLock);
mCallbacks.emplace_back(user, callback);
+9
View File
@@ -30,9 +30,12 @@
#include "private/backend/SamplerGroup.h"
#include <array>
#include <condition_variable>
#include <memory>
#include <mutex>
#include <thread>
#include <utility>
#include <vector>
#include <stdint.h>
@@ -231,6 +234,12 @@ protected:
private:
std::mutex mPurgeLock;
std::vector<std::pair<void*, CallbackHandler::Callback>> mCallbacks;
std::thread mServiceThread;
std::mutex mServiceThreadLock;
std::condition_variable mServiceThreadCondition;
std::vector<std::tuple<CallbackHandler*, CallbackHandler::Callback, void*>> mServiceThreadCallbackQueue;
bool mExitRequested = false;
};