internal: gracefully exit on termination after creating the event loop

possibly might help #103
This commit is contained in:
vaxerski 2023-10-05 01:24:50 +01:00
parent f9461b0b7d
commit 158b5892bd
2 changed files with 42 additions and 4 deletions

View File

@ -313,20 +313,23 @@ void CPortalManager::startEventLoop() {
std::thread pollThr([this, &pollfds]() {
while (1) {
int ret = poll(pollfds, 3, -1);
int ret = poll(pollfds, 3, 5 /* 5 seconds, reasonable. It's because we might need to terminate */);
if (ret < 0) {
Debug::log(CRIT, "[core] Polling fds failed with {}", strerror(errno));
exit(1);
g_pPortalManager->terminate();
}
for (size_t i = 0; i < 3; ++i) {
if (pollfds[0].revents & POLLHUP) {
Debug::log(CRIT, "[core] Disconnected from pollfd id {}", i);
exit(1);
g_pPortalManager->terminate();
}
}
{
if (m_bTerminate)
break;
if (ret != 0) {
Debug::log(TRACE, "[core] got poll event");
std::lock_guard<std::mutex> lg(m_sEventLoopInternals.loopRequestMutex);
m_sEventLoopInternals.shouldProcess = true;
@ -352,6 +355,9 @@ void CPortalManager::startEventLoop() {
m_sTimersThread.loopSignal.wait_for(lk, std::chrono::milliseconds((int)nearest), [this] { return m_sTimersThread.shouldProcess; });
m_sTimersThread.shouldProcess = false;
if (m_bTerminate)
break;
// awakened. Check if any timers passed
m_mEventLock.lock();
bool notify = false;
@ -372,6 +378,8 @@ void CPortalManager::startEventLoop() {
}
});
addTimer({10000, [this] { this->terminate(); }});
while (1) { // dbus events
// wait for being awakened
m_sEventLoopInternals.loopRequestMutex.unlock(); // unlock, we are ready to take events
@ -382,6 +390,9 @@ void CPortalManager::startEventLoop() {
m_sEventLoopInternals.loopRequestMutex.lock(); // lock incoming events
if (m_bTerminate)
break;
m_sEventLoopInternals.shouldProcess = false;
m_mEventLock.lock();
@ -431,7 +442,17 @@ void CPortalManager::startEventLoop() {
m_mEventLock.unlock();
}
Debug::log(ERR, "[core] Terminated");
m_sPortals.globalShortcuts.reset();
m_sPortals.screencopy.reset();
m_pConnection.reset();
pw_loop_destroy(m_sPipewire.loop);
wl_display_disconnect(m_sWaylandConnection.display);
m_sTimersThread.thread.release();
pollThr.join(); // wait for poll to exit
}
sdbus::IConnection* CPortalManager::getConnection() {
@ -494,3 +515,15 @@ void CPortalManager::addTimer(const CTimer& timer) {
m_sTimersThread.shouldProcess = true;
m_sTimersThread.loopSignal.notify_all();
}
void CPortalManager::terminate() {
m_bTerminate = true;
{
m_sEventLoopInternals.shouldProcess = true;
m_sEventLoopInternals.loopSignal.notify_all();
}
m_sTimersThread.shouldProcess = true;
m_sTimersThread.loopSignal.notify_all();
}

View File

@ -71,9 +71,14 @@ class CPortalManager {
gbm_device* createGBMDevice(drmDevice* dev);
// terminate after the event loop has been created. Before we can exit()
void terminate();
private:
void startEventLoop();
bool m_bTerminate = false;
struct {
std::condition_variable loopSignal;
std::mutex loopMutex;