aboutsummaryrefslogtreecommitdiffstats
path: root/src/connection.c
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2012-10-09 12:14:34 -0400
committerKristian Høgsberg <krh@bitplanet.net>2012-10-10 22:01:17 -0400
commit5d2b32b1fd14fddd3920205d1368cf0e499fc6ff (patch)
tree9b7bd99895ac836d60e54b1197334b9e720d3420 /src/connection.c
parentSplit the global registry into its own wl_registry object (diff)
downloadwayland-5d2b32b1fd14fddd3920205d1368cf0e499fc6ff.tar
wayland-5d2b32b1fd14fddd3920205d1368cf0e499fc6ff.tar.gz
wayland-5d2b32b1fd14fddd3920205d1368cf0e499fc6ff.tar.bz2
wayland-5d2b32b1fd14fddd3920205d1368cf0e499fc6ff.tar.lz
wayland-5d2b32b1fd14fddd3920205d1368cf0e499fc6ff.tar.xz
wayland-5d2b32b1fd14fddd3920205d1368cf0e499fc6ff.tar.zst
wayland-5d2b32b1fd14fddd3920205d1368cf0e499fc6ff.zip
connection: Move object lookup out of wl_connection_demarshal()
On the client side where we queue up multiple events before dispatching, we need to look up the receiving proxy and argument proxies immediately before calling the handler. Between queueing up multiple events and eventually invoking the handler, previous handlers may have destroyed some of the proxies.
Diffstat (limited to 'src/connection.c')
-rw-r--r--src/connection.c81
1 files changed, 53 insertions, 28 deletions
diff --git a/src/connection.c b/src/connection.c
index ce6fac6..0958fe0 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -706,12 +706,13 @@ wl_connection_demarshal(struct wl_connection *connection,
break;
case 'o':
closure->types[i] = &ffi_type_pointer;
- object = (struct wl_object **) extra;
- extra += sizeof *object;
- closure->args[i] = object;
+ id = (uint32_t **) extra;
+ extra += sizeof *id;
+ closure->args[i] = id;
+ *id = p;
- if (*p == 0 && !arg.nullable) {
- printf("NULL new ID received on non-nullable "
+ if (*id == 0 && !arg.nullable) {
+ printf("NULL object received on non-nullable "
"type, message %s(%s)\n", message->name,
message->signature);
*object = NULL;
@@ -719,29 +720,6 @@ wl_connection_demarshal(struct wl_connection *connection,
goto err;
}
- *object = wl_map_lookup(objects, *p);
- if (*object == WL_ZOMBIE_OBJECT) {
- /* references object we've already
- * destroyed client side */
- *object = NULL;
- } else if (*object == NULL && *p != 0) {
- printf("unknown object (%u), message %s(%s)\n",
- *p, message->name, message->signature);
- *object = NULL;
- errno = EINVAL;
- goto err;
- }
-
- if (*object != NULL && message->types[i-2] != NULL &&
- (*object)->interface != message->types[i-2]) {
- printf("invalid object (%u), type (%s), "
- "message %s(%s)\n",
- *p, (*object)->interface->name,
- message->name, message->signature);
- errno = EINVAL;
- goto err;
- }
-
p++;
break;
case 'n':
@@ -828,6 +806,53 @@ wl_connection_demarshal(struct wl_connection *connection,
return NULL;
}
+int
+wl_closure_lookup_objects(struct wl_closure *closure, struct wl_map *objects)
+{
+ struct wl_object **object;
+ const struct wl_message *message;
+ const char *signature;
+ struct argument_details arg;
+ int i, count;
+ uint32_t id;
+
+ message = closure->message;
+ signature = message->signature;
+ count = arg_count_for_signature(signature) + 2;
+ for (i = 2; i < count; i++) {
+ signature = get_next_argument(signature, &arg);
+ switch (arg.type) {
+ case 'o':
+ id = **(uint32_t **) closure->args[i];
+ object = closure->args[i];
+ *object = wl_map_lookup(objects, id);
+ if (*object == WL_ZOMBIE_OBJECT) {
+ /* references object we've already
+ * destroyed client side */
+ *object = NULL;
+ } else if (*object == NULL && id != 0) {
+ printf("unknown object (%u), message %s(%s)\n",
+ id, message->name, message->signature);
+ *object = NULL;
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (*object != NULL && message->types[i-2] != NULL &&
+ (*object)->interface != message->types[i-2]) {
+ printf("invalid object (%u), type (%s), "
+ "message %s(%s)\n",
+ id, (*object)->interface->name,
+ message->name, message->signature);
+ errno = EINVAL;
+ return -1;
+ }
+ }
+ }
+
+ return 0;
+}
+
void
wl_closure_invoke(struct wl_closure *closure,
struct wl_object *target, void (*func)(void), void *data)