core: Destroy pipewire streams when ScreenCast sessions are closed (#130)

* fix: avoid double freeing the screencopy stream

* fix: avoid leaking pipewire streams

* style: remove brackets around the short if
This commit is contained in:
Junxuan Liao 2023-11-19 20:36:20 +08:00 committed by GitHub
parent b2fc111096
commit 8d3538e113
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -299,7 +299,14 @@ void CScreencopyPortal::onCreateSession(sdbus::MethodCall& call) {
// create objects // create objects
PSESSION->session = createDBusSession(sessionHandle); PSESSION->session = createDBusSession(sessionHandle);
PSESSION->session->onDestroy = [PSESSION]() { PSESSION->session.release(); }; PSESSION->session->onDestroy = [PSESSION, this]() {
if (PSESSION->sharingData.active) {
m_pPipewire->destroyStream(PSESSION);
Debug::log(LOG, "[screencopy] Stream destroyed");
}
PSESSION->session.release();
Debug::log(LOG, "[screencopy] Session destroyed");
};
PSESSION->request = createDBusRequest(requestHandle); PSESSION->request = createDBusRequest(requestHandle);
PSESSION->request->onDestroy = [PSESSION]() { PSESSION->request.release(); }; PSESSION->request->onDestroy = [PSESSION]() { PSESSION->request.release(); };
@ -988,6 +995,11 @@ void CPipewireConnection::createStream(CScreencopyPortal::SSession* pSession) {
} }
void CPipewireConnection::destroyStream(CScreencopyPortal::SSession* pSession) { void CPipewireConnection::destroyStream(CScreencopyPortal::SSession* pSession) {
// Disconnecting the stream can cause reentrance to this function.
if (pSession->sharingData.active == false)
return;
pSession->sharingData.active = false;
const auto PSTREAM = streamFromSession(pSession); const auto PSTREAM = streamFromSession(pSession);
if (!PSTREAM || !PSTREAM->stream) if (!PSTREAM || !PSTREAM->stream)
@ -1003,8 +1015,6 @@ void CPipewireConnection::destroyStream(CScreencopyPortal::SSession* pSession) {
pw_stream_disconnect(PSTREAM->stream); pw_stream_disconnect(PSTREAM->stream);
pw_stream_destroy(PSTREAM->stream); pw_stream_destroy(PSTREAM->stream);
pSession->sharingData.active = false;
std::erase_if(m_vStreams, [&](const auto& other) { return other.get() == PSTREAM; }); std::erase_if(m_vStreams, [&](const auto& other) { return other.get() == PSTREAM; });
} }