From 47aafeb4bccc4b497c169c2a6f241c96eff94639 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 4 Sep 2015 13:55:48 +1000 Subject: [PATCH] Note that libinput_unref() really destroys everything MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is both a bug and required behavior. A caller may hold refcounted references to devices, seats, or device groups but when libinput_unref() cleans up, all these become invalid. It is required behavior, because the last call to libinput_unref() also calls libinput_suspend() and thus stops any events. Any attempt at fixing this will break current behavior: * keeping structs until all refcounts are 0 may leak memory in current callers * it would require an explicit call to libinput_suspend(), or make libinput_unref() inconsistent in its behavior. So we document it as a bug and tell people not to do it. https://bugs.freedesktop.org/show_bug.cgi?id=91872 Signed-off-by: Peter Hutterer Reviewed-by: Jonas Ã…dahl --- src/libinput.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/libinput.h b/src/libinput.h index 88b3c05f..898d26ef 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -1449,6 +1449,26 @@ libinput_ref(struct libinput *libinput); * destroyed, if the last reference was dereferenced. If so, the context is * invalid and may not be interacted with. * + * @bug When the refcount reaches zero, libinput_unref() releases resources + * even if a caller still holds refcounted references to related resources + * (e.g. a libinput_device). When libinput_unref() returns + * NULL, the caller must consider any resources related to that context + * invalid. See https://bugs.freedesktop.org/show_bug.cgi?id=91872. + * Example code: + * @code + * li = libinput_path_create_context(&interface, NULL); + * device = libinput_path_add_device(li, "/dev/input/event0"); + * // get extra reference to device + * libinput_device_ref(device); + * + * // refcount reaches 0, so *all* resources are cleaned up, + * // including device + * libinput_unref(li); + * + * // INCORRECT: device has been cleaned up and must not be used + * // li = libinput_device_get_context(device); + * @endcode + * * @param libinput A previously initialized libinput context * @return NULL if context was destroyed otherwise the passed context */