diff --git a/src/connection.c b/src/connection.c index 5b7965e9..448cc65d 100644 --- a/src/connection.c +++ b/src/connection.c @@ -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); } diff --git a/src/wayland-client.c b/src/wayland-client.c index bba972e5..1ab94e8a 100644 --- a/src/wayland-client.c +++ b/src/wayland-client.c @@ -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 diff --git a/src/wayland-private.h b/src/wayland-private.h index c7af179c..ea702584 100644 --- a/src/wayland-private.h +++ b/src/wayland-private.h @@ -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); diff --git a/src/wayland-server.c b/src/wayland-server.c index 75f7e1f0..010d9ca3 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -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;