mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-02-03 11:10:29 +01:00
Make context reference counted
Instead of only allowing one owner keeping a libinput context alive, make context reference counted, replacing libinput_destroy() with libinput_unref() while adding another function libinput_ref(). Even though there might not be any current use cases, it doesn't mean we should hard code this usage model in the API. The old behaviour can be emulated by never calling libinput_ref() while replacing libinput_destroy() with libinput_unref(). Signed-off-by: Jonas Ådahl <jadahl@gmail.com> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
13e9a1d744
commit
faab25c25c
13 changed files with 78 additions and 42 deletions
|
|
@ -57,6 +57,7 @@ struct libinput {
|
|||
const struct libinput_interface *interface;
|
||||
const struct libinput_interface_backend *interface_backend;
|
||||
void *user_data;
|
||||
int refcount;
|
||||
};
|
||||
|
||||
typedef void (*libinput_seat_destroy_func) (struct libinput_seat *seat);
|
||||
|
|
|
|||
|
|
@ -502,6 +502,7 @@ libinput_init(struct libinput *libinput,
|
|||
libinput->interface = interface;
|
||||
libinput->interface_backend = interface_backend;
|
||||
libinput->user_data = user_data;
|
||||
libinput->refcount = 1;
|
||||
list_init(&libinput->source_destroy_list);
|
||||
list_init(&libinput->seat_list);
|
||||
|
||||
|
|
@ -530,15 +531,27 @@ libinput_drop_destroyed_sources(struct libinput *libinput)
|
|||
list_init(&libinput->source_destroy_list);
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT void
|
||||
libinput_destroy(struct libinput *libinput)
|
||||
LIBINPUT_EXPORT struct libinput *
|
||||
libinput_ref(struct libinput *libinput)
|
||||
{
|
||||
libinput->refcount++;
|
||||
return libinput;
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT struct libinput *
|
||||
libinput_unref(struct libinput *libinput)
|
||||
{
|
||||
struct libinput_event *event;
|
||||
struct libinput_device *device, *next_device;
|
||||
struct libinput_seat *seat, *next_seat;
|
||||
|
||||
if (libinput == NULL)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
assert(libinput->refcount > 0);
|
||||
libinput->refcount--;
|
||||
if (libinput->refcount > 0)
|
||||
return libinput;
|
||||
|
||||
libinput_suspend(libinput);
|
||||
|
||||
|
|
@ -562,6 +575,8 @@ libinput_destroy(struct libinput *libinput)
|
|||
libinput_drop_destroyed_sources(libinput);
|
||||
close(libinput->epoll_fd);
|
||||
free(libinput);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT void
|
||||
|
|
|
|||
|
|
@ -793,6 +793,9 @@ struct libinput_interface {
|
|||
* device are ignored. Such devices and those that failed to open
|
||||
* ignored until the next call to libinput_resume().
|
||||
*
|
||||
* The reference count of the context is initialized to 1. See @ref
|
||||
* libinput_unref.
|
||||
*
|
||||
* @param interface The callback interface
|
||||
* @param user_data Caller-specific data passed to the various callback
|
||||
* interfaces.
|
||||
|
|
@ -818,6 +821,9 @@ libinput_udev_create_for_seat(const struct libinput_interface *interface,
|
|||
* The context is fully initialized but will not generate events until at
|
||||
* least one device has been added.
|
||||
*
|
||||
* The reference count of the context is initialized to 1. See @ref
|
||||
* libinput_unref.
|
||||
*
|
||||
* @param interface The callback interface
|
||||
* @param user_data Caller-specific data passed to the various callback
|
||||
* interfaces.
|
||||
|
|
@ -967,13 +973,27 @@ libinput_suspend(struct libinput *libinput);
|
|||
/**
|
||||
* @ingroup base
|
||||
*
|
||||
* Destroy the libinput context. After this, object references associated with
|
||||
* the destroyed context are invalid and may not be interacted with.
|
||||
* Add a reference to the context. A context is destroyed whenever the
|
||||
* reference count reaches 0. See @ref libinput_unref.
|
||||
*
|
||||
* @param libinput A previously initialized valid libinput context
|
||||
* @return The passed libinput context
|
||||
*/
|
||||
struct libinput *
|
||||
libinput_ref(struct libinput *libinput);
|
||||
|
||||
/**
|
||||
* @ingroup base
|
||||
*
|
||||
* Dereference the libinput context. After this, the context may have been
|
||||
* destroyed, if the last reference was dereferenced. If so, the context is
|
||||
* invalid and may not be interacted with.
|
||||
*
|
||||
* @param libinput A previously initialized libinput context
|
||||
* @return NULL if context was destroyed otherwise the passed context
|
||||
*/
|
||||
void
|
||||
libinput_destroy(struct libinput *libinput);
|
||||
struct libinput *
|
||||
libinput_unref(struct libinput *libinput);
|
||||
|
||||
/**
|
||||
* @ingroup base
|
||||
|
|
|
|||
|
|
@ -358,7 +358,7 @@ libinput_udev_create_for_seat(const struct libinput_interface *interface,
|
|||
|
||||
if (udev_input_enable(&input->base) < 0) {
|
||||
udev_unref(udev);
|
||||
libinput_destroy(&input->base);
|
||||
libinput_unref(&input->base);
|
||||
free(input);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ START_TEST(keyboard_seat_key_count)
|
|||
|
||||
for (i = 0; i < num_devices; ++i)
|
||||
litest_delete_device(devices[i]);
|
||||
libinput_destroy(libinput);
|
||||
libinput_unref(libinput);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
|
|
|||
|
|
@ -573,7 +573,7 @@ litest_delete_device(struct litest_device *d)
|
|||
|
||||
libinput_device_unref(d->libinput_device);
|
||||
if (d->owns_context)
|
||||
libinput_destroy(d->libinput);
|
||||
libinput_unref(d->libinput);
|
||||
libevdev_free(d->evdev);
|
||||
libevdev_uinput_destroy(d->uinput);
|
||||
memset(d,0, sizeof(*d));
|
||||
|
|
|
|||
10
test/log.c
10
test/log.c
|
|
@ -86,7 +86,7 @@ START_TEST(log_handler_invoked)
|
|||
ck_assert_int_gt(log_handler_called, 0);
|
||||
log_handler_called = 0;
|
||||
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
libinput_log_set_priority(pri);
|
||||
}
|
||||
END_TEST
|
||||
|
|
@ -106,7 +106,7 @@ START_TEST(log_userdata_NULL)
|
|||
ck_assert_int_gt(log_handler_called, 0);
|
||||
log_handler_called = 0;
|
||||
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
|
||||
libinput_log_set_priority(pri);
|
||||
}
|
||||
|
|
@ -127,7 +127,7 @@ START_TEST(log_userdata)
|
|||
ck_assert_int_gt(log_handler_called, 0);
|
||||
log_handler_called = 0;
|
||||
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
libinput_log_set_priority(pri);
|
||||
}
|
||||
END_TEST
|
||||
|
|
@ -148,7 +148,7 @@ START_TEST(log_handler_NULL)
|
|||
log_handler_called = 0;
|
||||
libinput_log_set_handler(simple_log_handler, NULL);
|
||||
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
libinput_log_set_priority(pri);
|
||||
}
|
||||
END_TEST
|
||||
|
|
@ -173,7 +173,7 @@ START_TEST(log_priority)
|
|||
|
||||
log_handler_called = 0;
|
||||
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
libinput_log_set_priority(pri);
|
||||
}
|
||||
END_TEST
|
||||
|
|
|
|||
10
test/misc.c
10
test/misc.c
|
|
@ -133,7 +133,7 @@ START_TEST(event_conversion_device_notify)
|
|||
libinput_event_destroy(event);
|
||||
}
|
||||
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
libevdev_uinput_destroy(uinput);
|
||||
|
||||
ck_assert_int_gt(device_added, 0);
|
||||
|
|
@ -194,7 +194,7 @@ START_TEST(event_conversion_pointer)
|
|||
libinput_event_destroy(event);
|
||||
}
|
||||
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
libevdev_uinput_destroy(uinput);
|
||||
|
||||
ck_assert_int_gt(motion, 0);
|
||||
|
|
@ -254,7 +254,7 @@ START_TEST(event_conversion_pointer_abs)
|
|||
libinput_event_destroy(event);
|
||||
}
|
||||
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
libevdev_uinput_destroy(uinput);
|
||||
|
||||
ck_assert_int_gt(motion, 0);
|
||||
|
|
@ -304,7 +304,7 @@ START_TEST(event_conversion_key)
|
|||
libinput_event_destroy(event);
|
||||
}
|
||||
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
libevdev_uinput_destroy(uinput);
|
||||
|
||||
ck_assert_int_gt(key, 0);
|
||||
|
|
@ -364,7 +364,7 @@ START_TEST(event_conversion_touch)
|
|||
libinput_event_destroy(event);
|
||||
}
|
||||
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
libevdev_uinput_destroy(uinput);
|
||||
|
||||
ck_assert_int_gt(touch, 0);
|
||||
|
|
|
|||
20
test/path.c
20
test/path.c
|
|
@ -65,7 +65,7 @@ START_TEST(path_create_NULL)
|
|||
ck_assert(li == NULL);
|
||||
li = libinput_path_create_context(&simple_interface, NULL);
|
||||
ck_assert(li != NULL);
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
|
||||
ck_assert_int_eq(open_func_count, 0);
|
||||
ck_assert_int_eq(close_func_count, 0);
|
||||
|
|
@ -92,7 +92,7 @@ START_TEST(path_create_invalid)
|
|||
ck_assert_int_eq(open_func_count, 0);
|
||||
ck_assert_int_eq(close_func_count, 0);
|
||||
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
ck_assert_int_eq(close_func_count, 0);
|
||||
|
||||
open_func_count = 0;
|
||||
|
|
@ -126,7 +126,7 @@ START_TEST(path_create_destroy)
|
|||
ck_assert_int_eq(open_func_count, 1);
|
||||
|
||||
libevdev_uinput_destroy(uinput);
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
ck_assert_int_eq(close_func_count, 1);
|
||||
|
||||
open_func_count = 0;
|
||||
|
|
@ -372,7 +372,7 @@ START_TEST(path_suspend)
|
|||
libinput_resume(li);
|
||||
|
||||
libevdev_uinput_destroy(uinput);
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
|
||||
open_func_count = 0;
|
||||
close_func_count = 0;
|
||||
|
|
@ -406,7 +406,7 @@ START_TEST(path_double_suspend)
|
|||
libinput_resume(li);
|
||||
|
||||
libevdev_uinput_destroy(uinput);
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
|
||||
open_func_count = 0;
|
||||
close_func_count = 0;
|
||||
|
|
@ -440,7 +440,7 @@ START_TEST(path_double_resume)
|
|||
libinput_resume(li);
|
||||
|
||||
libevdev_uinput_destroy(uinput);
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
|
||||
open_func_count = 0;
|
||||
close_func_count = 0;
|
||||
|
|
@ -523,7 +523,7 @@ START_TEST(path_add_device_suspend_resume)
|
|||
|
||||
libevdev_uinput_destroy(uinput1);
|
||||
libevdev_uinput_destroy(uinput2);
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
|
||||
open_func_count = 0;
|
||||
close_func_count = 0;
|
||||
|
|
@ -614,7 +614,7 @@ START_TEST(path_add_device_suspend_resume_fail)
|
|||
ck_assert_int_eq(nevents, 2);
|
||||
|
||||
libevdev_uinput_destroy(uinput2);
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
|
||||
open_func_count = 0;
|
||||
close_func_count = 0;
|
||||
|
|
@ -704,7 +704,7 @@ START_TEST(path_add_device_suspend_resume_remove_device)
|
|||
ck_assert_int_eq(nevents, 1);
|
||||
|
||||
libevdev_uinput_destroy(uinput1);
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
|
||||
open_func_count = 0;
|
||||
close_func_count = 0;
|
||||
|
|
@ -790,7 +790,7 @@ START_TEST(path_seat_recycle)
|
|||
|
||||
ck_assert(found == 1);
|
||||
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
|
||||
libevdev_uinput_destroy(uinput);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -292,7 +292,7 @@ START_TEST(pointer_seat_button_count)
|
|||
|
||||
for (i = 0; i < num_devices; ++i)
|
||||
litest_delete_device(devices[i]);
|
||||
libinput_destroy(libinput);
|
||||
libinput_unref(libinput);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
|
|
|||
16
test/udev.c
16
test/udev.c
|
|
@ -97,7 +97,7 @@ START_TEST(udev_create_seat0)
|
|||
ck_assert(event != NULL);
|
||||
|
||||
libinput_event_destroy(event);
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
udev_unref(udev);
|
||||
}
|
||||
END_TEST
|
||||
|
|
@ -124,7 +124,7 @@ START_TEST(udev_create_empty_seat)
|
|||
ck_assert(event == NULL);
|
||||
|
||||
libinput_event_destroy(event);
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
udev_unref(udev);
|
||||
}
|
||||
END_TEST
|
||||
|
|
@ -169,7 +169,7 @@ START_TEST(udev_added_seat_default)
|
|||
|
||||
ck_assert(default_seat_found);
|
||||
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
udev_unref(udev);
|
||||
}
|
||||
END_TEST
|
||||
|
|
@ -200,7 +200,7 @@ START_TEST(udev_double_suspend)
|
|||
libinput_resume(li);
|
||||
|
||||
libinput_event_destroy(event);
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
udev_unref(udev);
|
||||
}
|
||||
END_TEST
|
||||
|
|
@ -231,7 +231,7 @@ START_TEST(udev_double_resume)
|
|||
libinput_resume(li);
|
||||
|
||||
libinput_event_destroy(event);
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
udev_unref(udev);
|
||||
}
|
||||
END_TEST
|
||||
|
|
@ -289,7 +289,7 @@ START_TEST(udev_suspend_resume)
|
|||
process_events_count_devices(li, &num_devices);
|
||||
ck_assert_int_gt(num_devices, 0);
|
||||
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
udev_unref(udev);
|
||||
}
|
||||
END_TEST
|
||||
|
|
@ -322,7 +322,7 @@ START_TEST(udev_device_sysname)
|
|||
libinput_event_destroy(ev);
|
||||
}
|
||||
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
udev_unref(udev);
|
||||
}
|
||||
END_TEST
|
||||
|
|
@ -396,7 +396,7 @@ START_TEST(udev_seat_recycle)
|
|||
|
||||
ck_assert(found == 1);
|
||||
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
udev_unref(udev);
|
||||
}
|
||||
END_TEST
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ open_device(struct libinput **li, const char *path)
|
|||
device = libinput_path_add_device(*li, path);
|
||||
if (!device) {
|
||||
fprintf(stderr, "Failed to initialized device %s\n", path);
|
||||
libinput_destroy(*li);
|
||||
libinput_unref(*li);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -478,7 +478,7 @@ main(int argc, char **argv)
|
|||
|
||||
mainloop(li);
|
||||
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
if (udev)
|
||||
udev_unref(udev);
|
||||
|
||||
|
|
|
|||
|
|
@ -467,7 +467,7 @@ main(int argc, char *argv[])
|
|||
|
||||
gtk_main();
|
||||
|
||||
libinput_destroy(li);
|
||||
libinput_unref(li);
|
||||
udev_unref(udev);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue