Merge branch 'ref-counting-context'

Conflicts:
	src/udev-seat.c
	test/log.c
This commit is contained in:
Peter Hutterer 2014-06-25 10:32:42 +10:00
commit bad56cac5b
13 changed files with 125 additions and 53 deletions

View file

@ -60,6 +60,7 @@ struct libinput {
libinput_log_handler log_handler;
enum libinput_log_priority log_priority;
void *user_data;
int refcount;
};
typedef void (*libinput_seat_destroy_func) (struct libinput_seat *seat);

View file

@ -496,6 +496,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);
@ -524,15 +525,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);
@ -556,6 +569,8 @@ libinput_destroy(struct libinput *libinput)
libinput_drop_destroyed_sources(libinput);
close(libinput->epoll_fd);
free(libinput);
return NULL;
}
LIBINPUT_EXPORT void
@ -601,10 +616,11 @@ libinput_seat_init(struct libinput_seat *seat,
list_insert(&libinput->seat_list, &seat->link);
}
LIBINPUT_EXPORT void
LIBINPUT_EXPORT struct libinput_seat *
libinput_seat_ref(struct libinput_seat *seat)
{
seat->refcount++;
return seat;
}
static void
@ -616,13 +632,17 @@ libinput_seat_destroy(struct libinput_seat *seat)
seat->destroy(seat);
}
LIBINPUT_EXPORT void
LIBINPUT_EXPORT struct libinput_seat *
libinput_seat_unref(struct libinput_seat *seat)
{
assert(seat->refcount > 0);
seat->refcount--;
if (seat->refcount == 0)
if (seat->refcount == 0) {
libinput_seat_destroy(seat);
return NULL;
} else {
return seat;
}
}
LIBINPUT_EXPORT void
@ -657,10 +677,11 @@ libinput_device_init(struct libinput_device *device,
device->refcount = 1;
}
LIBINPUT_EXPORT void
LIBINPUT_EXPORT struct libinput_device *
libinput_device_ref(struct libinput_device *device)
{
device->refcount++;
return device;
}
static void
@ -669,13 +690,17 @@ libinput_device_destroy(struct libinput_device *device)
evdev_device_destroy((struct evdev_device *) device);
}
LIBINPUT_EXPORT void
LIBINPUT_EXPORT struct libinput_device *
libinput_device_unref(struct libinput_device *device)
{
assert(device->refcount > 0);
device->refcount--;
if (device->refcount == 0)
if (device->refcount == 0) {
libinput_device_destroy(device);
return NULL;
} else {
return device;
}
}
LIBINPUT_EXPORT int

View file

@ -837,6 +837,9 @@ libinput_udev_assign_seat(struct libinput *libinput,
* 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.
@ -867,6 +870,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.
@ -1016,13 +1022,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
@ -1132,8 +1152,9 @@ libinput_log_set_handler(struct libinput *libinput,
* the seat correctly to avoid dangling pointers.
*
* @param seat A previously obtained seat
* @return The passed seat
*/
void
struct libinput_seat *
libinput_seat_ref(struct libinput_seat *seat);
/**
@ -1145,8 +1166,9 @@ libinput_seat_ref(struct libinput_seat *seat);
* the seat correctly to avoid dangling pointers.
*
* @param seat A previously obtained seat
* @return NULL if seat was destroyed, otherwise the passed seat
*/
void
struct libinput_seat *
libinput_seat_unref(struct libinput_seat *seat);
/**
@ -1219,8 +1241,9 @@ libinput_seat_get_logical_name(struct libinput_seat *seat);
* the device correctly to avoid dangling pointers.
*
* @param device A previously obtained device
* @return The passed device
*/
void
struct libinput_device *
libinput_device_ref(struct libinput_device *device);
/**
@ -1232,8 +1255,9 @@ libinput_device_ref(struct libinput_device *device);
* the device correctly to avoid dangling pointers.
*
* @param device A previously obtained device
* @return NULL if device was destroyed, otherwise the passed device
*/
void
struct libinput_device *
libinput_device_unref(struct libinput_device *device);
/**

View file

@ -351,6 +351,7 @@ libinput_udev_create_context(const struct libinput_interface *interface,
if (libinput_init(&input->base, interface,
&interface_backend, user_data) != 0) {
libinput_unref(&input->base);
free(input);
return NULL;
}
@ -400,7 +401,7 @@ libinput_udev_create_for_seat(const struct libinput_interface *interface,
return NULL;
if (libinput_udev_assign_seat(libinput, seat_id) != 0) {
libinput_destroy(libinput);
libinput_unref(libinput);
libinput = NULL;
}

View file

@ -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

View file

@ -577,7 +577,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));

View file

@ -72,7 +72,7 @@ START_TEST(log_default_priority)
ck_assert_int_eq(pri, LIBINPUT_LOG_PRIORITY_ERROR);
libinput_destroy(li);
libinput_unref(li);
}
END_TEST
@ -91,7 +91,7 @@ START_TEST(log_handler_invoked)
ck_assert_int_gt(log_handler_called, 0);
log_handler_called = 0;
libinput_destroy(li);
libinput_unref(li);
log_handler_context = NULL;
}
@ -110,7 +110,7 @@ START_TEST(log_handler_NULL)
ck_assert_int_eq(log_handler_called, 0);
log_handler_called = 0;
libinput_destroy(li);
libinput_unref(li);
}
END_TEST
@ -133,7 +133,7 @@ START_TEST(log_priority)
log_handler_called = 0;
libinput_destroy(li);
libinput_unref(li);
log_handler_context = NULL;
}
END_TEST

View file

@ -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,19 +364,39 @@ 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);
}
END_TEST
START_TEST(context_ref_counting)
{
struct libinput *li;
/* These tests rely on valgrind to detect memory leak and use after
* free errors. */
li = libinput_path_create_context(&simple_interface, NULL);
ck_assert_notnull(li);
ck_assert_ptr_eq(libinput_unref(li), NULL);
li = libinput_path_create_context(&simple_interface, NULL);
ck_assert_notnull(li);
ck_assert_ptr_eq(libinput_ref(li), li);
ck_assert_ptr_eq(libinput_unref(li), li);
ck_assert_ptr_eq(libinput_unref(li), NULL);
}
END_TEST
int main (int argc, char **argv) {
litest_add_no_device("events:conversion", event_conversion_device_notify);
litest_add_no_device("events:conversion", event_conversion_pointer);
litest_add_no_device("events:conversion", event_conversion_pointer_abs);
litest_add_no_device("events:conversion", event_conversion_key);
litest_add_no_device("events:conversion", event_conversion_touch);
litest_add_no_device("context:refcount", context_ref_counting);
return litest_run(argc, argv);
}

View file

@ -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);
}

View file

@ -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

View file

@ -68,7 +68,8 @@ START_TEST(udev_create_NULL)
li = libinput_udev_create_context(&interface, NULL, udev);
ck_assert(li != NULL);
ck_assert_int_eq(libinput_udev_assign_seat(li, NULL), -1);
libinput_destroy(li);
libinput_unref(li);
udev_unref(udev);
}
END_TEST
@ -96,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 +125,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
@ -170,7 +171,7 @@ START_TEST(udev_added_seat_default)
ck_assert(default_seat_found);
libinput_destroy(li);
libinput_unref(li);
udev_unref(udev);
}
END_TEST
@ -202,7 +203,7 @@ START_TEST(udev_double_suspend)
libinput_resume(li);
libinput_event_destroy(event);
libinput_destroy(li);
libinput_unref(li);
udev_unref(udev);
}
END_TEST
@ -234,7 +235,7 @@ START_TEST(udev_double_resume)
libinput_resume(li);
libinput_event_destroy(event);
libinput_destroy(li);
libinput_unref(li);
udev_unref(udev);
}
END_TEST
@ -293,7 +294,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
@ -327,7 +328,7 @@ START_TEST(udev_device_sysname)
libinput_event_destroy(ev);
}
libinput_destroy(li);
libinput_unref(li);
udev_unref(udev);
}
END_TEST
@ -402,7 +403,7 @@ START_TEST(udev_seat_recycle)
ck_assert(found == 1);
libinput_destroy(li);
libinput_unref(li);
udev_unref(udev);
}
END_TEST

View file

@ -162,7 +162,7 @@ open_udev(struct libinput **li)
if (libinput_udev_assign_seat(*li, seat)) {
fprintf(stderr, "Failed to set seat\n");
libinput_destroy(*li);
libinput_unref(*li);
return 1;
}
@ -188,7 +188,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;
}
@ -489,7 +489,7 @@ main(int argc, char **argv)
mainloop(li);
libinput_destroy(li);
libinput_unref(li);
if (udev)
udev_unref(udev);

View file

@ -467,7 +467,7 @@ main(int argc, char *argv[])
gtk_main();
libinput_destroy(li);
libinput_unref(li);
udev_unref(udev);
return 0;