[RFC 1/2] server: add wl_guard and convert one user

Pekka Paalanen ppaalanen at gmail.com
Fri Mar 2 04:10:06 PST 2012


From: Pekka Paalanen <ppaalanen at gmail.com>

In wayland and weston code bases we have roughly a dozen destroy
listeners whose only job is to set a pointer to NULL, if a wl_resource
object gets destroyed.

Introduce struct wl_guard as a shorthand for replacing all these trivial
callbacks.

One case in data-device.c is converted as an example.

Signed-off-by: Pekka Paalanen <ppaalanen at gmail.com>
---

Sent by hand since this is just a RFC. The next patch is the real
question...

 src/data-device.c    |   18 ++----------------
 src/wayland-server.c |   30 ++++++++++++++++++++++++++++++
 src/wayland-server.h |   15 ++++++++++++++-
 3 files changed, 46 insertions(+), 17 deletions(-)

diff --git a/src/data-device.c b/src/data-device.c
index f0f6baa..ce55c7a 100644
--- a/src/data-device.c
+++ b/src/data-device.c
@@ -66,7 +66,7 @@ destroy_data_offer(struct wl_resource *resource)
 {
 	struct wl_data_offer *offer = resource->data;
 
-	wl_list_remove(&offer->source_destroy_listener.link);
+	wl_guard_unset(&offer->source_guard);
 	free(offer);
 }
 
@@ -77,18 +77,6 @@ static const struct wl_data_offer_interface data_offer_interface = {
 };
 
 static void
-destroy_offer_data_source(struct wl_listener *listener,
-			  struct wl_resource *resource, uint32_t time)
-{
-	struct wl_data_offer *offer;
-
-	offer = container_of(listener, struct wl_data_offer,
-			     source_destroy_listener);
-
-	offer->source = NULL;
-}
-
-static void
 data_source_cancel(struct wl_data_source *source)
 {
 	wl_resource_post_event(&source->resource, WL_DATA_SOURCE_CANCELLED);
@@ -114,9 +102,7 @@ wl_data_source_send_offer(struct wl_data_source *source,
 	wl_list_init(&offer->resource.destroy_listener_list);
 
 	offer->source = source;
-	offer->source_destroy_listener.func = destroy_offer_data_source;
-	wl_list_insert(&source->resource.destroy_listener_list,
-		       &offer->source_destroy_listener.link);
+	wl_guard_set(&offer->source_guard, &source->resource, &offer->source);
 
 	wl_client_add_resource(target->client, &offer->resource);
 
diff --git a/src/wayland-server.c b/src/wayland-server.c
index 6a8cbcb..1fa2f4d 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -1030,3 +1030,33 @@ wl_client_new_object(struct wl_client *client,
 				    interface, implementation, id, data);
 
 }
+
+static void
+guard_handle_resource_destroy(struct wl_listener *listener,
+			      struct wl_resource *resource, uint32_t time)
+{
+	struct wl_guard *guard =
+		container_of(listener, struct wl_guard, listener);
+
+	*(guard->pointer) = NULL;
+}
+
+WL_EXPORT void
+wl_guard_set(struct wl_guard *guard, struct wl_resource *resource,
+	     void *pointer_address)
+{
+	assert(pointer_address != NULL);
+
+	guard->listener.func = guard_handle_resource_destroy;
+	wl_list_insert(resource->destroy_listener_list.prev,
+		       &guard->listener.link);
+	guard->pointer = pointer_address;
+}
+
+WL_EXPORT void
+wl_guard_unset(struct wl_guard *guard)
+{
+	if (*(guard->pointer))
+		wl_list_remove(&guard->listener.link);
+	*(guard->pointer) = NULL;
+}
diff --git a/src/wayland-server.h b/src/wayland-server.h
index 49ab5b1..af3138f 100644
--- a/src/wayland-server.h
+++ b/src/wayland-server.h
@@ -144,6 +144,12 @@ struct wl_listener {
 		     struct wl_resource *resource, uint32_t time);
 };
 
+/* A guardian for pointers that depend on a specific wl_resource object. */
+struct wl_guard {
+	struct wl_listener listener;
+	void **pointer;
+};
+
 struct wl_surface {
 	struct wl_resource resource;
 };
@@ -181,7 +187,7 @@ struct wl_keyboard_grab {
 struct wl_data_offer {
 	struct wl_resource resource;
 	struct wl_data_source *source;
-	struct wl_listener source_destroy_listener;
+	struct wl_guard source_guard;
 };
 
 struct wl_data_source {
@@ -343,6 +349,13 @@ wl_shm_init(struct wl_display *display,
 void
 wl_shm_finish(struct wl_shm *shm);
 
+void
+wl_guard_set(struct wl_guard *guard, struct wl_resource *resource,
+	     void *pointer_address);
+
+void
+wl_guard_unset(struct wl_guard *guard);
+
 #ifdef  __cplusplus
 }
 #endif
-- 
1.7.3.4



More information about the wayland-devel mailing list