mirror of
https://github.com/hyprwm/xdg-desktop-portal-hyprland.git
synced 2024-11-25 23:45:58 +01:00
internal: gracefully exit on termination after creating the event loop
possibly might help #103
This commit is contained in:
parent
f9461b0b7d
commit
158b5892bd
2 changed files with 42 additions and 4 deletions
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue