diff options
| author | Vladimir Kondratyev <wulf@FreeBSD.org> | 2020-04-21 22:38:14 +0000 |
|---|---|---|
| committer | Vladimir Kondratyev <wulf@FreeBSD.org> | 2021-01-07 23:18:42 +0000 |
| commit | 3b8c8b35de3a1a8a24169d144189b6a4db82ce10 (patch) | |
| tree | 0c4ab1221f08828654358da47415420372c48de7 /sys/dev/evdev | |
| parent | d276eae674d22214d6a58d1f4871053ceb0cb9f5 (diff) | |
Diffstat (limited to 'sys/dev/evdev')
| -rw-r--r-- | sys/dev/evdev/cdev.c | 11 | ||||
| -rw-r--r-- | sys/dev/evdev/evdev_private.h | 9 |
2 files changed, 15 insertions, 5 deletions
diff --git a/sys/dev/evdev/cdev.c b/sys/dev/evdev/cdev.c index c4550362ebce..ec60a12dbf2d 100644 --- a/sys/dev/evdev/cdev.c +++ b/sys/dev/evdev/cdev.c @@ -126,19 +126,20 @@ evdev_open(struct cdev *dev, int oflags, int devtype, struct thread *td) mtx_init(&client->ec_buffer_mtx, "evclient", "evdev", MTX_DEF); knlist_init_mtx(&client->ec_selp.si_note, &client->ec_buffer_mtx); + ret = EVDEV_LIST_LOCK_SIG(evdev); + if (ret != 0) + goto out; /* Avoid race with evdev_unregister */ - EVDEV_LIST_LOCK(evdev); if (dev->si_drv1 == NULL) ret = ENODEV; else ret = evdev_register_client(evdev, client); - - if (ret != 0) - evdev_revoke_client(client); EVDEV_LIST_UNLOCK(evdev); - +out: if (ret == 0) ret = devfs_set_cdevpriv(client, evdev_dtor); + else + client->ec_revoked = true; if (ret != 0) { debugf(client, "cannot register evdev client"); diff --git a/sys/dev/evdev/evdev_private.h b/sys/dev/evdev/evdev_private.h index 66a059c763bc..19636823b804 100644 --- a/sys/dev/evdev/evdev_private.h +++ b/sys/dev/evdev/evdev_private.h @@ -206,6 +206,15 @@ struct evdev_dev else \ sx_assert(&(evdev)->ev_list_lock, MA_OWNED); \ } while (0) +static inline int +EVDEV_LIST_LOCK_SIG(struct evdev_dev *evdev) +{ + if (evdev->ev_lock_type == EV_LOCK_MTX) { + EVDEV_LOCK(evdev); + return (0); + } + return (sx_xlock_sig(&evdev->ev_list_lock)); +} struct evdev_client { |
