From 605d10f7f2c06334b8259cb59e920b1459454161 Mon Sep 17 00:00:00 2001 From: Fernando Nasser Date: Mon, 19 Jan 2004 17:38:36 +0000 Subject: [PATCH] EventQueue.java (pop): Prevent racing condition to add events to the queue out of order by acquiring... * java/awt/EventQueue.java (pop): Prevent racing condition to add events to the queue out of order by acquiring locks in the proper order and not by releasing one before acquiring the other. From-SVN: r76161 --- libjava/ChangeLog | 6 +++++ libjava/java/awt/EventQueue.java | 38 +++++++++++++++++--------------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index afe9565655b..2b34a94f9e1 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,9 @@ +2004-01-19 Fernando Nasser + + * java/awt/EventQueue.java (pop): Prevent racing condition to add + events to the queue out of order by acquiring locks in the proper + order and not by releasing one before acquiring the other. + 2004-01-19 Fernando Nasser * gnu/java/awt/peer/gtk/TestAWT.java (DialogWindow): Make text not diff --git a/libjava/java/awt/EventQueue.java b/libjava/java/awt/EventQueue.java index 4cb0703ec62..7df40edee38 100644 --- a/libjava/java/awt/EventQueue.java +++ b/libjava/java/awt/EventQueue.java @@ -358,32 +358,34 @@ public class EventQueue if (prev == null) throw new EmptyStackException(); - // Don't synchronize both this and prev at the same time, or deadlock could - // occur. + /* The order is important here, we must get the prev lock first, + or deadlock could occur as callers usually get here following + prev's next pointer, and thus obtain prev's lock before trying + to get this lock. */ synchronized (prev) { prev.next = next; if (next != null) next.prev = prev; - } - synchronized (this) - { - int i = next_out; - while (i != next_in) + synchronized (this) { - prev.postEvent(queue[i]); - next_out = i; - if (++i == queue.length) - i = 0; - } - // Empty the queue so it can be reused - next_in = 0; - next_out = 0; + int i = next_out; + while (i != next_in) + { + prev.postEvent(queue[i]); + next_out = i; + if (++i == queue.length) + i = 0; + } + // Empty the queue so it can be reused + next_in = 0; + next_out = 0; - // Tell our EventDispatchThread that it can end execution - dispatchThread.interrupt (); - dispatchThread = null; + // Tell our EventDispatchThread that it can end execution + dispatchThread.interrupt (); + dispatchThread = null; + } } } -- 2.30.2