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; });
} }
@ -1065,7 +1075,7 @@ uint32_t CPipewireConnection::buildFormatsFor(spa_pod_builder* b[2], const spa_p
paramCount = 2; paramCount = 2;
params[0] = build_format(b[0], pwFromDrmFourcc(stream->pSession->sharingData.frameInfoDMA.fmt), stream->pSession->sharingData.frameInfoDMA.w, params[0] = build_format(b[0], pwFromDrmFourcc(stream->pSession->sharingData.frameInfoDMA.fmt), stream->pSession->sharingData.frameInfoDMA.w,
stream->pSession->sharingData.frameInfoDMA.h, stream->pSession->sharingData.framerate, modifiers, modCount); stream->pSession->sharingData.frameInfoDMA.h, stream->pSession->sharingData.framerate, modifiers, modCount);
assert(params[0] != NULL); assert(params[0] != NULL);
params[1] = build_format(b[1], pwFromDrmFourcc(stream->pSession->sharingData.frameInfoSHM.fmt), stream->pSession->sharingData.frameInfoSHM.w, params[1] = build_format(b[1], pwFromDrmFourcc(stream->pSession->sharingData.frameInfoSHM.fmt), stream->pSession->sharingData.frameInfoSHM.w,
stream->pSession->sharingData.frameInfoSHM.h, stream->pSession->sharingData.framerate, NULL, 0); stream->pSession->sharingData.frameInfoSHM.h, stream->pSession->sharingData.framerate, NULL, 0);
@ -1075,7 +1085,7 @@ uint32_t CPipewireConnection::buildFormatsFor(spa_pod_builder* b[2], const spa_p
paramCount = 1; paramCount = 1;
params[0] = build_format(b[0], pwFromDrmFourcc(stream->pSession->sharingData.frameInfoSHM.fmt), stream->pSession->sharingData.frameInfoSHM.w, params[0] = build_format(b[0], pwFromDrmFourcc(stream->pSession->sharingData.frameInfoSHM.fmt), stream->pSession->sharingData.frameInfoSHM.w,
stream->pSession->sharingData.frameInfoSHM.h, stream->pSession->sharingData.framerate, NULL, 0); stream->pSession->sharingData.frameInfoSHM.h, stream->pSession->sharingData.framerate, NULL, 0);
} }
if (modifiers) if (modifiers)