From: Rémi Bernon rbernon@codeweavers.com
--- server/protocol.def | 1 + server/queue.c | 24 ++++++++++++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/server/protocol.def b/server/protocol.def index f69a3e8a846..12eef14cc67 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -936,6 +936,7 @@ typedef volatile struct user_handle_t cursor; /* handle to the cursor */ int cursor_count; /* cursor show count */ unsigned char keystate[256]; /* key state */ + int keystate_lock; /* keystate is locked */ } input_shm_t;
typedef volatile union diff --git a/server/queue.c b/server/queue.c index c082d7acab8..7411168a2ff 100644 --- a/server/queue.c +++ b/server/queue.c @@ -108,7 +108,6 @@ struct thread_input int caret_state; /* caret on/off state */ struct list msg_list; /* list of hardware messages */ unsigned char desktop_keystate[256]; /* desktop keystate when keystate was synced */ - int keystate_lock; /* keystate is locked */ const input_shm_t *shared; /* thread input in session shared memory */ };
@@ -250,7 +249,6 @@ static struct thread_input *create_thread_input( struct thread *thread ) if ((input = alloc_object( &thread_input_ops ))) { list_init( &input->msg_list ); - input->keystate_lock = 0; input->shared = NULL;
if (!(input->desktop = get_thread_desktop( thread, 0 /* FIXME: access rights */ ))) @@ -279,6 +277,7 @@ static struct thread_input *create_thread_input( struct thread *thread ) shared->cursor = 0; shared->cursor_count = 0; memset( (void *)shared->keystate, 0, sizeof(shared->keystate) ); + shared->keystate_lock = 0; } SHARED_WRITE_END; } @@ -364,7 +363,7 @@ static void sync_input_keystate( struct thread_input *input ) struct desktop *desktop; int i;
- if (!(desktop = input->desktop) || input->keystate_lock) return; + if (!(desktop = input->desktop) || input_shm->keystate_lock) return; desktop_shm = input->desktop->shared;
SHARED_WRITE_BEGIN( input_shm, input_shm_t ) @@ -381,14 +380,27 @@ static void sync_input_keystate( struct thread_input *input ) /* locks thread input keystate to prevent synchronization */ static void lock_input_keystate( struct thread_input *input ) { - input->keystate_lock++; + const input_shm_t *input_shm = input->shared; + + SHARED_WRITE_BEGIN( input_shm, input_shm_t ) + { + shared->keystate_lock++; + } + SHARED_WRITE_END; }
/* unlock the thread input keystate and synchronize it again */ static void unlock_input_keystate( struct thread_input *input ) { - input->keystate_lock--; - if (!input->keystate_lock) sync_input_keystate( input ); + const input_shm_t *input_shm = input->shared; + + SHARED_WRITE_BEGIN( input_shm, input_shm_t ) + { + shared->keystate_lock--; + } + SHARED_WRITE_END; + + if (!input_shm->keystate_lock) sync_input_keystate( input ); }
/* change the thread input data of a given thread */