From 328397f4f4d0e6a3608f6fd8c3ec0abdd5763135 Mon Sep 17 00:00:00 2001 From: Adrian Perez de Castro Date: Wed, 14 Apr 2021 15:55:59 +0300 Subject: [PATCH 13/13] ws: Remove wl_client pointer that can end up dangling Instead of trying to keep track of the destruction of the wl_client references from ViewBackend::m_client, completely remove the member variable and instead: - In ViewBackend::releaseBuffer() use wl_resource_get_client() to obtain the wl_client from the buffer resource. Given that the buffer resource has just been used, it is guaranteed that the wl_client it refers to should be still valid. - In ViewBackend::dispatchFrameCallbacks() remove the flush call, and instead do it in WS::Surface::dispatchFrameCallbacks(), and pick the wl_client from the callback resource objects, if any callback was dispatched at all. Again, if any callback was dispatched their associated wl_client should be still valid. Skipping the flush if no callbacks are dispatched is fine because in that case there would not be any messages pending be sent over the wire anyway to trigger dispatching the callbacks in the client side. --- src/view-backend-private.cpp | 5 ++--- src/view-backend-private.h | 1 - src/ws.cpp | 3 +-- src/ws.h | 9 ++++++++- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/view-backend-private.cpp b/src/view-backend-private.cpp index b78831d..7e3a738 100644 --- a/src/view-backend-private.cpp +++ b/src/view-backend-private.cpp @@ -95,20 +95,19 @@ void ViewBackend::dispatchFrameCallbacks() if (G_LIKELY(m_bridgeId)) WS::Instance::singleton().dispatchFrameCallbacks(m_bridgeId); - wl_client_flush(m_client); wpe_view_backend_dispatch_frame_displayed(m_backend); } void ViewBackend::releaseBuffer(struct wl_resource* buffer_resource) { wl_buffer_send_release(buffer_resource); - wl_client_flush(m_client); + wl_client_flush(wl_resource_get_client(buffer_resource)); } void ViewBackend::registerSurface(uint32_t bridgeId) { m_bridgeId = bridgeId; - m_client = WS::Instance::singleton().registerViewBackend(m_bridgeId, *this); + WS::Instance::singleton().registerViewBackend(m_bridgeId, *this); } void ViewBackend::unregisterSurface(uint32_t bridgeId) diff --git a/src/view-backend-private.h b/src/view-backend-private.h index 15e98e6..363b787 100644 --- a/src/view-backend-private.h +++ b/src/view-backend-private.h @@ -79,7 +79,6 @@ private: static gboolean s_socketCallback(GSocket*, GIOCondition, gpointer); uint32_t m_bridgeId { 0 }; - struct wl_client* m_client { nullptr }; ClientBundle* m_clientBundle; struct wpe_view_backend* m_backend; diff --git a/src/ws.cpp b/src/ws.cpp index 87faaf3..622bbf3 100644 --- a/src/ws.cpp +++ b/src/ws.cpp @@ -519,14 +519,13 @@ void Instance::releaseAudioPacketExport(struct wpe_audio_packet_export* packet_e wpe_audio_packet_export_send_release(packet_export->exportResource); } -struct wl_client* Instance::registerViewBackend(uint32_t bridgeId, APIClient& apiClient) +void Instance::registerViewBackend(uint32_t bridgeId, APIClient& apiClient) { auto it = m_viewBackendMap.find(bridgeId); if (it == m_viewBackendMap.end()) g_error("Instance::registerViewBackend(): " "Cannot find surface with bridgeId %" PRIu32 " in view backend map.", bridgeId); it->second->apiClient = &apiClient; - return wl_resource_get_client(it->second->resource); } void Instance::unregisterViewBackend(uint32_t bridgeId) diff --git a/src/ws.h b/src/ws.h index 30baf8e..1bf528e 100644 --- a/src/ws.h +++ b/src/ws.h @@ -88,10 +88,17 @@ struct Surface { { struct wl_resource* resource; struct wl_resource* tmp; + struct wl_client* client { nullptr }; + wl_resource_for_each_safe(resource, tmp, &m_currentFrameCallbacks) { + g_assert(!client || client == wl_resource_get_client(resource)); + client = wl_resource_get_client(resource); wl_callback_send_done(resource, 0); wl_resource_destroy(resource); } + + if (client) + wl_client_flush(client); } private: @@ -129,7 +136,7 @@ public: int createClient(); void registerSurface(uint32_t, Surface*); - struct wl_client* registerViewBackend(uint32_t, APIClient&); + void registerViewBackend(uint32_t, APIClient&); void unregisterViewBackend(uint32_t); void dispatchFrameCallbacks(uint32_t); -- 2.31.1