custom folly executor for running coroutines on GLib main context

This commit is contained in:
Selim Mustafaev 2022-05-09 19:57:03 +03:00
parent 6f9623106b
commit ee12ea81d0
4 changed files with 60 additions and 2 deletions

View File

@ -39,7 +39,7 @@ add_executable(autocat_gnome main.cpp
services/Settings.h services/Settings.h
gui/TitleBar.cpp gui/TitleBar.cpp
gui/TitleBar.h gui/TitleBar.h
coro/Coro.h) coro/Coro.h coro/GLibMainContextExecutor.cpp coro/GLibMainContextExecutor.h)
target_link_libraries(autocat_gnome ${GTKMM_LIBRARIES} target_link_libraries(autocat_gnome ${GTKMM_LIBRARIES}
${GLIBMM_LIBRARIES} ${GLIBMM_LIBRARIES}

View File

@ -0,0 +1,32 @@
//
// Created by selim on 09.05.2022.
//
#include "GLibMainContextExecutor.h"
#include <glibmm.h>
int callback(void* data) {
auto executor = reinterpret_cast<GLibMainContextExecutor*>(data);
executor->runFront();
return G_SOURCE_REMOVE;
}
void GLibMainContextExecutor::add(folly::Func func) {
std::lock_guard<std::mutex> lock(_mutex);
_tasks.push(std::move(func));
g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, callback, this, nullptr);
}
void GLibMainContextExecutor::runFront() {
std::lock_guard<std::mutex> lock(_mutex);
if(!_tasks.empty()) {
auto task = std::move(_tasks.front());
_tasks.pop();
task();
}
}
folly::Executor::KeepAlive<GLibMainContextExecutor> GLibMainContextExecutor::instance() {
static GLibMainContextExecutor instance;
return folly::getKeepAliveToken(instance);
}

View File

@ -0,0 +1,25 @@
//
// Created by selim on 09.05.2022.
//
#ifndef AUTOCAT_GNOME_GLIBMAINCONTEXTEXECUTOR_H
#define AUTOCAT_GNOME_GLIBMAINCONTEXTEXECUTOR_H
#include <folly/Executor.h>
#include <queue>
#include <mutex>
class GLibMainContextExecutor: public folly::Executor {
private:
std::queue<folly::Func> _tasks;
std::mutex _mutex;
public:
static folly::Executor::KeepAlive<GLibMainContextExecutor> instance();
~GLibMainContextExecutor() override = default;
void add(folly::Func func) override;
void runFront();
};
#endif //AUTOCAT_GNOME_GLIBMAINCONTEXTEXECUTOR_H

View File

@ -5,6 +5,7 @@
#include "LoginWindow.h" #include "LoginWindow.h"
#include "MainWindow.h" #include "MainWindow.h"
#include "../services/Api.h" #include "../services/Api.h"
#include "../coro/GLibMainContextExecutor.h"
#include <gtkmm/application.h> #include <gtkmm/application.h>
#include <gtkmm/box.h> #include <gtkmm/box.h>
@ -50,7 +51,7 @@ void LoginWindow::loginClicked() {
_spinner.start(); _spinner.start();
try { try {
User user = co_await Api::login(email, password).scheduleOn(folly::getGlobalIOExecutor()); User user = co_await Api::login(email, password).scheduleOn(GLibMainContextExecutor::instance());
auto app = this->get_application(); auto app = this->get_application();
auto mainWindow = new MainWindow(); auto mainWindow = new MainWindow();
mainWindow->show(); mainWindow->show();