From: Bill Spitzak <[email protected]>

Splits the allocation of wl_proxy from the assignment of the id. This removes
some code such as the malloc from the lock, possibly improving multithreaded
performance.

Removes unnecessary lock in wl_proxy_create_wrapper.

This does not change the public api.

Signed-off-by: Bill Spitzak <[email protected]>
---
 src/wayland-client.c | 157 +++++++++++++++++++++++++--------------------------
 1 file changed, 77 insertions(+), 80 deletions(-)

diff --git a/src/wayland-client.c b/src/wayland-client.c
index 03c087a..9934cd2 100644
--- a/src/wayland-client.c
+++ b/src/wayland-client.c
@@ -325,24 +325,13 @@ wl_display_create_queue(struct wl_display *display)
 }
 
 static struct wl_proxy *
-proxy_create(struct wl_proxy *factory, const struct wl_interface *interface,
-            uint32_t version)
+proxy_new(const struct wl_interface *interface)
 {
-       struct wl_proxy *proxy;
-       struct wl_display *display = factory->display;
-
-       proxy = zalloc(sizeof *proxy);
-       if (proxy == NULL)
-               return NULL;
-
-       proxy->object.interface = interface;
-       proxy->display = display;
-       proxy->queue = factory->queue;
-       proxy->refcount = 1;
-       proxy->version = version;
-
-       proxy->object.id = wl_map_insert_new(&display->objects, 0, proxy);
-
+       struct wl_proxy *proxy = zalloc(sizeof *proxy);
+       if (proxy) {
+               proxy->object.interface = interface;
+               proxy->refcount = 1;
+       }
        return proxy;
 }
 
@@ -369,10 +358,16 @@ WL_EXPORT struct wl_proxy *
 wl_proxy_create(struct wl_proxy *factory, const struct wl_interface *interface)
 {
        struct wl_display *display = factory->display;
-       struct wl_proxy *proxy;
+       struct wl_proxy *proxy = proxy_new(interface);
+       if (proxy == NULL)
+               return NULL;
+
+       proxy->display = display;
+       proxy->queue = factory->queue;
+       proxy->version = factory->version;
 
        pthread_mutex_lock(&display->mutex);
-       proxy = proxy_create(factory, interface, factory->version);
+       proxy->object.id = wl_map_insert_new(&display->objects, 0, proxy);
        pthread_mutex_unlock(&display->mutex);
 
        return proxy;
@@ -383,19 +378,15 @@ static struct wl_proxy *
 wl_proxy_create_for_id(struct wl_proxy *factory,
                       uint32_t id, const struct wl_interface *interface)
 {
-       struct wl_proxy *proxy;
        struct wl_display *display = factory->display;
-
-       proxy = zalloc(sizeof *proxy);
+       struct wl_proxy *proxy = proxy_new(interface);
        if (proxy == NULL)
                return NULL;
 
-       proxy->object.interface = interface;
-       proxy->object.id = id;
        proxy->display = display;
        proxy->queue = factory->queue;
-       proxy->refcount = 1;
        proxy->version = factory->version;
+       proxy->object.id = id;
 
        wl_map_insert_at(&display->objects, 0, id, proxy);
 
@@ -539,33 +530,63 @@ wl_proxy_add_dispatcher(struct wl_proxy *proxy,
        return 0;
 }
 
-static struct wl_proxy *
-create_outgoing_proxy(struct wl_proxy *proxy, const struct wl_message *message,
-                     union wl_argument *args,
-                     const struct wl_interface *interface, uint32_t version)
+/* Return index of the new_id argument */
+static int
+new_id_index(struct wl_proxy *proxy, uint32_t opcode)
 {
-       int i, count;
-       const char *signature;
-       struct argument_details arg;
-       struct wl_proxy *new_proxy = NULL;
-
-       signature = message->signature;
-       count = arg_count_for_signature(signature);
-       for (i = 0; i < count; i++) {
+       int i;
+       const struct wl_message *message =
+               &proxy->object.interface->methods[opcode];
+       const char *signature = message->signature;
+       int count = arg_count_for_signature(signature);
+       for (i = 0; ; i++) {
+               struct argument_details arg;
+               if (i >= count)
+                       wl_abort("Missing new_id argument");
                signature = get_next_argument(signature, &arg);
+               if (arg.type == 'n')
+                       break;
+       }
+       return i;
+}
 
-               switch (arg.type) {
-               case 'n':
-                       new_proxy = proxy_create(proxy, interface, version);
-                       if (new_proxy == NULL)
-                               return NULL;
+/* Does wl_proxy_marshal_array, but also allocates an id for new_proxy
+ * if it is not null before sending the message (which requires the
+ * lock that this holds).
+ */
+static void
+proxy_marshal_array(struct wl_proxy *proxy,
+                   uint32_t opcode,
+                   union wl_argument *args,
+                   struct wl_proxy *new_proxy)
+{
+       struct wl_closure *closure;
+       const struct wl_message *message;
 
-                       args[i].o = &new_proxy->object;
-                       break;
-               }
+       pthread_mutex_lock(&proxy->display->mutex);
+
+       if (new_proxy) {
+               if (new_proxy->object.id)
+                       wl_abort("Proxy %p already has an id\n", new_proxy);
+               new_proxy->object.id =
+                       wl_map_insert_new(&proxy->display->objects, 0, 
new_proxy);
        }
 
-       return new_proxy;
+       message = &proxy->object.interface->methods[opcode];
+
+       closure = wl_closure_marshal(&proxy->object, opcode, args, message);
+       if (closure == NULL)
+               wl_abort("Error marshalling request: %s\n", strerror(errno));
+
+       if (debug_client)
+               wl_closure_print(closure, &proxy->object, true);
+
+       if (wl_closure_send(closure, proxy->display->connection))
+               wl_abort("Error sending request: %s\n", strerror(errno));
+
+       wl_closure_destroy(closure);
+
+       pthread_mutex_unlock(&proxy->display->mutex);
 }
 
 /** Prepare a request to be sent to the compositor
@@ -633,35 +654,19 @@ wl_proxy_marshal_array_constructor_versioned(struct 
wl_proxy *proxy,
                                             const struct wl_interface 
*interface,
                                             uint32_t version)
 {
-       struct wl_closure *closure;
        struct wl_proxy *new_proxy = NULL;
-       const struct wl_message *message;
-
-       pthread_mutex_lock(&proxy->display->mutex);
 
-       message = &proxy->object.interface->methods[opcode];
        if (interface) {
-               new_proxy = create_outgoing_proxy(proxy, message,
-                                                 args, interface,
-                                                 version);
+               new_proxy = proxy_new(interface);
                if (new_proxy == NULL)
-                       goto err_unlock;
+                       return NULL;
+               new_proxy->display = proxy->display;
+               new_proxy->queue = proxy->queue;
+               new_proxy->version = version;
+               args[new_id_index(proxy, opcode)].o = &new_proxy->object;
        }
 
-       closure = wl_closure_marshal(&proxy->object, opcode, args, message);
-       if (closure == NULL)
-               wl_abort("Error marshalling request: %s\n", strerror(errno));
-
-       if (debug_client)
-               wl_closure_print(closure, &proxy->object, true);
-
-       if (wl_closure_send(closure, proxy->display->connection))
-               wl_abort("Error sending request: %s\n", strerror(errno));
-
-       wl_closure_destroy(closure);
-
- err_unlock:
-       pthread_mutex_unlock(&proxy->display->mutex);
+       proxy_marshal_array(proxy, opcode, args, new_proxy);
 
        return new_proxy;
 }
@@ -693,7 +698,7 @@ wl_proxy_marshal(struct wl_proxy *proxy, uint32_t opcode, 
...)
                                 args, WL_CLOSURE_MAX_ARGS, ap);
        va_end(ap);
 
-       wl_proxy_marshal_array_constructor(proxy, opcode, args, NULL);
+       proxy_marshal_array(proxy, opcode, args, NULL);
 }
 
 /** Prepare a request to be sent to the compositor
@@ -794,7 +799,7 @@ WL_EXPORT void
 wl_proxy_marshal_array(struct wl_proxy *proxy, uint32_t opcode,
                       union wl_argument *args)
 {
-       wl_proxy_marshal_array_constructor(proxy, opcode, args, NULL);
+       proxy_marshal_array(proxy, opcode, args, NULL);
 }
 
 static void
@@ -2029,23 +2034,15 @@ WL_EXPORT void *
 wl_proxy_create_wrapper(void *proxy)
 {
        struct wl_proxy *wrapped_proxy = proxy;
-       struct wl_proxy *wrapper;
-
-       wrapper = zalloc(sizeof *wrapper);
+       struct wl_proxy *wrapper = proxy_new(wrapped_proxy->object.interface);
        if (!wrapper)
                return NULL;
 
-       pthread_mutex_lock(&wrapped_proxy->display->mutex);
-
-       wrapper->object.interface = wrapped_proxy->object.interface;
        wrapper->object.id = wrapped_proxy->object.id;
        wrapper->version = wrapped_proxy->version;
        wrapper->display = wrapped_proxy->display;
        wrapper->queue = wrapped_proxy->queue;
        wrapper->flags = WL_PROXY_FLAG_WRAPPER;
-       wrapper->refcount = 1;
-
-       pthread_mutex_unlock(&wrapped_proxy->display->mutex);
 
        return wrapper;
 }
-- 
1.9.1

_______________________________________________
wayland-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to