client: Keep track of proxy validity and number of reference holders

When events are queued, the associated proxy objects (target proxy and
potentially closure argument proxies) are verified being valid. However,
as any event may destroy some proxy object, validity needs to be
verified again before dispatching. Before this change this was done by
again looking up the object via the display object map, but that did not
work because a delete_id event could be dispatched out-of-order if it
was queued in another queue, causing the object map to either have a new
proxy object with the same id or none at all, had it been destroyed in
an earlier event in the queue.

Instead, make wl_proxy reference counted and increase the reference
counter of every object associated with an event when it is queued. In
wl_proxy_destroy() set a flag saying the proxy has been destroyed by the
application and only free the proxy if the reference counter reaches
zero after decreasing it.

Before dispatching, verify that a proxy object still is valid by
checking that the flag set in wl_proxy_destroy() has not been set. When
dequeuing the event, all associated proxy objects are dereferenced and
free:ed if the reference counter reaches zero. As proxy reference counter
is initiated to 1, when dispatching an event it can never reach zero
without having the destroyed flag set.

Signed-off-by: Jonas Ådahl <jadahl@gmail.com>
This commit is contained in:
Jonas Ådahl 2012-11-03 22:26:10 +01:00 committed by Kristian Høgsberg
parent c4857e9232
commit e273c7cde3
2 changed files with 110 additions and 20 deletions

View file

@ -59,6 +59,7 @@ void wl_map_for_each(struct wl_map *map, wl_iterator_func_t func, void *data);
struct wl_connection;
struct wl_closure;
struct wl_proxy;
struct wl_connection *wl_connection_create(int fd);
void wl_connection_destroy(struct wl_connection *connection);
@ -80,6 +81,7 @@ struct wl_closure {
void *args[20];
uint32_t *start;
struct wl_list link;
struct wl_proxy *proxy;
uint32_t buffer[0];
};