mirror of
https://github.com/brl/mutter.git
synced 2024-11-26 10:00:45 -05:00
wayland/idle-inhibit: Handle immediate inhibitor destruction
If the inhibitor object was destroyed immediately, the proxy
construction completing would try to update the inhibitation state, but
this didn't work since it was already freed. Fix this by adding an
'initializing' state that keeps track of this.
Fixes: a3c62bf8aa
("wayland/idle-inhibit: Add state tracking to fix races")
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2998
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3234>
This commit is contained in:
parent
10d8c5fa82
commit
88fef1d021
@ -563,6 +563,7 @@ if have_native_tests
|
|||||||
'depends': [
|
'depends': [
|
||||||
test_client,
|
test_client,
|
||||||
test_client_executables.get('buffer-transform'),
|
test_client_executables.get('buffer-transform'),
|
||||||
|
test_client_executables.get('idle-inhibit'),
|
||||||
test_client_executables.get('invalid-subsurfaces'),
|
test_client_executables.get('invalid-subsurfaces'),
|
||||||
test_client_executables.get('invalid-xdg-shell-actions'),
|
test_client_executables.get('invalid-xdg-shell-actions'),
|
||||||
test_client_executables.get('single-pixel-buffer'),
|
test_client_executables.get('single-pixel-buffer'),
|
||||||
|
82
src/tests/wayland-test-clients/idle-inhibit.c
Normal file
82
src/tests/wayland-test-clients/idle-inhibit.c
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <wayland-client.h>
|
||||||
|
|
||||||
|
#include "wayland-test-client-utils.h"
|
||||||
|
|
||||||
|
#include "idle-inhibit-unstable-v1-client-protocol.h"
|
||||||
|
|
||||||
|
static WaylandDisplay *display;
|
||||||
|
struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager;
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_registry_global (void *user_data,
|
||||||
|
struct wl_registry *registry,
|
||||||
|
uint32_t id,
|
||||||
|
const char *interface,
|
||||||
|
uint32_t version)
|
||||||
|
{
|
||||||
|
if (strcmp (interface, "zwp_idle_inhibit_manager_v1") == 0)
|
||||||
|
{
|
||||||
|
idle_inhibit_manager = wl_registry_bind (registry, id,
|
||||||
|
&zwp_idle_inhibit_manager_v1_interface,
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_registry_global_remove (void *user_data,
|
||||||
|
struct wl_registry *registry,
|
||||||
|
uint32_t name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_registry_listener registry_listener = {
|
||||||
|
handle_registry_global,
|
||||||
|
handle_registry_global_remove
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc,
|
||||||
|
char **argv)
|
||||||
|
{
|
||||||
|
struct wl_registry *registry;
|
||||||
|
WaylandSurface *surface;
|
||||||
|
struct zwp_idle_inhibitor_v1 *inhibitor;
|
||||||
|
|
||||||
|
display = wayland_display_new (WAYLAND_DISPLAY_CAPABILITY_TEST_DRIVER);
|
||||||
|
registry = wl_display_get_registry (display->display);
|
||||||
|
wl_registry_add_listener (registry, ®istry_listener, NULL);
|
||||||
|
wl_display_roundtrip (display->display);
|
||||||
|
|
||||||
|
surface = wayland_surface_new (display,
|
||||||
|
"idle-inhibit-client",
|
||||||
|
20, 20, 0x11223344);
|
||||||
|
|
||||||
|
inhibitor =
|
||||||
|
zwp_idle_inhibit_manager_v1_create_inhibitor (idle_inhibit_manager,
|
||||||
|
surface->wl_surface);
|
||||||
|
zwp_idle_inhibitor_v1_destroy (inhibitor);
|
||||||
|
|
||||||
|
wl_display_roundtrip (display->display);
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
@ -54,6 +54,9 @@ wayland_test_clients = [
|
|||||||
{
|
{
|
||||||
'name': 'fullscreen',
|
'name': 'fullscreen',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
'name': 'idle-inhibit',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
'name': 'kms-cursor-hotplug-helper',
|
'name': 'kms-cursor-hotplug-helper',
|
||||||
'extra_deps': [
|
'extra_deps': [
|
||||||
|
@ -839,6 +839,32 @@ wayland_registry_filter (void)
|
|||||||
g_assert_false (client3_saw_global);
|
g_assert_false (client3_saw_global);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
set_true (gpointer user_data)
|
||||||
|
{
|
||||||
|
gboolean *done = user_data;
|
||||||
|
|
||||||
|
*done = TRUE;
|
||||||
|
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
wayland_idle_inhibit_instant_destroy (void)
|
||||||
|
{
|
||||||
|
MetaWaylandTestClient *wayland_test_client;
|
||||||
|
gboolean done;
|
||||||
|
|
||||||
|
wayland_test_client =
|
||||||
|
meta_wayland_test_client_new (test_context, "idle-inhibit");
|
||||||
|
meta_wayland_test_client_finish (wayland_test_client);
|
||||||
|
|
||||||
|
done = FALSE;
|
||||||
|
g_timeout_add_seconds (1, set_true, &done);
|
||||||
|
while (!done)
|
||||||
|
g_main_context_iteration (NULL, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_before_tests (void)
|
on_before_tests (void)
|
||||||
{
|
{
|
||||||
@ -886,6 +912,8 @@ init_tests (void)
|
|||||||
xdg_foreign_set_parent_of);
|
xdg_foreign_set_parent_of);
|
||||||
g_test_add_func ("/wayland/registry/filter",
|
g_test_add_func ("/wayland/registry/filter",
|
||||||
wayland_registry_filter);
|
wayland_registry_filter);
|
||||||
|
g_test_add_func ("/wayland/idle-inhibit/instant-destroy",
|
||||||
|
wayland_idle_inhibit_instant_destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
typedef enum _IdleState
|
typedef enum _IdleState
|
||||||
{
|
{
|
||||||
|
IDLE_STATE_INITIALIZING,
|
||||||
IDLE_STATE_UNINHIBITED,
|
IDLE_STATE_UNINHIBITED,
|
||||||
IDLE_STATE_INHIBITING,
|
IDLE_STATE_INHIBITING,
|
||||||
IDLE_STATE_INHIBITED,
|
IDLE_STATE_INHIBITED,
|
||||||
@ -151,6 +152,7 @@ update_inhibitation (MetaWaylandIdleInhibitor *inhibitor)
|
|||||||
|
|
||||||
switch (inhibitor->state)
|
switch (inhibitor->state)
|
||||||
{
|
{
|
||||||
|
case IDLE_STATE_INITIALIZING:
|
||||||
case IDLE_STATE_UNINHIBITED:
|
case IDLE_STATE_UNINHIBITED:
|
||||||
if (!inhibitor->resource)
|
if (!inhibitor->resource)
|
||||||
{
|
{
|
||||||
@ -227,6 +229,7 @@ inhibitor_proxy_completed (GObject *source,
|
|||||||
}
|
}
|
||||||
|
|
||||||
inhibitor->session_proxy = proxy;
|
inhibitor->session_proxy = proxy;
|
||||||
|
inhibitor->state = IDLE_STATE_UNINHIBITED;
|
||||||
|
|
||||||
update_inhibitation (inhibitor);
|
update_inhibitation (inhibitor);
|
||||||
}
|
}
|
||||||
@ -248,6 +251,7 @@ idle_inhibitor_destructor (struct wl_resource *resource)
|
|||||||
case IDLE_STATE_UNINHIBITED:
|
case IDLE_STATE_UNINHIBITED:
|
||||||
meta_wayland_inhibitor_free (inhibitor);
|
meta_wayland_inhibitor_free (inhibitor);
|
||||||
return;
|
return;
|
||||||
|
case IDLE_STATE_INITIALIZING:
|
||||||
case IDLE_STATE_INHIBITED:
|
case IDLE_STATE_INHIBITED:
|
||||||
case IDLE_STATE_INHIBITING:
|
case IDLE_STATE_INHIBITING:
|
||||||
case IDLE_STATE_UNINHIBITING:
|
case IDLE_STATE_UNINHIBITING:
|
||||||
|
Loading…
Reference in New Issue
Block a user