From 73ec3d093c2af2db3636551db9d590d7ac703d91 Mon Sep 17 00:00:00 2001 From: Mihail Konev Date: Tue, 20 Sep 2016 18:43:15 +0000 Subject: [PATCH xserver] Add processed-all-input-dev-removes barrier Signed-off-by: Mihail Konev --- hw/xfree86/common/xf86Events.c | 1 + include/input.h | 2 ++ os/inputthread.c | 20 ++++++++++++++++++++ 3 files changed, 23 insertions(+) diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c index 9a8f432a0556..92b1ec5c00cb 100644 --- a/hw/xfree86/common/xf86Events.c +++ b/hw/xfree86/common/xf86Events.c @@ -438,6 +438,7 @@ xf86VTLeave(void) } for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next) xf86DisableInputDeviceForVTSwitch(pInfo); + input_wait_for_processing_all_removes(); input_lock(); for (i = 0; i < xf86NumScreens; i++) diff --git a/include/input.h b/include/input.h index e0f6b9b01d97..3635b8ab4e97 100644 --- a/include/input.h +++ b/include/input.h @@ -719,6 +719,8 @@ extern _X_EXPORT void input_lock(void); extern _X_EXPORT void input_unlock(void); extern _X_EXPORT void input_force_unlock(void); +extern _X_EXPORT void input_wait_for_processing_all_removes(void); + extern void InputThreadPreInit(void); extern void InputThreadInit(void); extern void InputThreadFini(void); diff --git a/os/inputthread.c b/os/inputthread.c index 6aa0a9ce6fb5..7c8d51b7c868 100644 --- a/os/inputthread.c +++ b/os/inputthread.c @@ -90,6 +90,17 @@ static pthread_mutex_t input_mutex; static Bool input_mutex_initialized; #endif +static Bool waiting_for_processing_all_removes = FALSE; +static int unprocessed_removes_count = 0; +static pthread_barrier_t all_removes_processed_barrier; + +void +input_wait_for_processing_all_removes(void) +{ + waiting_for_processing_all_removes = TRUE; + pthread_barrier_wait(&all_removes_processed_barrier); +} + void input_lock(void) { @@ -267,6 +278,7 @@ InputThreadUnregisterDev(int fd) dev->state = device_state_removed; inputThreadInfo->changed = TRUE; + unprocessed_removes_count++; input_unlock(); @@ -348,12 +360,18 @@ InputThreadDoWork(void *arg) ospoll_remove(inputThreadInfo->fds, dev->fd); xorg_list_del(&dev->node); free(dev); + unprocessed_removes_count--; break; } } input_unlock(); } + if (waiting_for_processing_all_removes && !unprocessed_removes_count) { + waiting_for_processing_all_removes = FALSE; + pthread_barrier_wait(&all_removes_processed_barrier); + } + if (ospoll_wait(inputThreadInfo->fds, -1) < 0) { if (errno == EINVAL) FatalError("input-thread: %s (%s)", __func__, strerror(errno)); @@ -400,6 +418,8 @@ InputThreadPreInit(void) if (!inputThreadInfo) FatalError("input-thread: could not allocate memory"); + pthread_barrier_init(&all_removes_processed_barrier, NULL, 2); + inputThreadInfo->thread = 0; xorg_list_init(&inputThreadInfo->devs); inputThreadInfo->fds = ospoll_create(); -- 2.9.2