connection: Refactor out closure allocation
authorDerek Foreman <derekf@osg.samsung.com>
Wed, 6 Dec 2017 17:22:18 +0000 (11:22 -0600)
committerDaniel Stone <daniels@collabora.com>
Wed, 27 Dec 2017 13:59:48 +0000 (13:59 +0000)
Moves the common/similar bits into one place.

This has a minor functional change - count and message are now initialized
immediately, previously they'd only be set if (de)marshal was successful.

Signed-off-by: Derek Foreman <derekf@osg.samsung.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
src/connection.c

index d029914..8d8eb60 100644 (file)
@@ -524,16 +524,12 @@ wl_argument_from_va_list(const char *signature, union wl_argument *args,
        }
 }
 
-struct wl_closure *
-wl_closure_marshal(struct wl_object *sender, uint32_t opcode,
-                  union wl_argument *args,
-                  const struct wl_message *message)
+static struct wl_closure *
+wl_closure_init(const struct wl_message *message, uint32_t size,
+                int *num_arrays, union wl_argument *args)
 {
        struct wl_closure *closure;
-       struct wl_object *object;
-       int i, count, fd, dup_fd;
-       const char *signature;
-       struct argument_details arg;
+       int count;
 
        count = arg_count_for_signature(message->signature);
        if (count > WL_CLOSURE_MAX_ARGS) {
@@ -542,13 +538,44 @@ wl_closure_marshal(struct wl_object *sender, uint32_t opcode,
                return NULL;
        }
 
-       closure = malloc(sizeof *closure);
-       if (closure == NULL) {
+       if (size) {
+               *num_arrays = wl_message_count_arrays(message);
+               closure = malloc(sizeof *closure + size +
+                                *num_arrays * sizeof(struct wl_array));
+       } else {
+               closure = malloc(sizeof *closure);
+       }
+
+       if (!closure) {
                errno = ENOMEM;
                return NULL;
        }
 
-       memcpy(closure->args, args, count * sizeof *args);
+       if (args)
+               memcpy(closure->args, args, count * sizeof *args);
+
+       closure->message = message;
+       closure->count = count;
+
+       return closure;
+}
+
+struct wl_closure *
+wl_closure_marshal(struct wl_object *sender, uint32_t opcode,
+                  union wl_argument *args,
+                  const struct wl_message *message)
+{
+       struct wl_closure *closure;
+       struct wl_object *object;
+       int i, count, fd, dup_fd;
+       const char *signature;
+       struct argument_details arg;
+
+       closure = wl_closure_init(message, 0, NULL, args);
+       if (closure == NULL)
+               return NULL;
+
+       count = closure->count;
 
        signature = message->signature;
        for (i = 0; i < count; i++) {
@@ -593,8 +620,6 @@ wl_closure_marshal(struct wl_object *sender, uint32_t opcode,
 
        closure->sender_id = sender->id;
        closure->opcode = opcode;
-       closure->message = message;
-       closure->count = count;
 
        return closure;
 
@@ -628,29 +653,20 @@ wl_connection_demarshal(struct wl_connection *connection,
        uint32_t *p, *next, *end, length, id;
        int fd;
        char *s;
-       unsigned int i, count, num_arrays;
+       int i, count, num_arrays;
        const char *signature;
        struct argument_details arg;
        struct wl_closure *closure;
        struct wl_array *array_extra;
 
-       count = arg_count_for_signature(message->signature);
-       if (count > WL_CLOSURE_MAX_ARGS) {
-               wl_log("too many args (%d)\n", count);
-               errno = EINVAL;
-               wl_connection_consume(connection, size);
-               return NULL;
-       }
-
-       num_arrays = wl_message_count_arrays(message);
-       closure = malloc(sizeof *closure + size +
-                        num_arrays * sizeof(struct wl_array));
+       closure = wl_closure_init(message, size, &num_arrays, NULL);
        if (closure == NULL) {
-               errno = ENOMEM;
                wl_connection_consume(connection, size);
                return NULL;
        }
 
+       count = closure->count;
+
        array_extra = closure->extra;
        p = (uint32_t *)(closure->extra + num_arrays);
        end = p + size / sizeof *p;
@@ -785,9 +801,6 @@ wl_connection_demarshal(struct wl_connection *connection,
                }
        }
 
-       closure->count = count;
-       closure->message = message;
-
        wl_connection_consume(connection, size);
 
        return closure;