From: Rémi Bernon rbernon@codeweavers.com
And set a QS_DRIVER bit when the queue fd is ready for reading, or clear it if it isn't, before waiting on it.
Clear the bit after waiting as we expect the client to process events before calling the server again and before we can poll it again. --- server/protocol.def | 1 + server/queue.c | 35 ++++++++++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/server/protocol.def b/server/protocol.def index c9c77b1cf17..452f3f163af 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1017,6 +1017,7 @@ typedef volatile struct unsigned int wake_bits; /* wakeup bits */ unsigned int changed_mask; /* changed wakeup mask */ unsigned int changed_bits; /* changed wakeup bits */ + unsigned int internal_bits; /* internal queue bits */ int hooks_count[NB_HOOKS]; /* active hooks count */ } queue_shm_t;
diff --git a/server/queue.c b/server/queue.c index 268c921a914..4ee01245757 100644 --- a/server/queue.c +++ b/server/queue.c @@ -46,6 +46,9 @@ #include "request.h" #include "user.h"
+#define QS_DRIVER 0x80000000 +#define QS_INTERNAL QS_DRIVER + #define WM_NCMOUSEFIRST WM_NCMOUSEMOVE #define WM_NCMOUSELAST (WM_NCMOUSEFIRST+(WM_MOUSELAST-WM_MOUSEFIRST))
@@ -335,6 +338,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_ shared->wake_bits = 0; shared->changed_mask = 0; shared->changed_bits = 0; + shared->internal_bits = 0; } SHARED_WRITE_END;
@@ -737,8 +741,10 @@ static inline int get_queue_status( struct msg_queue *queue ) static inline void set_queue_bits( struct msg_queue *queue, unsigned int bits ) { queue_shm_t *queue_shm = queue->shared; + unsigned int internal = bits & QS_INTERNAL; + bits &= ~QS_INTERNAL;
- if (bits & (QS_KEY | QS_MOUSEBUTTON)) + if (!internal && (bits & (QS_KEY | QS_MOUSEBUTTON))) { if (!queue->keystate_lock) lock_input_keystate( queue->input ); queue->keystate_lock = 1; @@ -748,6 +754,7 @@ static inline void set_queue_bits( struct msg_queue *queue, unsigned int bits ) { shared->wake_bits |= bits; shared->changed_bits |= bits; + shared->internal_bits |= internal; } SHARED_WRITE_END;
@@ -758,15 +765,19 @@ static inline void set_queue_bits( struct msg_queue *queue, unsigned int bits ) static inline void clear_queue_bits( struct msg_queue *queue, unsigned int bits ) { queue_shm_t *queue_shm = queue->shared; + unsigned int internal = bits & QS_INTERNAL; + bits &= ~QS_INTERNAL;
SHARED_WRITE_BEGIN( queue_shm, queue_shm_t ) { shared->wake_bits &= ~bits; shared->changed_bits &= ~bits; + shared->internal_bits &= ~internal; + bits = shared->wake_bits; } SHARED_WRITE_END;
- if (!(queue_shm->wake_bits & (QS_KEY | QS_MOUSEBUTTON))) + if (!internal && !(bits & (QS_KEY | QS_MOUSEBUTTON))) { if (queue->keystate_lock) unlock_input_keystate( queue->input ); queue->keystate_lock = 0; @@ -1298,8 +1309,16 @@ static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *ent
if (queue->fd) { - if (check_fd_events( queue->fd, POLLIN )) signal_queue_sync( queue ); - else set_fd_events( queue->fd, POLLIN ); + if (check_fd_events( queue->fd, POLLIN )) + { + set_queue_bits( queue, QS_DRIVER ); + signal_queue_sync( queue ); + } + else + { + clear_queue_bits( queue, QS_DRIVER ); + set_fd_events( queue->fd, POLLIN ); + } } add_queue( obj, entry ); return 1; @@ -1310,7 +1329,12 @@ static void msg_queue_remove_queue(struct object *obj, struct wait_queue_entry * struct msg_queue *queue = (struct msg_queue *)obj;
remove_queue( obj, entry ); - if (queue->fd) set_fd_events( queue->fd, 0 ); + if (queue->fd) + { + /* after waiting, assume that all events will be processed */ + clear_queue_bits( queue, QS_DRIVER ); + set_fd_events( queue->fd, 0 ); + } }
static void msg_queue_dump( struct object *obj, int verbose ) @@ -1387,6 +1411,7 @@ static void msg_queue_poll_event( struct fd *fd, int event )
if (event & (POLLERR | POLLHUP)) set_fd_events( fd, -1 ); else set_fd_events( queue->fd, 0 ); + set_queue_bits( queue, QS_DRIVER ); signal_queue_sync( queue ); }