client: Do not warn about attached proxies on default queue destruction.
If the default queue is being destroyed, the client is disconnecting from the wl_display, so there is no possibility of subsequent events being queued to the destroyed default queue, which is what this warning is about. Note that interacting with (e.g., destroying) a wl_proxy after its wl_display is destroyed is a certain memory error, and this warning will indirectly warn about this issue. However, this memory error should be detected and warned about through a more deliberate mechanism. Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
This commit is contained in:
parent
344d31f871
commit
b01a85dfd5
|
@ -304,14 +304,18 @@ wl_event_queue_release(struct wl_event_queue *queue)
|
||||||
if (!wl_list_empty(&queue->proxy_list)) {
|
if (!wl_list_empty(&queue->proxy_list)) {
|
||||||
struct wl_proxy *proxy, *tmp;
|
struct wl_proxy *proxy, *tmp;
|
||||||
|
|
||||||
wl_log("warning: queue %p destroyed while proxies still "
|
if (queue != &queue->display->default_queue) {
|
||||||
"attached:\n", queue);
|
wl_log("warning: queue %p destroyed while proxies "
|
||||||
|
"still attached:\n", queue);
|
||||||
|
}
|
||||||
|
|
||||||
wl_list_for_each_safe(proxy, tmp, &queue->proxy_list,
|
wl_list_for_each_safe(proxy, tmp, &queue->proxy_list,
|
||||||
queue_link) {
|
queue_link) {
|
||||||
wl_log(" %s@%u still attached\n",
|
if (queue != &queue->display->default_queue) {
|
||||||
proxy->object.interface->name,
|
wl_log(" %s@%u still attached\n",
|
||||||
proxy->object.id);
|
proxy->object.interface->name,
|
||||||
|
proxy->object.id);
|
||||||
|
}
|
||||||
proxy->queue = NULL;
|
proxy->queue = NULL;
|
||||||
wl_list_remove(&proxy->queue_link);
|
wl_list_remove(&proxy->queue_link);
|
||||||
wl_list_init(&proxy->queue_link);
|
wl_list_init(&proxy->queue_link);
|
||||||
|
|
|
@ -308,12 +308,22 @@ client_test_queue_set_queue_race(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
map_file(int fd, size_t *len)
|
maybe_map_file(int fd, size_t *len)
|
||||||
{
|
{
|
||||||
char *data;
|
char *data;
|
||||||
|
|
||||||
*len = lseek(fd, 0, SEEK_END);
|
*len = lseek(fd, 0, SEEK_END);
|
||||||
data = mmap(0, *len, PROT_READ, MAP_PRIVATE, fd, 0);
|
data = mmap(0, *len, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
map_file(int fd, size_t *len)
|
||||||
|
{
|
||||||
|
char *data;
|
||||||
|
|
||||||
|
data = maybe_map_file(fd, len);
|
||||||
assert(data != MAP_FAILED && "Failed to mmap file");
|
assert(data != MAP_FAILED && "Failed to mmap file");
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
@ -422,6 +432,45 @@ client_test_queue_proxy_event_to_destroyed_queue(void)
|
||||||
wl_display_disconnect(display);
|
wl_display_disconnect(display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
client_test_queue_destroy_default_with_attached_proxies(void)
|
||||||
|
{
|
||||||
|
struct wl_display *display;
|
||||||
|
struct wl_callback *callback;
|
||||||
|
char *log;
|
||||||
|
size_t log_len;
|
||||||
|
char callback_name[24];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
display = wl_display_connect(NULL);
|
||||||
|
assert(display);
|
||||||
|
|
||||||
|
/* Create a sync dispatching events on the default queue. */
|
||||||
|
callback = wl_display_sync(display);
|
||||||
|
assert(callback != NULL);
|
||||||
|
|
||||||
|
/* Destroy the default queue (by disconnecting) before the attached
|
||||||
|
* object. */
|
||||||
|
wl_display_disconnect(display);
|
||||||
|
|
||||||
|
/* Check that the log does not contain any warning about the attached
|
||||||
|
* wl_callback proxy. */
|
||||||
|
log = maybe_map_file(client_log_fd, &log_len);
|
||||||
|
ret = snprintf(callback_name, sizeof(callback_name), "wl_callback@%u",
|
||||||
|
wl_proxy_get_id((struct wl_proxy *) callback));
|
||||||
|
assert(ret > 0 && ret < (int)sizeof(callback_name) &&
|
||||||
|
"callback name creation failed (possibly truncated)");
|
||||||
|
assert(log == MAP_FAILED || strstr(log, callback_name) == NULL);
|
||||||
|
if (log != MAP_FAILED)
|
||||||
|
munmap(log, log_len);
|
||||||
|
|
||||||
|
/* HACK: Directly free the memory of the wl_callback proxy to appease
|
||||||
|
* ASan. We would normally use wl_callback_destroy(), but since we have
|
||||||
|
* destroyed the associated wl_display, using this function would lead
|
||||||
|
* to memory errors. */
|
||||||
|
free(callback);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dummy_bind(struct wl_client *client,
|
dummy_bind(struct wl_client *client,
|
||||||
void *data, uint32_t version, uint32_t id)
|
void *data, uint32_t version, uint32_t id)
|
||||||
|
@ -536,3 +585,15 @@ TEST(queue_proxy_event_to_destroyed_queue)
|
||||||
/* Check that the client aborted. */
|
/* Check that the client aborted. */
|
||||||
display_destroy_expect_signal(d, SIGABRT);
|
display_destroy_expect_signal(d, SIGABRT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(queue_destroy_default_with_attached_proxies)
|
||||||
|
{
|
||||||
|
struct display *d = display_create();
|
||||||
|
|
||||||
|
test_set_timeout(2);
|
||||||
|
|
||||||
|
client_create_noarg(d, client_test_queue_destroy_default_with_attached_proxies);
|
||||||
|
display_run(d);
|
||||||
|
|
||||||
|
display_destroy(d);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user