On Mon, Jun 23, 2014 at 11:56:41PM +0200, Jonas Ådahl wrote:
> 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 <jad...@gmail.com>
> ---
> 
> There are no users I know of which currently would benefit from this but
> I'm thinking it might be better to at least not disallow. Yay or nay?
> 
> Jonas
> 
>  src/libinput-private.h |  1 +
>  src/libinput.c         | 14 +++++++++++++-
>  src/libinput.h         | 25 ++++++++++++++++++++++---
>  src/udev-seat.c        |  2 +-
>  test/keyboard.c        |  2 +-
>  test/litest.c          |  2 +-
>  test/log.c             | 10 +++++-----
>  test/misc.c            | 10 +++++-----
>  test/path.c            | 20 ++++++++++----------
>  test/pointer.c         |  2 +-
>  test/udev.c            | 16 ++++++++--------
>  tools/event-debug.c    |  4 ++--
>  tools/event-gui.c      |  2 +-
>  13 files changed, 71 insertions(+), 39 deletions(-)
> 
> diff --git a/src/libinput-private.h b/src/libinput-private.h
> index f0bda1f..cfe6535 100644
> --- a/src/libinput-private.h
> +++ b/src/libinput-private.h
> @@ -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);
> diff --git a/src/libinput.c b/src/libinput.c
> index c4f7fe1..d3e2149 100644
> --- a/src/libinput.c
> +++ b/src/libinput.c
> @@ -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);
>  
> @@ -531,7 +532,13 @@ libinput_drop_destroyed_sources(struct libinput 
> *libinput)
>  }
>  
>  LIBINPUT_EXPORT void
> -libinput_destroy(struct libinput *libinput)
> +libinput_ref(struct libinput *libinput)

How about making this function return its argument? Often you have code
like

    void obj_new(struct libinput *libinput)
    {
        [...]
        obj->libinput = libinput;
        libinput_ref(libinput);
        [...]
    }

I think this is better:

        obj->libinput = libinput_ref(libinput);

Ran

> +{
> +     libinput->refcount++;
> +}
> +
> +LIBINPUT_EXPORT void
> +libinput_unref(struct libinput *libinput)
>  {
>       struct libinput_event *event;
>       struct libinput_device *device, *next_device;
> @@ -540,6 +547,11 @@ libinput_destroy(struct libinput *libinput)
>       if (libinput == NULL)
>               return;
>  
> +     assert(libinput->refcount > 0);
> +     libinput->refcount--;
> +     if (libinput->refcount > 0)
> +             return;
> +
>       libinput_suspend(libinput);
>  
>       libinput->interface_backend->destroy(libinput);
> diff --git a/src/libinput.h b/src/libinput.h
> index b1b1124..1eada8f 100644
> --- a/src/libinput.h
> +++ b/src/libinput.h
> @@ -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,26 @@ 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
> + */
> +void
> +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. It is up to the caller to keep
> + * track of the number of references held.
>   *
>   * @param libinput A previously initialized libinput context
>   */
>  void
> -libinput_destroy(struct libinput *libinput);
> +libinput_unref(struct libinput *libinput);
>  
>  /**
>   * @ingroup base
> diff --git a/src/udev-seat.c b/src/udev-seat.c
> index 38a13b7..5b61dee 100644
> --- a/src/udev-seat.c
> +++ b/src/udev-seat.c
> @@ -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;
>       }
> diff --git a/test/keyboard.c b/test/keyboard.c
> index a518b66..83153bb 100644
> --- a/test/keyboard.c
> +++ b/test/keyboard.c
> @@ -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
>  
> diff --git a/test/litest.c b/test/litest.c
> index 0a9cc72..55ba678 100644
> --- a/test/litest.c
> +++ b/test/litest.c
> @@ -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));
> diff --git a/test/log.c b/test/log.c
> index a281820..fe67d68 100644
> --- a/test/log.c
> +++ b/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
> diff --git a/test/misc.c b/test/misc.c
> index 133bdb6..ad2e1f6 100644
> --- a/test/misc.c
> +++ b/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);
> diff --git a/test/path.c b/test/path.c
> index 24f60e0..99b474e 100644
> --- a/test/path.c
> +++ b/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);
>  }
> diff --git a/test/pointer.c b/test/pointer.c
> index 346e59b..7d5668f 100644
> --- a/test/pointer.c
> +++ b/test/pointer.c
> @@ -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
>  
> diff --git a/test/udev.c b/test/udev.c
> index 6af2cb0..09c2a94 100644
> --- a/test/udev.c
> +++ b/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
> diff --git a/tools/event-debug.c b/tools/event-debug.c
> index 34acfce..95e7628 100644
> --- a/tools/event-debug.c
> +++ b/tools/event-debug.c
> @@ -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);
>  
> diff --git a/tools/event-gui.c b/tools/event-gui.c
> index e080ea8..d2b0428 100644
> --- a/tools/event-gui.c
> +++ b/tools/event-gui.c
> @@ -467,7 +467,7 @@ main(int argc, char *argv[])
>  
>       gtk_main();
>  
> -     libinput_destroy(li);
> +     libinput_unref(li);
>       udev_unref(udev);
>  
>       return 0;
> -- 
> 1.9.1
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to