From 765b8f84eb22af6237e20ae0838d1ba2d3f45da7 Mon Sep 17 00:00:00 2001 From: YaoBing Xiao Date: Thu, 28 Aug 2025 17:51:03 +0800 Subject: [PATCH] refactor: restructure treeland codebase for better maintainability simplify the processing flow of wl_client_destroy. Fixes: linuxdeepin/treeland#449 Log: --- waylib/src/server/kernel/wsocket.cpp | 75 ++++++---------------------- 1 file changed, 16 insertions(+), 59 deletions(-) diff --git a/waylib/src/server/kernel/wsocket.cpp b/waylib/src/server/kernel/wsocket.cpp index a29f54e8c..743e64033 100644 --- a/waylib/src/server/kernel/wsocket.cpp +++ b/waylib/src/server/kernel/wsocket.cpp @@ -145,39 +145,6 @@ class Q_DECL_HIDDEN WSocketPrivate : public WObjectPrivate QList clients; }; -struct Q_DECL_HIDDEN WlClientDestroyListener { - WlClientDestroyListener(WClient *client) - : client(client) - { - destroy.notify = handle_destroy; - } - - ~WlClientDestroyListener(); - - static WlClientDestroyListener *get(const wl_client *client); - static void handle_destroy(struct wl_listener *listener, void *); - - wl_listener destroy; - QPointer client; -}; - -WlClientDestroyListener::~WlClientDestroyListener() -{ - wl_list_remove(&destroy.link); -} - -WlClientDestroyListener *WlClientDestroyListener::get(const wl_client *client) -{ - wl_listener *listener = wl_client_get_destroy_listener(const_cast(client), - WlClientDestroyListener::handle_destroy); - if (!listener) { - return nullptr; - } - - WlClientDestroyListener *tmp = wl_container_of(listener, tmp, destroy); - return tmp; -} - static bool pauseClient(wl_client *client, bool pause) { pid_t pid = 0; @@ -232,49 +199,40 @@ class Q_DECL_HIDDEN WClientPrivate : public WObjectPrivate , handle(handle) , socket(socket) { - auto listener = new WlClientDestroyListener(qq); - wl_client_add_destroy_listener(handle, &listener->destroy); + destroyListener.notify = destroyListenerCallback; + wl_client_add_destroy_listener(handle, &destroyListener); } ~WClientPrivate() { if (pidFD >= 0) close(pidFD); - if (handle) { - auto listener = WlClientDestroyListener::get(handle); - Q_ASSERT(listener); - delete listener; - } + if (destroyListener.link.next && destroyListener.link.prev) + wl_list_remove(&destroyListener.link); + } + + static void destroyListenerCallback(struct wl_listener *listener, void *data) { + wl_client *handle = static_cast(data); + WClient *client = WClient::get(handle); + Q_ASSERT(client); + wl_list_remove(&client->d_func()->destroyListener.link); + client->socket()->removeClient(handle); } W_DECLARE_PUBLIC(WClient) + wl_listener destroyListener; wl_client *handle = nullptr; WSocket *socket = nullptr; mutable QSharedPointer credentials; mutable int pidFD = -1; }; -void WlClientDestroyListener::handle_destroy(wl_listener *listener, void *data) -{ - WlClientDestroyListener *self = wl_container_of(listener, self, destroy); - if (self->client) { - Q_ASSERT(reinterpret_cast(data) == self->client->handle()); - self->client->d_func()->handle = nullptr; - auto socket = self->client->socket(); - Q_ASSERT(socket); - bool ok = socket->removeClient(self->client); - Q_ASSERT(ok); - } - - delete self; -} - WClient::WClient(wl_client *client, WSocket *socket) : QObject(nullptr) , WObject(*new WClientPrivate(client, socket, this)) { - + wl_client_set_user_data(client, this, nullptr); } WSocket *WClient::socket() const @@ -324,9 +282,8 @@ QSharedPointer WClient::getCredentials(const wl_client *cl WClient *WClient::get(const wl_client *client) { - if (auto tmp = WlClientDestroyListener::get(client)) - return tmp->client; - return nullptr; + return static_cast( + wl_client_get_user_data(const_cast(client))); } void WClient::freeze()