From: Rémi Bernon rbernon@codeweavers.com
This is called before waiting on the queue and makes the access time reliable to detect hung queues. --- server/queue.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/server/queue.c b/server/queue.c index 3f06c15d006..f139793e400 100644 --- a/server/queue.c +++ b/server/queue.c @@ -3161,6 +3161,7 @@ DECL_HANDLER(set_queue_mask)
SHARED_WRITE_BEGIN( queue_shm, queue_shm_t ) { + shared->access_time = monotonic_time; shared->wake_mask = req->wake_mask; shared->changed_mask = req->changed_mask; reply->wake_bits = shared->wake_bits;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/message.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index d3ef83785bb..df64e059177 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -3229,7 +3229,10 @@ static BOOL check_queue_masks( UINT wake_mask, UINT changed_mask ) UINT status;
while ((status = get_shared_queue( &lock, &queue_shm )) == STATUS_PENDING) - skip = queue_shm->wake_mask == wake_mask && queue_shm->changed_mask == changed_mask; + { + if (queue_shm->wake_mask != wake_mask || queue_shm->changed_mask != changed_mask) skip = FALSE; + else skip = get_tick_count() - (UINT64)queue_shm->access_time / 10000 < 3000; /* avoid hung queue */ + }
if (status) return FALSE; return skip;
From: Rémi Bernon rbernon@codeweavers.com
--- server/queue.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/server/queue.c b/server/queue.c index f139793e400..a1d2595e856 100644 --- a/server/queue.c +++ b/server/queue.c @@ -1283,9 +1283,8 @@ static void cleanup_results( struct msg_queue *queue ) /* check if the thread owning the queue is hung (not checking for messages) */ static int is_queue_hung( struct msg_queue *queue ) { - if (monotonic_time - queue->shared->access_time <= 5 * TICKS_PER_SEC) - return 0; /* less than 5 seconds since last get message -> not hung */ - return !queue->waiting; + /* queue is hung if it's signaled and thread didn't access it for more than 5 seconds */ + return queue->signaled && monotonic_time - queue->shared->access_time > 5 * TICKS_PER_SEC; }
static int msg_queue_select( struct msg_queue *queue, int events )
From: Rémi Bernon rbernon@codeweavers.com
--- server/queue.c | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-)
diff --git a/server/queue.c b/server/queue.c index a1d2595e856..268c921a914 100644 --- a/server/queue.c +++ b/server/queue.c @@ -134,7 +134,6 @@ struct msg_queue struct thread_input *input; /* thread input descriptor */ struct hook_table *hooks; /* hook table */ int keystate_lock; /* owns an input keystate lock */ - int waiting; /* is thread waiting on queue */ queue_shm_t *shared; /* queue in session shared memory */ };
@@ -319,7 +318,6 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_ queue->input = (struct thread_input *)grab_object( input ); queue->hooks = NULL; queue->keystate_lock = 0; - queue->waiting = 0; list_init( &queue->send_result ); list_init( &queue->callback_result ); list_init( &queue->pending_timers ); @@ -1287,23 +1285,6 @@ static int is_queue_hung( struct msg_queue *queue ) return queue->signaled && monotonic_time - queue->shared->access_time > 5 * TICKS_PER_SEC; }
-static int msg_queue_select( struct msg_queue *queue, int events ) -{ - if (queue->waiting == !!events) - { - set_error( STATUS_ACCESS_DENIED ); - return 0; - } - queue->waiting = !!events; - - if (queue->fd) - { - if (events && check_fd_events( queue->fd, POLLIN )) signal_queue_sync( queue ); - else set_fd_events( queue->fd, events ); - } - return 1; -} - static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *entry ) { struct msg_queue *queue = (struct msg_queue *)obj; @@ -1315,7 +1296,11 @@ static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *ent return 0; }
- if (!msg_queue_select( queue, POLLIN )) return 0; + if (queue->fd) + { + if (check_fd_events( queue->fd, POLLIN )) signal_queue_sync( queue ); + else set_fd_events( queue->fd, POLLIN ); + } add_queue( obj, entry ); return 1; } @@ -1325,7 +1310,7 @@ 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 ); - msg_queue_select( queue, 0 ); + if (queue->fd) set_fd_events( queue->fd, 0 ); }
static void msg_queue_dump( struct object *obj, int verbose )