summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2013-11-14 21:29:06 -0800
committerKristian Høgsberg <krh@bitplanet.net>2013-11-14 21:29:06 -0800
commit00345b3b4a0b48fc83920e25f38fb50c2115d491 (patch)
treed3e5fc910be3eb507f60a25ba06acf6b6ad63b0f
parent05f95c85c8cad07bee233f1d4e205a12538365e1 (diff)
proxy race fixproxy-race
-rw-r--r--src/scanner.c36
-rw-r--r--src/wayland-client.c111
-rw-r--r--src/wayland-client.h4
3 files changed, 109 insertions, 42 deletions
diff --git a/src/scanner.c b/src/scanner.c
index 0fbaabd..44f7d6d 100644
--- a/src/scanner.c
+++ b/src/scanner.c
@@ -654,31 +654,31 @@ emit_stubs(struct wl_list *message_list, struct interface *interface)
"{\n");
if (ret) {
printf("\tstruct wl_proxy *%s;\n\n"
- "\t%s = wl_proxy_create("
- "(struct wl_proxy *) %s,\n",
- ret->name, ret->name, interface->name);
+ "\t%s = wl_proxy_marshal_constructor("
+ "(struct wl_proxy *) %s,\n"
+ "\t\t\t %s_%s, ",
+ ret->name, ret->name,
+ interface->name,
+ interface->uppercase_name,
+ m->uppercase_name);
+
if (ret->interface_name == NULL)
- printf("\t\t\t interface);\n");
+ printf("interface");
else
- printf("\t\t\t &%s_interface);\n",
- ret->interface_name);
-
- printf("\tif (!%s)\n"
- "\t\treturn NULL;\n\n",
- ret->name);
+ printf("&%s_interface", ret->interface_name);
+ } else {
+ printf("\twl_proxy_marshal((struct wl_proxy *) %s,\n"
+ "\t\t\t %s_%s",
+ interface->name,
+ interface->uppercase_name,
+ m->uppercase_name);
}
- printf("\twl_proxy_marshal((struct wl_proxy *) %s,\n"
- "\t\t\t %s_%s",
- interface->name,
- interface->uppercase_name,
- m->uppercase_name);
-
wl_list_for_each(a, &m->arg_list, link) {
if (a->type == NEW_ID && a->interface_name == NULL)
printf(", interface->name, version");
- printf(", ");
- printf("%s", a->name);
+ else if (a->type != NEW_ID)
+ printf(", %s", a->name);
}
printf(");\n");
diff --git a/src/wayland-client.c b/src/wayland-client.c
index e92317a..5118004 100644
--- a/src/wayland-client.c
+++ b/src/wayland-client.c
@@ -382,6 +382,76 @@ wl_proxy_add_dispatcher(struct wl_proxy *proxy,
return 0;
}
+static struct wl_proxy *
+create_outgoing_proxy(struct wl_proxy *proxy, const struct wl_message *message,
+ union wl_argument *args,
+ const struct wl_interface *interface)
+{
+ int i, count;
+ const char *signature;
+ struct argument_details arg;
+ struct wl_proxy *new_proxy = NULL;
+
+ count = arg_count_for_signature(message->signature);
+ signature = message->signature;
+ for (i = 0; i < count; i++) {
+ signature = get_next_argument(signature, &arg);
+
+ switch (arg.type) {
+ case 'n':
+ new_proxy = wl_proxy_create(proxy, interface);
+ if (new_proxy == NULL)
+ return NULL;
+
+ args[i].n = proxy->object.id;
+ break;
+ }
+ }
+
+ return new_proxy;
+}
+
+static struct wl_proxy *
+proxy_marshal_array(struct wl_proxy *proxy,
+ uint32_t opcode, union wl_argument *args,
+ const struct wl_interface *interface)
+{
+ struct wl_closure *closure;
+ struct wl_proxy *new_proxy = NULL;
+ const struct wl_message *message;
+
+ pthread_mutex_lock(&proxy->display->mutex);
+
+ message = &proxy->object.interface->methods[opcode];
+ if (interface) {
+ new_proxy = create_outgoing_proxy(proxy, message,
+ args, interface);
+ if (new_proxy == NULL)
+ return NULL;
+ }
+
+ closure = wl_closure_marshal(&proxy->object, opcode, args, message);
+ if (closure == NULL) {
+ fprintf(stderr, "Error marshalling request\n");
+ abort();
+ }
+
+ if (wl_debug)
+ wl_closure_print(closure, &proxy->object, true);
+
+ if (wl_closure_send(closure, proxy->display->connection)) {
+ fprintf(stderr, "Error sending request: %m\n");
+ abort();
+ }
+
+ wl_closure_destroy(closure);
+
+ pthread_mutex_unlock(&proxy->display->mutex);
+
+ return new_proxy;
+}
+
+
/** Prepare a request to be sent to the compositor
*
* \param proxy The proxy object
@@ -421,7 +491,22 @@ wl_proxy_marshal(struct wl_proxy *proxy, uint32_t opcode, ...)
args, WL_CLOSURE_MAX_ARGS, ap);
va_end(ap);
- wl_proxy_marshal_array(proxy, opcode, args);
+ proxy_marshal_array(proxy, opcode, args, NULL);
+}
+
+WL_EXPORT struct wl_proxy *
+wl_proxy_marshal_constructor(struct wl_proxy *proxy, uint32_t opcode,
+ const struct wl_interface *interface, ...)
+{
+ union wl_argument args[WL_CLOSURE_MAX_ARGS];
+ va_list ap;
+
+ va_start(ap, interface);
+ wl_argument_from_va_list(proxy->object.interface->methods[opcode].signature,
+ args, WL_CLOSURE_MAX_ARGS, ap);
+ va_end(ap);
+
+ return proxy_marshal_array(proxy, opcode, args, interface);
}
/** Prepare a request to be sent to the compositor
@@ -445,29 +530,7 @@ WL_EXPORT void
wl_proxy_marshal_array(struct wl_proxy *proxy, uint32_t opcode,
union wl_argument *args)
{
- struct wl_closure *closure;
-
- pthread_mutex_lock(&proxy->display->mutex);
-
- closure = wl_closure_marshal(&proxy->object, opcode, args,
- &proxy->object.interface->methods[opcode]);
-
- if (closure == NULL) {
- fprintf(stderr, "Error marshalling request\n");
- abort();
- }
-
- if (wl_debug)
- wl_closure_print(closure, &proxy->object, true);
-
- if (wl_closure_send(closure, proxy->display->connection)) {
- fprintf(stderr, "Error sending request: %m\n");
- abort();
- }
-
- wl_closure_destroy(closure);
-
- pthread_mutex_unlock(&proxy->display->mutex);
+ proxy_marshal_array(proxy, opcode, args, NULL);
}
static void
diff --git a/src/wayland-client.h b/src/wayland-client.h
index 43ba3fc..4b19aef 100644
--- a/src/wayland-client.h
+++ b/src/wayland-client.h
@@ -126,6 +126,10 @@ void wl_proxy_marshal_array(struct wl_proxy *p, uint32_t opcode,
union wl_argument *args);
struct wl_proxy *wl_proxy_create(struct wl_proxy *factory,
const struct wl_interface *interface);
+struct wl_proxy *wl_proxy_marshal_constructor(struct wl_proxy *proxy,
+ uint32_t opcode,
+ const struct wl_interface *interface,
+ ...);
void wl_proxy_destroy(struct wl_proxy *proxy);
int wl_proxy_add_listener(struct wl_proxy *proxy,