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 <jason@jlekstrand.net>
This commit is contained in:
Jason Ekstrand 2013-02-26 11:30:51 -05:00 committed by Kristian Høgsberg
parent a51ed6d50f
commit 2fc248dc2c
4 changed files with 399 additions and 352 deletions

View file

@ -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. */