[PATCH] client: "Ex" versions of constructors, alternative to proxy_wrapper

spitzak at gmail.com spitzak at gmail.com
Tue May 3 05:42:01 UTC 2016


From: Bill Spitzak <spitzak at gmail.com>

Scanner produces a xyz_create() for each object that wraps the
wl_proxy_create function. For each constructor request a new "Ex" version
is created that takes the created object. This allows the queue to be set
before creation. The existing code using proxy_wrapper changed to use this.

Comments/questions:

wl_registry_bindEx is nyi and is needed (the proxy_wrapper does not fix this either).

You cannot use create for an object provided by an event, and I see no good
way to achieve this. Not very important unless static wl_proxy is supported.

It may be better for the create function to take an actual factory proxy pointer,
rather than a wl_proxy*, to avoid casts. However there are a few cases where the
same object has multiple factory objects. But this is rare enough that putting
the factory name into the create function name is undesirable.

Create function is useless if there is no constructor request and maybe should
not be produced.

It may be desirable to delay allocation of the id until the wl_proxy_marshal.
This would remove the lock from wl_proxy_create and greatly reduce the code
executed while the lock is held in normal constructors. Not clear if anything
is relying on the id being set by wl_proxy_create.

I was hoping this would allow use of static wl_proxy structures (or more importantly
ones on the stack or embedded in larger objects). However the handling of queued
events is preventing this. A rewrite where wl_proxy_destroy fixes the queued
events rather than having the events reference-count the proxies would fix this
but would be pretty major.

Signed-off-by: Bill Spitzak <spitzak at gmail.com>
---
 src/scanner.c        | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/wayland-client.c | 15 ++++----------
 tests/queue-test.c   |  9 +++-----
 3 files changed, 65 insertions(+), 17 deletions(-)

diff --git a/src/scanner.c b/src/scanner.c
index 52c07a6..a6b9d3a 100644
--- a/src/scanner.c
+++ b/src/scanner.c
@@ -1129,6 +1129,50 @@ emit_stubs(struct wl_list *message_list, struct interface *interface)
 			       ret->interface_name, ret->name);
 
 		printf("}\n\n");
+
+		/* Produce the Ex version of constructor calls.
+		 * FIXME: this is a cut + paste patch, it would be better
+		 * to reuse the above code and/or make the old constructor
+		 * be the special case.
+		 */
+		if (!ret || !ret->interface_name)
+			continue;
+		printf("/**\n"
+		       " * @ingroup iface_%s\n", interface->name);
+		printf(" *\n"
+		       " * Same as %s_%s() except it uses an existing proxy created by\n"
+		       " * %s_create().\n"
+		       " */\n", interface->name, m->name, ret->interface_name);
+		printf("static inline void\n");
+
+		printf("%s_%sEx(struct %s *%s",
+		       interface->name, m->name,
+		       interface->name, interface->name);
+
+		wl_list_for_each(a, &m->arg_list, link) {
+			printf(", ");
+			if (a->type == NEW_ID) {
+				printf("struct %s *", ret->interface_name);
+			} else {
+				emit_type(a);
+			}
+			printf("%s", a->name);
+		}
+
+		printf(")\n"
+		       "{\n"
+		       "\twl_proxy_marshal((struct wl_proxy *) %s,\n"
+		       "\t\t\t %s_%s",
+		       interface->name,
+		       interface->uppercase_name,
+		       m->uppercase_name);
+
+		wl_list_for_each(a, &m->arg_list, link) {
+			printf(", %s", a->name);
+		}
+		printf(");\n");
+
+		printf("}\n\n");
 	}
 }
 
@@ -1302,6 +1346,20 @@ emit_structs(struct wl_list *message_list, struct interface *interface, enum sid
 	printf("};\n\n");
 
 	if (side == CLIENT) {
+	    if (strcmp(interface->name, "wl_display"))
+	        printf("/**\n"
+		   " * @ingroup %s_iface\n"
+		   " *\n"
+		   " * Create a %s and allocate an id.\n"
+		   " */\n"
+		   "static inline struct %s *\n"
+		   "%s_create(struct wl_proxy *factory)\n"
+		   "{\n"
+		   "\treturn (struct %s *) wl_proxy_create(factory, &%s_interface);\n"
+		   "}\n\n",
+		   interface->name, interface->name, interface->name,
+		   interface->name, interface->name, interface->name);
+
 	    printf("/**\n"
 		   " * @ingroup %s_iface\n"
 		   " */\n", interface->name);
diff --git a/src/wayland-client.c b/src/wayland-client.c
index 7af806c..61acaee 100644
--- a/src/wayland-client.c
+++ b/src/wayland-client.c
@@ -1099,24 +1099,17 @@ static const struct wl_callback_listener sync_listener = {
 WL_EXPORT int
 wl_display_roundtrip_queue(struct wl_display *display, struct wl_event_queue *queue)
 {
-	struct wl_display *display_wrapper;
 	struct wl_callback *callback;
 	int done, ret = 0;
 
 	done = 0;
-
-	display_wrapper = wl_proxy_create_wrapper(display);
-	if (!display_wrapper)
-		return -1;
-
-	wl_proxy_set_queue((struct wl_proxy *) display_wrapper, queue);
-	callback = wl_display_sync(display_wrapper);
-	wl_proxy_wrapper_destroy(display_wrapper);
-
+	callback = wl_callback_create((struct wl_proxy *) display);
 	if (callback == NULL)
 		return -1;
-
+	wl_proxy_set_queue((struct wl_proxy *) callback, queue);
 	wl_callback_add_listener(callback, &sync_listener, &done);
+	wl_display_syncEx(display, callback);
+
 	while (!done && ret >= 0)
 		ret = wl_display_dispatch_queue(display, queue);
 
diff --git a/tests/queue-test.c b/tests/queue-test.c
index 932bc55..a4f3efb 100644
--- a/tests/queue-test.c
+++ b/tests/queue-test.c
@@ -209,7 +209,6 @@ client_test_queue_proxy_wrapper(void)
 {
 	struct wl_event_queue *queue;
 	struct wl_display *display;
-	struct wl_display *display_wrapper;
 	struct wl_callback *callback;
 	bool done = false;
 
@@ -226,12 +225,10 @@ client_test_queue_proxy_wrapper(void)
 	queue = wl_display_create_queue(display);
 	assert(queue);
 
-	display_wrapper = wl_proxy_create_wrapper(display);
-	assert(display_wrapper);
-	wl_proxy_set_queue((struct wl_proxy *) display_wrapper, queue);
-	callback = wl_display_sync(display_wrapper);
-	wl_proxy_wrapper_destroy(display_wrapper);
+	callback = wl_callback_create((struct wl_proxy *) display);
 	assert(callback != NULL);
+	wl_proxy_set_queue((struct wl_proxy *) callback, queue);
+	wl_display_syncEx(display, callback);
 
 	/* Pretend we are now another thread and dispatch the dispatch the main
 	 * queue while also knowing our callback is read and queued. */
-- 
1.9.1



More information about the wayland-devel mailing list