connection: Always malloc closure
authorKristian Høgsberg <krh@bitplanet.net>
Tue, 12 Jun 2012 21:45:25 +0000 (17:45 -0400)
committerKristian Høgsberg <krh@bitplanet.net>
Wed, 13 Jun 2012 14:45:34 +0000 (10:45 -0400)
This lets us allocate the closure just big enough and is a first step towards
a message queue.

src/connection.c
src/wayland-client.c
src/wayland-private.h
src/wayland-server.c

index 5b7965e..448cc65 100644 (file)
@@ -403,12 +403,12 @@ wl_connection_put_fd(struct wl_connection *connection, int32_t fd)
        return 0;
 }
 
-int
-wl_closure_vmarshal(struct wl_closure *closure,
-                   struct wl_object *sender,
+struct wl_closure *
+wl_closure_vmarshal(struct wl_object *sender,
                    uint32_t opcode, va_list ap,
                    const struct wl_message *message)
 {
+       struct wl_closure *closure;
        struct wl_object **objectp, *object;
        uint32_t length, *p, *start, size, *end;
        int dup_fd;
@@ -417,11 +417,16 @@ wl_closure_vmarshal(struct wl_closure *closure,
        char *extra;
        int i, count, fd, extra_size, *fd_ptr;
 
+       /* FIXME: Match old fixed allocation for now */
+       closure = malloc(sizeof *closure + 1024);
+       if (closure == NULL)
+               return NULL;
+
        extra_size = wl_message_size_extra(message);
        count = strlen(message->signature) + 2;
        extra = (char *) closure->buffer;
        start = &closure->buffer[DIV_ROUNDUP(extra_size, sizeof *p)];
-       end = &closure->buffer[ARRAY_LENGTH(closure->buffer)];
+       end = &closure->buffer[256];
        p = &start[2];
 
        closure->types[0] = &ffi_type_pointer;
@@ -553,18 +558,18 @@ wl_closure_vmarshal(struct wl_closure *closure,
        ffi_prep_cif(&closure->cif, FFI_DEFAULT_ABI,
                     closure->count, &ffi_type_void, closure->types);
 
-       return 0;
+       return closure;
 
 err:
        printf("request too big to marshal, maximum size is %zu\n",
               sizeof closure->buffer);
        errno = ENOMEM;
-       return -1;
+
+       return NULL;
 }
 
-int
+struct wl_closure *
 wl_connection_demarshal(struct wl_connection *connection,
-                       struct wl_closure *closure,
                        uint32_t size,
                        struct wl_map *objects,
                        const struct wl_message *message)
@@ -575,23 +580,20 @@ wl_connection_demarshal(struct wl_connection *connection,
        unsigned int i, count, extra_space;
        struct wl_object **object;
        struct wl_array **array;
+       struct wl_closure *closure;
 
        count = strlen(message->signature) + 2;
        if (count > ARRAY_LENGTH(closure->types)) {
                printf("too many args (%d)\n", count);
                errno = EINVAL;
                wl_connection_consume(connection, size);
-               return -1;
+               return NULL;
        }
 
        extra_space = wl_message_size_extra(message);
-       if (sizeof closure->buffer < size + extra_space) {
-               printf("request too big to demarshal, maximum %zu actual %d\n",
-                      sizeof closure->buffer, size + extra_space);
-               errno = ENOMEM;
-               wl_connection_consume(connection, size);
-               return -1;
-       }
+       closure = malloc(sizeof *closure + 8 + size + extra_space);
+       if (closure == NULL)
+               return NULL;
 
        closure->message = message;
        closure->types[0] = &ffi_type_pointer;
@@ -748,14 +750,14 @@ wl_connection_demarshal(struct wl_connection *connection,
 
        wl_connection_consume(connection, size);
 
-       return 0;
+       return closure;
 
  err:
        closure->count = i;
        wl_closure_destroy(closure);
        wl_connection_consume(connection, size);
 
-       return -1;
+       return NULL;
 }
 
 void
@@ -884,4 +886,5 @@ wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send)
 void
 wl_closure_destroy(struct wl_closure *closure)
 {
+       free(closure);
 }
index bba972e..1ab94e8 100644 (file)
@@ -190,29 +190,28 @@ wl_proxy_add_listener(struct wl_proxy *proxy,
 WL_EXPORT void
 wl_proxy_marshal(struct wl_proxy *proxy, uint32_t opcode, ...)
 {
-       struct wl_closure closure;
+       struct wl_closure *closure;
        va_list ap;
-       int ret;
 
        va_start(ap, opcode);
-       ret = wl_closure_vmarshal(&closure, &proxy->object, opcode, ap,
-                                 &proxy->object.interface->methods[opcode]);
+       closure = wl_closure_vmarshal(&proxy->object, opcode, ap,
+                                     &proxy->object.interface->methods[opcode]);
        va_end(ap);
 
-       if (ret) {
+       if (closure == NULL) {
                fprintf(stderr, "Error marshalling request\n");
                abort();
        }
 
-       if (wl_closure_send(&closure, proxy->display->connection)) {
+       if (wl_closure_send(closure, proxy->display->connection)) {
                fprintf(stderr, "Error sending request: %m\n");
                abort();
        }
 
        if (wl_debug)
-               wl_closure_print(&closure, &proxy->object, true);
+               wl_closure_print(closure, &proxy->object, true);
 
-       wl_closure_destroy(&closure);
+       wl_closure_destroy(closure);
 }
 
 /* Can't do this, there may be more than one instance of an
@@ -468,9 +467,8 @@ handle_event(struct wl_display *display,
             uint32_t id, uint32_t opcode, uint32_t size)
 {
        struct wl_proxy *proxy;
-       struct wl_closure closure;
+       struct wl_closure *closure;
        const struct wl_message *message;
-       int ret;
 
        proxy = wl_map_lookup(&display->objects, id);
 
@@ -483,22 +481,22 @@ handle_event(struct wl_display *display,
        }
 
        message = &proxy->object.interface->events[opcode];
-       ret = wl_connection_demarshal(display->connection, &closure,
-                                     size, &display->objects, message);
+       closure = wl_connection_demarshal(display->connection, size,
+                                         &display->objects, message);
 
-       if (ret) {
+       if (closure == NULL) {
                fprintf(stderr, "Error demarshalling event\n");
                abort();
        }
 
        if (wl_debug)
-               wl_closure_print(&closure, &proxy->object, false);
+               wl_closure_print(closure, &proxy->object, false);
 
-       wl_closure_invoke(&closure, &proxy->object,
+       wl_closure_invoke(closure, &proxy->object,
                          proxy->object.implementation[opcode],
                          proxy->user_data);
 
-       wl_closure_destroy(&closure);
+       wl_closure_destroy(closure);
 }
 
 WL_EXPORT void
index c7af179..ea70258 100644 (file)
@@ -76,19 +76,17 @@ struct wl_closure {
        ffi_type *types[20];
        ffi_cif cif;
        void *args[20];
-       uint32_t buffer[256];
        uint32_t *start;
+       uint32_t buffer[0];
 };
 
-int
-wl_closure_vmarshal(struct wl_closure *closure,
-                   struct wl_object *sender,
+struct wl_closure *
+wl_closure_vmarshal(struct wl_object *sender,
                    uint32_t opcode, va_list ap,
                    const struct wl_message *message);
 
-int
+struct wl_closure *
 wl_connection_demarshal(struct wl_connection *connection,
-                       struct wl_closure *closure,
                        uint32_t size,
                        struct wl_map *objects,
                        const struct wl_message *message);
index 75f7e1f..010d9ca 100644 (file)
@@ -102,54 +102,52 @@ destroy_client(void *data)
 WL_EXPORT void
 wl_resource_post_event(struct wl_resource *resource, uint32_t opcode, ...)
 {
-       struct wl_closure closure;
+       struct wl_closure *closure;
        struct wl_object *object = &resource->object;
        va_list ap;
-       int ret;
 
        va_start(ap, opcode);
-       ret = wl_closure_vmarshal(&closure, object, opcode, ap,
-                                 &object->interface->events[opcode]);
+       closure = wl_closure_vmarshal(object, opcode, ap,
+                                     &object->interface->events[opcode]);
        va_end(ap);
 
-       if (ret)
+       if (closure == NULL)
                return;
 
-       if (wl_closure_send(&closure, resource->client->connection))
+       if (wl_closure_send(closure, resource->client->connection))
                wl_event_loop_add_idle(resource->client->display->loop,
                                       destroy_client, resource->client);
 
        if (wl_debug)
-               wl_closure_print(&closure, object, true);
+               wl_closure_print(closure, object, true);
 
-       wl_closure_destroy(&closure);
+       wl_closure_destroy(closure);
 }
 
 
 WL_EXPORT void
 wl_resource_queue_event(struct wl_resource *resource, uint32_t opcode, ...)
 {
-       struct wl_closure closure;
+       struct wl_closure *closure;
        struct wl_object *object = &resource->object;
        va_list ap;
-       int ret;
 
        va_start(ap, opcode);
-       ret = wl_closure_vmarshal(&closure, object, opcode, ap,
-                                 &object->interface->events[opcode]);
+       closure = wl_closure_vmarshal(object, opcode, ap,
+                                     &object->interface->events[opcode]);
        va_end(ap);
 
-       if (ret)
+       if (closure == NULL)
                return;
 
-       if (wl_closure_queue(&closure, resource->client->connection))
+       if (wl_closure_queue(closure, resource->client->connection))
                wl_event_loop_add_idle(resource->client->display->loop,
                                       destroy_client, resource->client);
 
        if (wl_debug)
-               wl_closure_print(&closure, object, true);
+               wl_closure_print(closure, object, true);
 
-       wl_closure_destroy(&closure);
+       wl_closure_destroy(closure);
 }
 
 WL_EXPORT void
@@ -187,12 +185,12 @@ wl_client_connection_data(int fd, uint32_t mask, void *data)
        struct wl_connection *connection = client->connection;
        struct wl_resource *resource;
        struct wl_object *object;
-       struct wl_closure closure;
+       struct wl_closure *closure;
        const struct wl_message *message;
        uint32_t p[2];
        int opcode, size;
        uint32_t cmask = 0;
-       int len, ret;
+       int len;
 
        if (mask & WL_EVENT_READABLE)
                cmask |= WL_CONNECTION_READABLE;
@@ -232,11 +230,11 @@ wl_client_connection_data(int fd, uint32_t mask, void *data)
                }
 
                message = &object->interface->methods[opcode];
-               ret = wl_connection_demarshal(client->connection, &closure,
-                                             size, &client->objects, message);
+               closure = wl_connection_demarshal(client->connection, size,
+                                                 &client->objects, message);
                len -= size;
 
-               if (ret && errno == EINVAL) {
+               if (closure == NULL && errno == EINVAL) {
                        wl_resource_post_error(client->display_resource,
                                               WL_DISPLAY_ERROR_INVALID_METHOD,
                                               "invalid arguments for %s@%d.%s",
@@ -244,18 +242,18 @@ wl_client_connection_data(int fd, uint32_t mask, void *data)
                                               object->id,
                                               message->name);
                        break;
-               } else if (ret && errno == ENOMEM) {
+               } else if (closure == NULL && errno == ENOMEM) {
                        wl_resource_post_no_memory(resource);
                        break;
                }
 
                if (wl_debug)
-                       wl_closure_print(&closure, object, false);
+                       wl_closure_print(closure, object, false);
 
-               wl_closure_invoke(&closure, object,
+               wl_closure_invoke(closure, object,
                                  object->implementation[opcode], client);
 
-               wl_closure_destroy(&closure);
+               wl_closure_destroy(closure);
 
                if (client->error)
                        break;