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 b30be63c1f
commit 2551feb17e
4 changed files with 399 additions and 352 deletions

View file

@ -1,6 +1,7 @@
/*
* 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,