Commit 2fc248dc authored by Jason Ekstrand's avatar Jason Ekstrand Committed by Kristian H. Kristensen

Clean up and refactor wl_closure and associated functions

The primary purpose of this patch is to clean up wl_closure and separate
closure storage, libffi, and the wire format.  To that end, a number of changes
have been made:

 - The maximum number of closure arguments has been changed from a magic number
   to a #define WL_CLOSURE_MAX_ARGS

 - A wl_argument union has been added for storing a generalized closure
   argument and wl_closure has been converted to use wl_argument instead of the
   combination of libffi, the wire format, and a dummy extra buffer.  As of
   now, the "extra" field in wl_closure should be treated as bulk storage and
   never direclty referenced outside of wl_connection_demarshal.

 - Everything having to do with libffi has been moved into wl_closure_invoke
   and the convert_arguments_to_ffi helper function.

 - Everything having to do with the wire format has been restricted to
   wl_connection_demarshal and the new static serialize_closure function.  The
   wl_closure_send and wl_closure_queue functions are now light wrappers around
   serialize_closure.
Signed-off-by: Jason Ekstrand's avatarJason Ekstrand <jason@jlekstrand.net>
parent a51ed6d5
This diff is collapsed.
......@@ -669,21 +669,21 @@ create_proxies(struct wl_proxy *sender, struct wl_closure *closure)
int count;
signature = closure->message->signature;
count = arg_count_for_signature(signature) + 2;
for (i = 2; i < count; i++) {
count = arg_count_for_signature(signature);
for (i = 0; i < count; i++) {
signature = get_next_argument(signature, &arg);
switch (arg.type) {
case 'n':
id = **(uint32_t **) closure->args[i];
id = closure->args[i].n;
if (id == 0) {
*(void **) closure->args[i] = NULL;
closure->args[i].o = NULL;
break;
}
proxy = wl_proxy_create_for_id(sender, id,
closure->message->types[i - 2]);
closure->message->types[i]);
if (proxy == NULL)
return -1;
*(void **) closure->args[i] = proxy;
closure->args[i].o = (struct wl_object *)proxy;
break;
default:
break;
......@@ -702,13 +702,13 @@ increase_closure_args_refcount(struct wl_closure *closure)
struct wl_proxy *proxy;
signature = closure->message->signature;
count = arg_count_for_signature(signature) + 2;
for (i = 2; i < count; i++) {
count = arg_count_for_signature(signature);
for (i = 0; i < count; i++) {
signature = get_next_argument(signature, &arg);
switch (arg.type) {
case 'n':
case 'o':
proxy = *(struct wl_proxy **) closure->args[i];
proxy = (struct wl_proxy *) closure->args[i].o;
if (proxy)
proxy->refcount++;
break;
......@@ -779,16 +779,16 @@ decrease_closure_args_refcount(struct wl_closure *closure)
struct wl_proxy *proxy;
signature = closure->message->signature;
count = arg_count_for_signature(signature) + 2;
for (i = 2; i < count; i++) {
count = arg_count_for_signature(signature);
for (i = 0; i < count; i++) {
signature = get_next_argument(signature, &arg);
switch (arg.type) {
case 'n':
case 'o':
proxy = *(struct wl_proxy **) closure->args[i];
proxy = (struct wl_proxy *) closure->args[i].o;
if (proxy) {
if (proxy->flags & WL_PROXY_FLAG_DESTROYED)
*(void **) closure->args[i] = NULL;
closure->args[i].o = NULL;
proxy->refcount--;
if (!proxy->refcount)
......@@ -812,7 +812,7 @@ dispatch_event(struct wl_display *display, struct wl_event_queue *queue)
closure = container_of(queue->event_list.next,
struct wl_closure, link);
wl_list_remove(&closure->link);
opcode = closure->buffer[1] & 0xffff;
opcode = closure->opcode;
/* Verify that the receiving object is still valid by checking if has
* been destroyed by the application. */
......
/*
* Copyright © 2008-2011 Kristian Høgsberg
* Copyright © 2011 Intel Corporation
* Copyright © 2013 Jason Ekstrand
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
......@@ -25,7 +26,6 @@
#define WAYLAND_PRIVATE_H
#include <stdarg.h>
#include <ffi.h>
#include "wayland-util.h"
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
......@@ -39,6 +39,7 @@
#define WL_MAP_SERVER_SIDE 0
#define WL_MAP_CLIENT_SIDE 1
#define WL_SERVER_ID_START 0xff000000
#define WL_CLOSURE_MAX_ARGS 20
struct wl_map {
struct wl_array client_entries;
......@@ -73,16 +74,26 @@ int wl_connection_write(struct wl_connection *connection, const void *data, size
int wl_connection_queue(struct wl_connection *connection,
const void *data, size_t count);
union wl_argument {
int32_t i;
uint32_t u;
wl_fixed_t f;
const char *s;
struct wl_object *o;
uint32_t n;
struct wl_array *a;
int32_t h;
};
struct wl_closure {
int count;
const struct wl_message *message;
ffi_type *types[20];
ffi_cif cif;
void *args[20];
uint32_t *start;
uint32_t opcode;
uint32_t sender_id;
union wl_argument args[WL_CLOSURE_MAX_ARGS];
struct wl_list link;
struct wl_proxy *proxy;
uint32_t buffer[0];
struct wl_array extra[0];
};
struct argument_details {
......@@ -96,6 +107,14 @@ get_next_argument(const char *signature, struct argument_details *details);
int
arg_count_for_signature(const char *signature);
void
wl_argument_from_va_list(const char *signature, union wl_argument *args,
int count, va_list ap);
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 *
wl_closure_vmarshal(struct wl_object *sender,
uint32_t opcode, va_list ap,
......
......@@ -191,23 +191,6 @@ wl_resource_post_error(struct wl_resource *resource,
WL_DISPLAY_ERROR, resource, code, buffer);
}
static void
deref_new_objects(struct wl_closure *closure)
{
const char *signature;
int i;
signature = closure->message->signature;
for (i = 0; signature[i]; i++) {
switch (signature[i]) {
case 'n':
closure->args[i + 2] = *(uint32_t **) closure->args[i + 2];
closure->types[i] = &ffi_type_uint32;
break;
}
}
}
static int
wl_client_connection_data(int fd, uint32_t mask, void *data)
{
......@@ -294,8 +277,6 @@ wl_client_connection_data(int fd, uint32_t mask, void *data)
if (wl_debug)
wl_closure_print(closure, object, false);
deref_new_objects(closure);
wl_closure_invoke(closure, object,
object->implementation[opcode], client);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment