diff options
author | Jonas Ådahl <jadahl@gmail.com> | 2014-01-22 23:48:39 +0100 |
---|---|---|
committer | Jonas Ådahl <jadahl@gmail.com> | 2014-01-22 23:59:32 +0100 |
commit | 8264c3b60b0d8a7e5b31e65dd4cce6db7bd5148b (patch) | |
tree | 5053914722816a315a95d869039e208ba66ae874 /src | |
parent | a93a0597c5c73bb2c7ca848359ae091bc7270806 (diff) |
evdev: Make evdev manage its seat reference
Before the seat reference would be decreased when a device was removed.
This could cause libinput_device_get_seat() to potentially return an
invalid pointer when a device was removed, its seat unreferenced and
destryoed.
Signed-off-by: Jonas Ådahl <jadahl@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/evdev.c | 4 | ||||
-rw-r--r-- | src/path.c | 11 | ||||
-rw-r--r-- | src/udev-seat.c | 18 |
3 files changed, 13 insertions, 20 deletions
diff --git a/src/evdev.c b/src/evdev.c index ee6b0b9d..be0247b9 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -624,6 +624,8 @@ evdev_device_create(struct libinput_seat *seat, devname[sizeof(devname) - 1] = '\0'; device->devname = strdup(devname); + libinput_seat_ref(seat); + if (evdev_configure_device(device) == -1) goto err; @@ -719,6 +721,8 @@ evdev_device_destroy(struct evdev_device *device) if (dispatch) dispatch->interface->destroy(dispatch); + libinput_seat_unref(device->base.seat); + free(device->devname); free(device->devnode); free(device->sysname); @@ -40,20 +40,12 @@ path_input_disable(struct libinput *libinput) { struct path_input *input = (struct path_input*)libinput; struct evdev_device *device = input->device; - struct path_seat *seat, *tmp; if (device) { close_restricted(libinput, device->fd); evdev_device_remove(device); input->device = NULL; } - - /* should only be one seat anyway */ - list_for_each_safe(seat, tmp, &libinput->seat_list, base.link) { - list_remove(&seat->base.link); - list_init(&seat->base.link); - libinput_seat_unref(&seat->base); - } } static void @@ -155,16 +147,15 @@ path_input_enable(struct libinput *libinput) device = evdev_device_create(&seat->base, devnode, syspath, fd); free(syspath); + libinput_seat_unref(&seat->base); if (device == EVDEV_UNHANDLED_DEVICE) { close_restricted(libinput, fd); log_info("not using input device '%s'.\n", devnode); - libinput_seat_unref(&seat->base); return -1; } else if (device == NULL) { close_restricted(libinput, fd); log_info("failed to create input device '%s'.\n", devnode); - libinput_seat_unref(&seat->base); return -1; } diff --git a/src/udev-seat.c b/src/udev-seat.c index 2a7c9a2e..59365112 100644 --- a/src/udev-seat.c +++ b/src/udev-seat.c @@ -83,19 +83,23 @@ device_added(struct udev_device *udev_device, struct udev_input *input) * read. mtdev_get() also expects this. */ fd = open_restricted(libinput, devnode, O_RDWR | O_NONBLOCK); if (fd < 0) { - log_info("opening input device '%s' failed (%s).\n", devnode, strerror(-fd)); - goto error; + log_info("opening input device '%s' failed (%s).\n", + devnode, strerror(-fd)); + libinput_seat_unref(&seat->base); + return 0; } device = evdev_device_create(&seat->base, devnode, sysname, fd); + libinput_seat_unref(&seat->base); + if (device == EVDEV_UNHANDLED_DEVICE) { close_restricted(libinput, fd); log_info("not using input device '%s'.\n", devnode); - goto error; + return 0; } else if (device == NULL) { close_restricted(libinput, fd); log_info("failed to create input device '%s'.\n", devnode); - goto error; + return 0; } calibration_values = @@ -125,10 +129,6 @@ device_added(struct udev_device *udev_device, struct udev_input *input) device->output_name = strdup(output_name); return 0; -error: - if (seat) - libinput_seat_unref(&seat->base); - return 0; } static int @@ -200,7 +200,6 @@ evdev_udev_handler(void *data) device->devname, device->devnode); close_restricted(libinput, device->fd); evdev_device_remove(device); - libinput_seat_unref(&seat->base); break; } } @@ -230,7 +229,6 @@ udev_input_remove_devices(struct udev_input *input) list_remove(&seat->base.link); list_init(&seat->base.link); } - libinput_seat_unref(&seat->base); } libinput_seat_unref(&seat->base); } |