mirror of
https://github.com/hyprwm/xdg-desktop-portal-hyprland.git
synced 2024-11-22 22:35:59 +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]() {
|
std::thread pollThr([this, &pollfds]() {
|
||||||
while (1) {
|
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) {
|
if (ret < 0) {
|
||||||
Debug::log(CRIT, "[core] Polling fds failed with {}", strerror(errno));
|
Debug::log(CRIT, "[core] Polling fds failed with {}", strerror(errno));
|
||||||
exit(1);
|
g_pPortalManager->terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < 3; ++i) {
|
for (size_t i = 0; i < 3; ++i) {
|
||||||
if (pollfds[0].revents & POLLHUP) {
|
if (pollfds[0].revents & POLLHUP) {
|
||||||
Debug::log(CRIT, "[core] Disconnected from pollfd id {}", i);
|
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");
|
Debug::log(TRACE, "[core] got poll event");
|
||||||
std::lock_guard<std::mutex> lg(m_sEventLoopInternals.loopRequestMutex);
|
std::lock_guard<std::mutex> lg(m_sEventLoopInternals.loopRequestMutex);
|
||||||
m_sEventLoopInternals.shouldProcess = true;
|
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.loopSignal.wait_for(lk, std::chrono::milliseconds((int)nearest), [this] { return m_sTimersThread.shouldProcess; });
|
||||||
m_sTimersThread.shouldProcess = false;
|
m_sTimersThread.shouldProcess = false;
|
||||||
|
|
||||||
|
if (m_bTerminate)
|
||||||
|
break;
|
||||||
|
|
||||||
// awakened. Check if any timers passed
|
// awakened. Check if any timers passed
|
||||||
m_mEventLock.lock();
|
m_mEventLock.lock();
|
||||||
bool notify = false;
|
bool notify = false;
|
||||||
|
@ -372,6 +378,8 @@ void CPortalManager::startEventLoop() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addTimer({10000, [this] { this->terminate(); }});
|
||||||
|
|
||||||
while (1) { // dbus events
|
while (1) { // dbus events
|
||||||
// wait for being awakened
|
// wait for being awakened
|
||||||
m_sEventLoopInternals.loopRequestMutex.unlock(); // unlock, we are ready to take events
|
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
|
m_sEventLoopInternals.loopRequestMutex.lock(); // lock incoming events
|
||||||
|
|
||||||
|
if (m_bTerminate)
|
||||||
|
break;
|
||||||
|
|
||||||
m_sEventLoopInternals.shouldProcess = false;
|
m_sEventLoopInternals.shouldProcess = false;
|
||||||
|
|
||||||
m_mEventLock.lock();
|
m_mEventLock.lock();
|
||||||
|
@ -431,7 +442,17 @@ void CPortalManager::startEventLoop() {
|
||||||
m_mEventLock.unlock();
|
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();
|
m_sTimersThread.thread.release();
|
||||||
|
pollThr.join(); // wait for poll to exit
|
||||||
}
|
}
|
||||||
|
|
||||||
sdbus::IConnection* CPortalManager::getConnection() {
|
sdbus::IConnection* CPortalManager::getConnection() {
|
||||||
|
@ -494,3 +515,15 @@ void CPortalManager::addTimer(const CTimer& timer) {
|
||||||
m_sTimersThread.shouldProcess = true;
|
m_sTimersThread.shouldProcess = true;
|
||||||
m_sTimersThread.loopSignal.notify_all();
|
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);
|
gbm_device* createGBMDevice(drmDevice* dev);
|
||||||
|
|
||||||
|
// terminate after the event loop has been created. Before we can exit()
|
||||||
|
void terminate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void startEventLoop();
|
void startEventLoop();
|
||||||
|
|
||||||
|
bool m_bTerminate = false;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
std::condition_variable loopSignal;
|
std::condition_variable loopSignal;
|
||||||
std::mutex loopMutex;
|
std::mutex loopMutex;
|
||||||
|
|
Loading…
Reference in a new issue