Note that libinput_unref() really destroys everything
authorPeter Hutterer <peter.hutterer@who-t.net>
Fri, 4 Sep 2015 03:55:48 +0000 (13:55 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Fri, 4 Sep 2015 05:51:12 +0000 (15:51 +1000)
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 <peter.hutterer@who-t.net>
Reviewed-by: Jonas Ã…dahl <jadahl@gmail.com>
src/libinput.h

index 88b3c05f8f5226c8cdc43fddd01bb77720c82396..898d26ef04d0ea141a64eab07f0151513e2d7744 100644 (file)
@@ -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
  */