Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
3403002c
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
3403002c
编写于
7月 12, 2010
作者:
L
lana
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
e3f35040
08f5c35c
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
533 addition
and
250 deletion
+533
-250
src/share/classes/java/awt/EventDispatchThread.java
src/share/classes/java/awt/EventDispatchThread.java
+41
-87
src/share/classes/java/awt/EventQueue.java
src/share/classes/java/awt/EventQueue.java
+112
-95
src/share/classes/sun/awt/SunToolkit.java
src/share/classes/sun/awt/SunToolkit.java
+44
-11
src/solaris/classes/sun/awt/X11/XToolkit.java
src/solaris/classes/sun/awt/X11/XToolkit.java
+20
-10
src/solaris/classes/sun/awt/X11/XWindow.java
src/solaris/classes/sun/awt/X11/XWindow.java
+2
-2
src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c
src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c
+22
-10
test/java/awt/EventDispatchThread/HandleExceptionOnEDT/HandleExceptionOnEDT.java
...atchThread/HandleExceptionOnEDT/HandleExceptionOnEDT.java
+23
-0
test/java/awt/EventDispatchThread/LoopRobustness/LoopRobustness.java
...wt/EventDispatchThread/LoopRobustness/LoopRobustness.java
+38
-31
test/java/awt/EventDispatchThread/PreserveDispathThread/PreserveDispatchThread.java
...hThread/PreserveDispathThread/PreserveDispatchThread.java
+224
-0
test/java/awt/EventQueue/PushPopDeadlock2/PushPopTest.java
test/java/awt/EventQueue/PushPopDeadlock2/PushPopTest.java
+7
-4
未找到文件。
src/share/classes/java/awt/EventDispatchThread.java
浏览文件 @
3403002c
...
...
@@ -61,85 +61,43 @@ import sun.awt.EventQueueDelegate;
* @since 1.1
*/
class
EventDispatchThread
extends
Thread
{
private
static
final
PlatformLogger
eventLog
=
PlatformLogger
.
getLogger
(
"java.awt.event.EventDispatchThread"
);
private
EventQueue
theQueue
;
private
boolean
doDispatch
=
true
;
private
boolean
threadDeathCaught
=
false
;
private
static
final
int
ANY_EVENT
=
-
1
;
private
Vector
<
EventFilter
>
eventFilters
=
new
Vector
<
EventFilter
>();
// used in handleException
private
int
modalFiltersCount
=
0
;
EventDispatchThread
(
ThreadGroup
group
,
String
name
,
EventQueue
queue
)
{
super
(
group
,
name
);
theQueue
=
queue
;
}
void
stopDispatchingImpl
(
boolean
wait
)
{
// Note: We stop dispatching via a flag rather than using
// Thread.interrupt() because we can't guarantee that the wait()
// we interrupt will be EventQueue.getNextEvent()'s. -fredx 8-11-98
StopDispatchEvent
stopEvent
=
new
StopDispatchEvent
();
// wait for the dispatcher to complete
if
(
Thread
.
currentThread
()
!=
this
)
{
// fix 4122683, 4128923
// Post an empty event to ensure getNextEvent is unblocked
//
// We have to use postEventPrivate instead of postEvent because
// EventQueue.pop calls EventDispatchThread.stopDispatching.
// Calling SunToolkit.flushPendingEvents in this case could
// lead to deadlock.
theQueue
.
postEventPrivate
(
stopEvent
);
if
(
wait
)
{
try
{
join
();
}
catch
(
InterruptedException
e
)
{
}
}
}
else
{
stopEvent
.
dispatch
();
}
theQueue
.
detachDispatchThread
(
this
,
false
);
setEventQueue
(
queue
);
}
/*
* Must be called on EDT only, that's why no synchronization
*/
public
void
stopDispatching
()
{
stopDispatchingImpl
(
true
);
}
public
void
stopDispatchingLater
()
{
stopDispatchingImpl
(
false
);
}
class
StopDispatchEvent
extends
AWTEvent
implements
ActiveEvent
{
/*
* serialVersionUID
*/
static
final
long
serialVersionUID
=
-
3692158172100730735L
;
public
StopDispatchEvent
()
{
super
(
EventDispatchThread
.
this
,
0
);
}
public
void
dispatch
()
{
doDispatch
=
false
;
}
doDispatch
=
false
;
}
public
void
run
()
{
try
{
pumpEvents
(
new
Conditional
()
{
public
boolean
evaluate
()
{
return
true
;
while
(
true
)
{
try
{
pumpEvents
(
new
Conditional
()
{
public
boolean
evaluate
()
{
return
true
;
}
});
}
finally
{
EventQueue
eq
=
getEventQueue
();
if
(
eq
.
detachDispatchThread
(
this
)
||
threadDeathCaught
)
{
break
;
}
});
}
finally
{
theQueue
.
detachDispatchThread
(
this
,
true
);
}
}
}
...
...
@@ -190,7 +148,6 @@ class EventDispatchThread extends Thread {
}
}
eventFilters
.
add
(
k
,
filter
);
modalFiltersCount
++;
}
else
{
eventFilters
.
add
(
filter
);
}
...
...
@@ -200,28 +157,25 @@ class EventDispatchThread extends Thread {
void
removeEventFilter
(
EventFilter
filter
)
{
synchronized
(
eventFilters
)
{
if
(
eventFilters
.
contains
(
filter
))
{
if
(
filter
instanceof
ModalEventFilter
)
{
modalFiltersCount
--;
}
eventFilters
.
remove
(
filter
);
}
eventFilters
.
remove
(
filter
);
}
}
boolean
pumpOneEventForFilters
(
int
id
)
{
AWTEvent
event
=
null
;
boolean
eventOK
=
false
;
try
{
AWTEvent
event
;
boolean
eventOK
;
EventQueueDelegate
.
Delegate
delegate
=
EventQueueDelegate
.
getDelegate
();
EventQueue
eq
=
null
;
EventQueueDelegate
.
Delegate
delegate
=
null
;
do
{
// EventQueue may change during the dispatching
eq
=
getEventQueue
();
delegate
=
EventQueueDelegate
.
getDelegate
();
if
(
delegate
!=
null
&&
id
==
ANY_EVENT
)
{
event
=
delegate
.
getNextEvent
(
theQueue
);
event
=
delegate
.
getNextEvent
(
eq
);
}
else
{
event
=
(
id
==
ANY_EVENT
)
?
theQueue
.
getNextEvent
()
:
theQueue
.
getNextEvent
(
id
);
event
=
(
id
==
ANY_EVENT
)
?
eq
.
getNextEvent
()
:
eq
.
getNextEvent
(
id
);
}
eventOK
=
true
;
...
...
@@ -252,13 +206,15 @@ class EventDispatchThread extends Thread {
if
(
delegate
!=
null
)
{
handle
=
delegate
.
beforeDispatch
(
event
);
}
theQueue
.
dispatchEvent
(
event
);
eq
.
dispatchEvent
(
event
);
if
(
delegate
!=
null
)
{
delegate
.
afterDispatch
(
event
,
handle
);
}
return
true
;
}
catch
(
ThreadDeath
death
)
{
threadDeathCaught
=
true
;
return
false
;
}
...
...
@@ -267,12 +223,10 @@ class EventDispatchThread extends Thread {
// Threads in the AppContext
}
// Can get and throw only unchecked exceptions
catch
(
RuntimeException
e
)
{
processException
(
e
);
}
catch
(
Error
e
)
{
catch
(
Throwable
e
)
{
processException
(
e
);
}
return
true
;
}
...
...
@@ -281,14 +235,14 @@ class EventDispatchThread extends Thread {
eventLog
.
fine
(
"Processing exception: "
+
e
);
}
getUncaughtExceptionHandler
().
uncaughtException
(
this
,
e
);
// don't rethrow the exception to avoid EDT recreation
}
boolean
isDispatching
(
EventQueue
eq
)
{
return
theQueue
.
equals
(
eq
);
public
synchronized
EventQueue
getEventQueue
()
{
return
theQueue
;
}
public
synchronized
void
setEventQueue
(
EventQueue
eq
)
{
theQueue
=
eq
;
}
EventQueue
getEventQueue
()
{
return
theQueue
;
}
private
static
class
HierarchyEventFilter
implements
EventFilter
{
private
Component
modalComponent
;
...
...
src/share/classes/java/awt/EventQueue.java
浏览文件 @
3403002c
...
...
@@ -138,6 +138,15 @@ public class EventQueue {
private
final
Lock
pushPopLock
;
private
final
Condition
pushPopCond
;
/*
* Dummy runnable to wake up EDT from getNextEvent() after
push/pop is performed
*/
private
final
static
Runnable
dummyRunnable
=
new
Runnable
()
{
public
void
run
()
{
}
};
private
EventDispatchThread
dispatchThread
;
private
final
ThreadGroup
threadGroup
=
...
...
@@ -219,22 +228,22 @@ public class EventQueue {
* @param theEvent an instance of <code>java.awt.AWTEvent</code>,
* or a subclass of it
*/
final
void
postEventPrivate
(
AWTEvent
theEvent
)
{
private
final
void
postEventPrivate
(
AWTEvent
theEvent
)
{
theEvent
.
isPosted
=
true
;
pushPopLock
.
lock
();
try
{
if
(
dispatchThread
==
null
&&
nextQueue
==
null
)
{
if
(
nextQueue
!=
null
)
{
// Forward the event to the top of EventQueue stack
nextQueue
.
postEventPrivate
(
theEvent
);
return
;
}
if
(
dispatchThread
==
null
)
{
if
(
theEvent
.
getSource
()
==
AWTAutoShutdown
.
getInstance
())
{
return
;
}
else
{
initDispatchThread
();
}
}
if
(
nextQueue
!=
null
)
{
// Forward event to top of EventQueue stack.
nextQueue
.
postEventPrivate
(
theEvent
);
return
;
}
postEvent
(
theEvent
,
getPriority
(
theEvent
));
}
finally
{
pushPopLock
.
unlock
();
...
...
@@ -242,29 +251,20 @@ public class EventQueue {
}
private
static
int
getPriority
(
AWTEvent
theEvent
)
{
if
(
theEvent
instanceof
PeerEvent
&&
(((
PeerEvent
)
theEvent
).
getFlags
()
&
PeerEvent
.
ULTIMATE_PRIORITY_EVENT
)
!=
0
)
{
return
ULTIMATE_PRIORITY
;
}
if
(
theEvent
instanceof
PeerEvent
&&
(((
PeerEvent
)
theEvent
).
getFlags
()
&
PeerEvent
.
PRIORITY_EVENT
)
!=
0
)
{
return
HIGH_PRIORITY
;
}
if
(
theEvent
instanceof
PeerEvent
&&
(((
PeerEvent
)
theEvent
).
getFlags
()
&
PeerEvent
.
LOW_PRIORITY_EVENT
)
!=
0
)
{
return
LOW_PRIORITY
;
if
(
theEvent
instanceof
PeerEvent
)
{
PeerEvent
peerEvent
=
(
PeerEvent
)
theEvent
;
if
((
peerEvent
.
getFlags
()
&
PeerEvent
.
ULTIMATE_PRIORITY_EVENT
)
!=
0
)
{
return
ULTIMATE_PRIORITY
;
}
if
((
peerEvent
.
getFlags
()
&
PeerEvent
.
PRIORITY_EVENT
)
!=
0
)
{
return
HIGH_PRIORITY
;
}
if
((
peerEvent
.
getFlags
()
&
PeerEvent
.
LOW_PRIORITY_EVENT
)
!=
0
)
{
return
LOW_PRIORITY
;
}
}
int
id
=
theEvent
.
getID
();
if
(
id
==
PaintEvent
.
PAINT
||
id
==
PaintEvent
.
UPDATE
)
{
if
(
(
id
>=
PaintEvent
.
PAINT_FIRST
)
&&
(
id
<=
PaintEvent
.
PAINT_LAST
)
)
{
return
LOW_PRIORITY
;
}
return
NORM_PRIORITY
;
...
...
@@ -501,16 +501,9 @@ public class EventQueue {
SunToolkit
.
flushPendingEvents
();
pushPopLock
.
lock
();
try
{
for
(
int
i
=
NUM_PRIORITIES
-
1
;
i
>=
0
;
i
--)
{
if
(
queues
[
i
].
head
!=
null
)
{
EventQueueItem
entry
=
queues
[
i
].
head
;
queues
[
i
].
head
=
entry
.
next
;
if
(
entry
.
next
==
null
)
{
queues
[
i
].
tail
=
null
;
}
uncacheEQItem
(
entry
);
return
entry
.
event
;
}
AWTEvent
event
=
getNextEventPrivate
();
if
(
event
!=
null
)
{
return
event
;
}
AWTAutoShutdown
.
getInstance
().
notifyThreadFree
(
dispatchThread
);
pushPopCond
.
await
();
...
...
@@ -520,6 +513,24 @@ public class EventQueue {
}
while
(
true
);
}
/*
* Must be called under the lock. Doesn't call flushPendingEvents()
*/
AWTEvent
getNextEventPrivate
()
throws
InterruptedException
{
for
(
int
i
=
NUM_PRIORITIES
-
1
;
i
>=
0
;
i
--)
{
if
(
queues
[
i
].
head
!=
null
)
{
EventQueueItem
entry
=
queues
[
i
].
head
;
queues
[
i
].
head
=
entry
.
next
;
if
(
entry
.
next
==
null
)
{
queues
[
i
].
tail
=
null
;
}
uncacheEQItem
(
entry
);
return
entry
.
event
;
}
}
return
null
;
}
AWTEvent
getNextEvent
(
int
id
)
throws
InterruptedException
{
do
{
/*
...
...
@@ -659,7 +670,9 @@ public class EventQueue {
dispatchThread
.
stopDispatching
();
}
}
else
{
System
.
err
.
println
(
"unable to dispatch event: "
+
event
);
if
(
eventLog
.
isLoggable
(
PlatformLogger
.
FINE
))
{
eventLog
.
fine
(
"Unable to dispatch event: "
+
event
);
}
}
}
...
...
@@ -761,15 +774,23 @@ public class EventQueue {
pushPopLock
.
lock
();
try
{
EventQueue
toPush
=
this
;
while
(
toPush
.
nextQueue
!=
null
)
{
toPush
=
toPush
.
nextQueue
;
EventQueue
topQueue
=
this
;
while
(
topQueue
.
nextQueue
!=
null
)
{
topQueue
=
topQueue
.
nextQueue
;
}
if
((
topQueue
.
dispatchThread
!=
null
)
&&
(
topQueue
.
dispatchThread
.
getEventQueue
()
==
this
))
{
newEventQueue
.
dispatchThread
=
topQueue
.
dispatchThread
;
topQueue
.
dispatchThread
.
setEventQueue
(
newEventQueue
);
}
// Transfer all events forward to new EventQueue.
while
(
to
Push
.
peekEvent
()
!=
null
)
{
while
(
to
pQueue
.
peekEvent
()
!=
null
)
{
try
{
newEventQueue
.
postEventPrivate
(
toPush
.
getNextEvent
());
// Use getNextEventPrivate() as it doesn't call flushPendingEvents()
newEventQueue
.
postEventPrivate
(
topQueue
.
getNextEventPrivate
());
}
catch
(
InterruptedException
ie
)
{
if
(
eventLog
.
isLoggable
(
PlatformLogger
.
FINE
))
{
eventLog
.
fine
(
"Interrupted push"
,
ie
);
...
...
@@ -777,28 +798,21 @@ public class EventQueue {
}
}
newEventQueue
.
previousQueue
=
toPush
;
/*
* Stop the event dispatch thread associated with the currently
* active event queue, so that after the new queue is pushed
* on the top this event dispatch thread won't prevent AWT from
* being automatically shut down.
* Use stopDispatchingLater() to avoid deadlock: stopDispatching()
* waits for the dispatch thread to exit, which in turn waits
* for the lock in EQ.detachDispatchThread(), which is hold by
* this method.
*/
if
(
toPush
.
dispatchThread
!=
null
)
{
toPush
.
dispatchThread
.
stopDispatchingLater
();
}
// Wake up EDT waiting in getNextEvent(), so it can
// pick up a new EventQueue. Post the waking event before
// topQueue.nextQueue is assigned, otherwise the event would
// go newEventQueue
topQueue
.
postEventPrivate
(
new
InvocationEvent
(
topQueue
,
dummyRunnable
));
toPush
.
nextQueue
=
newEventQueue
;
newEventQueue
.
previousQueue
=
topQueue
;
topQueue
.
nextQueue
=
newEventQueue
;
AppContext
appContext
=
AppContext
.
getAppContext
();
if
(
appContext
.
get
(
AppContext
.
EVENT_QUEUE_KEY
)
==
to
Push
)
{
if
(
appContext
.
get
(
AppContext
.
EVENT_QUEUE_KEY
)
==
to
pQueue
)
{
appContext
.
put
(
AppContext
.
EVENT_QUEUE_KEY
,
newEventQueue
);
}
pushPopCond
.
signalAll
();
}
finally
{
pushPopLock
.
unlock
();
}
...
...
@@ -822,44 +836,51 @@ public class EventQueue {
eventLog
.
fine
(
"EventQueue.pop("
+
this
+
")"
);
}
EventDispatchThread
dt
=
null
;
pushPopLock
.
lock
();
try
{
EventQueue
to
Pop
=
this
;
while
(
to
Pop
.
nextQueue
!=
null
)
{
to
Pop
=
toPop
.
nextQueue
;
EventQueue
to
pQueue
=
this
;
while
(
to
pQueue
.
nextQueue
!=
null
)
{
to
pQueue
=
topQueue
.
nextQueue
;
}
EventQueue
prev
=
toPop
.
previousQueue
;
if
(
prev
==
null
)
{
EventQueue
prev
Queue
=
topQueue
.
previousQueue
;
if
(
prev
Queue
==
null
)
{
throw
new
EmptyStackException
();
}
toPop
.
previousQueue
=
null
;
topQueue
.
previousQueue
=
null
;
prevQueue
.
nextQueue
=
null
;
// Transfer all events back to previous EventQueue.
prev
.
nextQueue
=
null
;
while
(
toPop
.
peekEvent
()
!=
null
)
{
while
(
topQueue
.
peekEvent
()
!=
null
)
{
try
{
prev
.
postEventPrivate
(
toPop
.
getNextEvent
());
prev
Queue
.
postEventPrivate
(
topQueue
.
getNextEventPrivate
());
}
catch
(
InterruptedException
ie
)
{
if
(
eventLog
.
isLoggable
(
PlatformLogger
.
FINE
))
{
eventLog
.
fine
(
"Interrupted pop"
,
ie
);
}
}
}
if
((
topQueue
.
dispatchThread
!=
null
)
&&
(
topQueue
.
dispatchThread
.
getEventQueue
()
==
this
))
{
prevQueue
.
dispatchThread
=
topQueue
.
dispatchThread
;
topQueue
.
dispatchThread
.
setEventQueue
(
prevQueue
);
}
AppContext
appContext
=
AppContext
.
getAppContext
();
if
(
appContext
.
get
(
AppContext
.
EVENT_QUEUE_KEY
)
==
this
)
{
appContext
.
put
(
AppContext
.
EVENT_QUEUE_KEY
,
prev
);
appContext
.
put
(
AppContext
.
EVENT_QUEUE_KEY
,
prev
Queue
);
}
dt
=
toPop
.
dispatchThread
;
// Wake up EDT waiting in getNextEvent(), so it can
// pick up a new EventQueue
topQueue
.
postEventPrivate
(
new
InvocationEvent
(
topQueue
,
dummyRunnable
));
pushPopCond
.
signalAll
();
}
finally
{
pushPopLock
.
unlock
();
}
if
(
dt
!=
null
)
{
dt
.
stopDispatching
();
// Must be done outside synchronized
// block to avoid possible deadlock
}
}
/**
...
...
@@ -907,9 +928,9 @@ public class EventQueue {
try
{
AppContext
appContext
=
AppContext
.
getAppContext
();
if
(
dispatchThread
==
null
&&
!
threadGroup
.
isDestroyed
()
&&
!
appContext
.
isDisposed
())
{
dispatchThread
=
(
EventDispatchThread
)
AccessController
.
doPrivileged
(
new
PrivilegedAction
()
{
public
Object
run
()
{
dispatchThread
=
AccessController
.
doPrivileged
(
new
PrivilegedAction
<
EventDispatchThread
>
()
{
public
EventDispatchThread
run
()
{
EventDispatchThread
t
=
new
EventDispatchThread
(
threadGroup
,
name
,
...
...
@@ -919,7 +940,8 @@ public class EventQueue {
t
.
setDaemon
(
false
);
return
t
;
}
});
}
);
AWTAutoShutdown
.
getInstance
().
notifyThreadBusy
(
dispatchThread
);
dispatchThread
.
start
();
}
...
...
@@ -928,7 +950,7 @@ public class EventQueue {
}
}
final
void
detachDispatchThread
(
EventDispatchThread
edt
,
boolean
restar
t
)
{
final
boolean
detachDispatchThread
(
EventDispatchThread
ed
t
)
{
/*
* This synchronized block is to secure that the event dispatch
* thread won't die in the middle of posting a new event to the
...
...
@@ -939,26 +961,21 @@ public class EventQueue {
*/
pushPopLock
.
lock
();
try
{
EventDispatchThread
oldDispatchThread
=
dispatchThread
;
if
(
dispatchThread
==
edt
)
{
dispatchThread
=
null
;
}
if
(
restart
)
{
if
(
edt
==
dispatchThread
)
{
/*
* Event dispatch thread dies in case of an uncaught exception.
* A new event dispatch thread for this queue will be started
* only if a new event is posted to it. In case if no more
* events are posted after this thread died all events that
* currently are in the queue will never be dispatched.
* Don't detach the thread if any events are pending. Not
* sure if it's a possible scenario, though.
*
* Fix for 4648733. Check both the associated java event
* queue and the PostEventQueue.
*/
if
((
peekEvent
()
!=
null
)
||
!
SunToolkit
.
isPostEventQueueEmpty
())
{
initDispatchThread
()
;
return
false
;
}
AWTAutoShutdown
.
getInstance
().
notifyThreadFree
(
oldDispatchThread
)
;
dispatchThread
=
null
;
}
AWTAutoShutdown
.
getInstance
().
notifyThreadFree
(
edt
);
return
true
;
}
finally
{
pushPopLock
.
unlock
();
}
...
...
src/share/classes/sun/awt/SunToolkit.java
浏览文件 @
3403002c
...
...
@@ -39,6 +39,7 @@ import java.net.URL;
import
java.util.*
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.locks.Condition
;
import
java.util.concurrent.locks.Lock
;
import
java.util.concurrent.locks.ReentrantLock
;
import
sun.util.logging.PlatformLogger
;
import
sun.misc.SoftCache
;
...
...
@@ -592,7 +593,7 @@ public abstract class SunToolkit extends Toolkit
}
PostEventQueue
postEventQueue
=
(
PostEventQueue
)
appContext
.
get
(
POST_EVENT_QUEUE_KEY
);
if
(
postEventQueue
!=
null
)
{
if
(
postEventQueue
!=
null
)
{
postEventQueue
.
postEvent
(
event
);
}
}
...
...
@@ -610,16 +611,29 @@ public abstract class SunToolkit extends Toolkit
postEvent
(
targetToAppContext
(
e
.
getSource
()),
pe
);
}
private
static
final
Lock
flushLock
=
new
ReentrantLock
();
private
static
boolean
isFlushingPendingEvents
=
false
;
/*
* Flush any pending events which haven't been posted to the AWT
* EventQueue yet.
*/
public
static
void
flushPendingEvents
()
{
AppContext
appContext
=
AppContext
.
getAppContext
();
PostEventQueue
postEventQueue
=
(
PostEventQueue
)
appContext
.
get
(
POST_EVENT_QUEUE_KEY
);
if
(
postEventQueue
!=
null
)
{
postEventQueue
.
flush
();
flushLock
.
lock
();
try
{
// Don't call flushPendingEvents() recursively
if
(!
isFlushingPendingEvents
)
{
isFlushingPendingEvents
=
true
;
AppContext
appContext
=
AppContext
.
getAppContext
();
PostEventQueue
postEventQueue
=
(
PostEventQueue
)
appContext
.
get
(
POST_EVENT_QUEUE_KEY
);
if
(
postEventQueue
!=
null
)
{
postEventQueue
.
flush
();
}
}
}
finally
{
isFlushingPendingEvents
=
false
;
flushLock
.
unlock
();
}
}
...
...
@@ -1930,6 +1944,25 @@ public abstract class SunToolkit extends Toolkit
return
(
Window
)
comp
;
}
/**
* Returns the value of the system property indicated by the specified key.
*/
public
static
String
getSystemProperty
(
final
String
key
)
{
return
(
String
)
AccessController
.
doPrivileged
(
new
PrivilegedAction
()
{
public
Object
run
()
{
return
System
.
getProperty
(
key
);
}
});
}
/**
* Returns the boolean value of the system property indicated by the specified key.
*/
protected
static
Boolean
getBooleanSystemProperty
(
String
key
)
{
return
Boolean
.
valueOf
(
AccessController
.
doPrivileged
(
new
GetBooleanAction
(
key
)));
}
private
static
Boolean
sunAwtDisableMixing
=
null
;
/**
...
...
@@ -1938,9 +1971,7 @@ public abstract class SunToolkit extends Toolkit
*/
public
synchronized
static
boolean
getSunAwtDisableMixing
()
{
if
(
sunAwtDisableMixing
==
null
)
{
sunAwtDisableMixing
=
Boolean
.
valueOf
(
AccessController
.
doPrivileged
(
new
GetBooleanAction
(
"sun.awt.disableMixing"
)));
sunAwtDisableMixing
=
getBooleanSystemProperty
(
"sun.awt.disableMixing"
);
}
return
sunAwtDisableMixing
.
booleanValue
();
}
...
...
@@ -2079,12 +2110,14 @@ class PostEventQueue {
eventQueue
=
eq
;
}
public
boolean
noEvents
()
{
public
synchronized
boolean
noEvents
()
{
return
queueHead
==
null
;
}
/*
* Continually post pending AWTEvents to the Java EventQueue.
* Continually post pending AWTEvents to the Java EventQueue. The method
* is synchronized to ensure the flush is completed before a new event
* can be posted to this queue.
*/
public
synchronized
void
flush
()
{
EventQueueItem
tempQueue
=
queueHead
;
...
...
src/solaris/classes/sun/awt/X11/XToolkit.java
浏览文件 @
3403002c
...
...
@@ -1053,10 +1053,28 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
return
peer
;
}
private
static
Boolean
sunAwtDisableGtkFileDialogs
=
null
;
/**
* Returns the value of "sun.awt.disableGtkFileDialogs" property. Default
* value is {@code false}.
*/
public
synchronized
static
boolean
getSunAwtDisableGtkFileDialogs
()
{
if
(
sunAwtDisableGtkFileDialogs
==
null
)
{
sunAwtDisableGtkFileDialogs
=
getBooleanSystemProperty
(
"sun.awt.disableGtkFileDialogs"
);
}
return
sunAwtDisableGtkFileDialogs
.
booleanValue
();
}
public
FileDialogPeer
createFileDialog
(
FileDialog
target
)
{
FileDialogPeer
peer
=
null
;
// The current GtkFileChooser is available from GTK+ 2.4
FileDialogPeer
peer
=
checkGtkVersion
(
2
,
4
,
0
)
?
new
GtkFileDialogPeer
(
target
)
:
new
XFileDialogPeer
(
target
);
if
(!
getSunAwtDisableGtkFileDialogs
()
&&
checkGtkVersion
(
2
,
4
,
0
))
{
peer
=
new
GtkFileDialogPeer
(
target
);
}
else
{
peer
=
new
XFileDialogPeer
(
target
);
}
targetCreatedPeer
(
target
,
peer
);
return
peer
;
}
...
...
@@ -1201,14 +1219,6 @@ public final class XToolkit extends UNIXToolkit implements Runnable {
}
}
static
String
getSystemProperty
(
final
String
name
)
{
return
(
String
)
AccessController
.
doPrivileged
(
new
PrivilegedAction
()
{
public
Object
run
()
{
return
System
.
getProperty
(
name
);
}
});
}
public
PrintJob
getPrintJob
(
final
Frame
frame
,
final
String
doctitle
,
final
Properties
props
)
{
...
...
src/solaris/classes/sun/awt/X11/XWindow.java
浏览文件 @
3403002c
...
...
@@ -778,8 +778,8 @@ public class XWindow extends XBaseWindow implements X11ComponentPeer {
x
,
y
,
xbe
.
get_x_root
(),
xbe
.
get_y_root
(),
clickCount
,
false
,
MouseWheelEvent
.
WHEEL_UNIT_SCROLL
,
3
,
button
==
4
?
-
1
:
1
);
1
,
false
,
MouseWheelEvent
.
WHEEL_UNIT_SCROLL
,
3
,
button
==
4
?
-
1
*
clickCount
:
1
*
clickCount
);
postEventToEventQueue
(
mwe
);
}
}
...
...
src/solaris/native/sun/awt/sun_awt_X11_GtkFileDialogPeer.c
浏览文件 @
3403002c
...
...
@@ -42,17 +42,16 @@ static gboolean filenameFilterCallback(const GtkFileFilterInfo * filter_info, gp
filename
);
}
/*
* Class: sun_awt_X11_GtkFileDialogPeer
* Method: quit
* Signature: ()V
*/
JNIEXPORT
void
JNICALL
Java_sun_awt_X11_GtkFileDialogPeer_quit
(
JNIEnv
*
env
,
jobject
jpeer
)
static
void
quit
(
gboolean
isSignalHandler
)
{
if
(
dialog
!=
NULL
)
{
fp_gdk_threads_enter
();
// Callbacks from GTK signals are made within the GTK lock
// So, within a signal handler there is no need to call
// gdk_threads_enter() / fp_gdk_threads_leave()
if
(
!
isSignalHandler
)
{
fp_gdk_threads_enter
();
}
fp_gtk_widget_hide
(
dialog
);
fp_gtk_widget_destroy
(
dialog
);
...
...
@@ -60,10 +59,23 @@ JNIEXPORT void JNICALL Java_sun_awt_X11_GtkFileDialogPeer_quit
fp_gtk_main_quit
();
dialog
=
NULL
;
fp_gdk_threads_leave
();
if
(
!
isSignalHandler
)
{
fp_gdk_threads_leave
();
}
}
}
/*
* Class: sun_awt_X11_GtkFileDialogPeer
* Method: quit
* Signature: ()V
*/
JNIEXPORT
void
JNICALL
Java_sun_awt_X11_GtkFileDialogPeer_quit
(
JNIEnv
*
env
,
jobject
jpeer
)
{
quit
(
FALSE
);
}
/**
* Convert a GSList to an array of filenames (without the parent folder)
*/
...
...
@@ -147,7 +159,7 @@ static void handle_response(GtkWidget* aDialog, gint responseId, gpointer obj)
jfilenames
);
fp_g_free
(
current_folder
);
Java_sun_awt_X11_GtkFileDialogPeer_quit
(
NULL
,
NULL
);
quit
(
TRUE
);
}
/*
...
...
test/java/awt/EventDispatchThread/HandleExceptionOnEDT/HandleExceptionOnEDT.java
浏览文件 @
3403002c
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
@test
@bug 6304473 6727884
...
...
test/java/awt/EventDispatchThread/LoopRobustness/LoopRobustness.java
浏览文件 @
3403002c
...
...
@@ -34,35 +34,40 @@
import
java.awt.*
;
import
java.awt.event.*
;
import
java.lang.Math
;
import
sun.awt.SunToolkit
;
import
test.java.awt.regtesthelpers.Util
;
public
class
LoopRobustness
{
static
int
clicks
=
0
;
final
static
long
TIMEOUT
=
5000
;
final
static
Object
LOCK
=
new
Object
();
static
volatile
boolean
notifyOccur
=
false
;
public
static
void
main
(
String
[]
args
)
{
public
static
int
clicks
=
0
;
public
static
volatile
boolean
notifyOccured
=
false
;
public
static
volatile
boolean
otherExceptionsCaught
=
false
;
public
static
void
main
(
String
[]
args
)
throws
Exception
{
ThreadGroup
mainThreadGroup
=
Thread
.
currentThread
().
getThreadGroup
();
long
at
;
//wait for a TIMEOUT giving a chance to a new Thread above to accomplish its stuff.
synchronized
(
LoopRobustness
.
LOCK
){
synchronized
(
LoopRobustness
.
LOCK
)
{
new
Thread
(
new
TestThreadGroup
(
mainThreadGroup
,
"TestGroup"
),
new
Impl
()).
start
();
at
=
System
.
currentTimeMillis
();
try
{
while
(!
notifyOccur
&&
System
.
currentTimeMillis
()
-
at
<
TIMEOUT
)
{
while
(!
notifyOccured
&&
(
System
.
currentTimeMillis
()
-
at
<
TIMEOUT
)
)
{
LoopRobustness
.
LOCK
.
wait
(
1000
);
}
}
catch
(
InterruptedException
e
)
{
}
catch
(
InterruptedException
e
)
{
throw
new
RuntimeException
(
"Test interrupted."
,
e
);
}
}
if
(
!
notifyOccur
)
{
if
(!
notifyOccured
)
{
//notify doesn't occur after a reasonable time.
throw
new
RuntimeException
(
"Test
failed. Second Thread didn't notify MainThread.
"
);
throw
new
RuntimeException
(
"Test
FAILED: second thread hasn't notified MainThread
"
);
}
//now wait for two clicks
...
...
@@ -75,7 +80,10 @@ public class LoopRobustness {
}
}
if
(
clicks
!=
2
)
{
throw
new
RuntimeException
(
"robot should press button twice"
);
throw
new
RuntimeException
(
"Test FAILED: robot should press button twice"
);
}
if
(
otherExceptionsCaught
)
{
throw
new
RuntimeException
(
"Test FAILED: unexpected exceptions caught"
);
}
}
}
...
...
@@ -83,18 +91,11 @@ public class LoopRobustness {
class
Impl
implements
Runnable
{
static
Robot
robot
;
public
void
run
()
{
SunToolkit
.
createNewAppContext
();
Button
b
=
new
Button
(
"Press me to test the AWT-Event Queue thread"
);
Frame
lr
=
new
Frame
(
"ROBUST FRAME"
);
/* Must load Toolkit on this thread only, rather then on Main.
If load on Main (on the parent ThreadGroup of current ThreadGroup) then
EDT will be created on Main thread and supplied with it's own exceptionHandler,
which just throws an Exception and terminates current thread.
The test implies that EDT is created on the child ThreadGroup (testThreadGroup)
which is supplied with its own uncaughtException().
*/
Toolkit
.
getDefaultToolkit
();
lr
.
setBounds
(
100
,
100
,
300
,
100
);
b
.
addActionListener
(
new
ActionListener
()
{
public
void
actionPerformed
(
ActionEvent
e
)
{
LoopRobustness
.
clicks
++;
...
...
@@ -107,40 +108,46 @@ class Impl implements Runnable{
try
{
robot
=
new
Robot
();
}
catch
(
AWTException
e
)
{
}
catch
(
AWTException
e
)
{
throw
new
RuntimeException
(
"Test interrupted."
,
e
);
}
Util
.
waitForIdle
(
robot
);
synchronized
(
LoopRobustness
.
LOCK
){
LoopRobustness
.
LOCK
.
notify
();
LoopRobustness
.
notifyOccur
=
true
;
LoopRobustness
.
notifyOccur
ed
=
true
;
}
int
i
=
0
;
while
(
i
<
2
)
{
while
(
i
<
2
)
{
robot
.
mouseMove
(
b
.
getLocationOnScreen
().
x
+
b
.
getWidth
()/
2
,
b
.
getLocationOnScreen
().
y
+
b
.
getHeight
()/
2
);
b
.
getLocationOnScreen
().
y
+
b
.
getHeight
()/
2
);
Util
.
waitForIdle
(
robot
);
robot
.
mousePress
(
InputEvent
.
BUTTON1_MASK
);
// robot.delay(10
);
Util
.
waitForIdle
(
robot
);
robot
.
mouseRelease
(
InputEvent
.
BUTTON1_MASK
);
Util
.
waitForIdle
(
robot
);
i
++;
robot
.
delay
(
1000
);
}
}
}
class
TestThreadGroup
extends
ThreadGroup
{
TestThreadGroup
(
ThreadGroup
threadGroup
,
String
name
){
TestThreadGroup
(
ThreadGroup
threadGroup
,
String
name
)
{
super
(
threadGroup
,
name
);
}
public
void
uncaughtException
(
Thread
exitedThread
,
Throwable
e
)
{
e
.
printStackTrace
();
if
((
e
instanceof
ExceptionInInitializerError
)
||
(
e
instanceof
NoClassDefFoundError
)){
throw
new
RuntimeException
(
"Test failed: other Exceptions were thrown "
,
e
);
public
void
uncaughtException
(
Thread
thread
,
Throwable
e
)
{
System
.
out
.
println
(
"Exception caught: "
+
e
);
e
.
printStackTrace
(
System
.
out
);
System
.
out
.
flush
();
if
((
e
instanceof
ExceptionInInitializerError
)
||
(
e
instanceof
NoClassDefFoundError
))
{
// These two are expected
return
;
}
LoopRobustness
.
otherExceptionsCaught
=
true
;
}
}
...
...
test/java/awt/EventDispatchThread/PreserveDispathThread/PreserveDispatchThread.java
0 → 100644
浏览文件 @
3403002c
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
@test
@bug 6424157
@author Artem Ananiev: area=eventqueue
@run main PreserveDispatchThread
*/
import
java.awt.*
;
import
java.awt.event.*
;
public
class
PreserveDispatchThread
{
private
static
volatile
Frame
f
;
private
static
volatile
Dialog
d
;
private
static
volatile
boolean
isEDT
=
true
;
public
static
void
main
(
String
[]
args
)
throws
Exception
{
f
=
new
Frame
(
"F"
);
f
.
setSize
(
320
,
340
);
f
.
setLocationRelativeTo
(
null
);
f
.
setVisible
(
true
);
try
{
test1
();
if
(!
isEDT
)
{
throw
new
RuntimeException
(
"Test FAILED (test1): event dispatch thread is changed"
);
}
test2
();
if
(!
isEDT
)
{
throw
new
RuntimeException
(
"Test FAILED (test2): event dispatch thread is changed"
);
}
test3
();
if
(!
isEDT
)
{
throw
new
RuntimeException
(
"Test FAILED (test3): event dispatch thread is changed"
);
}
}
finally
{
if
(
d
!=
null
)
{
d
.
dispose
();
}
f
.
dispose
();
}
}
/*
* Tests that push/pop doesn't change the dispatch thread if
* called on EDT.
*/
private
static
void
test1
()
throws
Exception
{
EventQueue
.
invokeAndWait
(
new
Runnable
()
{
@Override
public
void
run
()
{
TestEventQueue
teq
=
new
TestEventQueue
();
EventQueue
seq
=
Toolkit
.
getDefaultToolkit
().
getSystemEventQueue
();
try
{
seq
.
push
(
teq
);
d
=
new
TestDialog
();
d
.
setVisible
(
true
);
checkEDT
();
}
finally
{
teq
.
pop
();
}
checkEDT
();
}
});
}
/*
* Tests that push/pop doesn't change the dispatch thread if
* called on the main thread.
*/
private
static
void
test2
()
throws
Exception
{
TestEventQueue
teq
=
new
TestEventQueue
();
EventQueue
seq
=
Toolkit
.
getDefaultToolkit
().
getSystemEventQueue
();
try
{
seq
.
push
(
teq
);
EventQueue
.
invokeAndWait
(
new
Runnable
()
{
@Override
public
void
run
()
{
checkEDT
();
d
=
new
TestDialog
();
d
.
setVisible
(
true
);
checkEDT
();
}
});
}
finally
{
teq
.
pop
();
}
}
private
static
final
Object
test3Lock
=
new
Object
();
private
static
boolean
test3Sync
=
false
;
/*
* A complex test: several nested invokeLater() are called and
* in every runnable a check for EDT is performed. At the ent
* of the test we wait for all the runnables to be processed
* and the dialog is disposed; otherwise the last EDT check can
* be later than this method returns and the whole test is passed.
*/
private
static
void
test3
()
throws
Exception
{
EventQueue
.
invokeLater
(
new
Runnable
()
{
@Override
public
void
run
()
{
d
=
new
Dialog
(
f
,
true
);
d
.
setSize
(
240
,
180
);
d
.
setLocationRelativeTo
(
f
);
EventQueue
.
invokeLater
(
new
Runnable
()
{
@Override
public
void
run
()
{
d
.
setVisible
(
true
);
checkEDT
();
}
});
EventQueue
.
invokeLater
(
new
Runnable
()
{
@Override
public
void
run
()
{
TestEventQueue
teq
=
new
TestEventQueue
();
EventQueue
seq
=
Toolkit
.
getDefaultToolkit
().
getSystemEventQueue
();
try
{
seq
.
push
(
teq
);
checkEDT
();
EventQueue
.
invokeLater
(
new
Runnable
()
{
@Override
public
void
run
()
{
d
.
dispose
();
checkEDT
();
synchronized
(
test3Lock
)
{
test3Sync
=
true
;
test3Lock
.
notify
();
}
}
});
}
finally
{
teq
.
pop
();
}
checkEDT
();
}
});
checkEDT
();
}
});
synchronized
(
test3Lock
)
{
while
(!
test3Sync
)
{
try
{
test3Lock
.
wait
();
}
catch
(
InterruptedException
ie
)
{
break
;
}
}
}
// Make sure all the nested invokeLater/invokeAndWait are processed
EventQueue
.
invokeAndWait
(
new
Runnable
()
{
@Override
public
void
run
()
{
}
});
}
private
static
void
checkEDT
()
{
isEDT
=
isEDT
&&
EventQueue
.
isDispatchThread
();
}
private
static
class
TestEventQueue
extends
EventQueue
{
public
TestEventQueue
()
{
super
();
}
public
void
pop
()
{
super
.
pop
();
}
}
private
static
class
TestDialog
extends
Dialog
{
private
volatile
boolean
dialogShown
=
false
;
private
volatile
boolean
paintCalled
=
false
;
public
TestDialog
()
{
super
(
f
,
true
);
setSize
(
240
,
180
);
setLocationRelativeTo
(
f
);
addComponentListener
(
new
ComponentAdapter
()
{
@Override
public
void
componentShown
(
ComponentEvent
e
)
{
if
(
paintCalled
)
{
dispose
();
}
dialogShown
=
true
;
}
});
}
@Override
public
void
paint
(
Graphics
g
)
{
if
(
dialogShown
)
{
dispose
();
}
paintCalled
=
true
;
}
}
}
test/java/awt/EventQueue/PushPopDeadlock2/PushPopTest.java
浏览文件 @
3403002c
...
...
@@ -43,6 +43,7 @@ public class PushPopTest {
Runnable
dummy
=
new
Runnable
()
{
public
void
run
()
{
System
.
err
.
println
(
"Dummy is here."
);
System
.
err
.
flush
();
}
};
EventQueue
seq
=
Toolkit
.
getDefaultToolkit
().
getSystemEventQueue
();
...
...
@@ -58,10 +59,11 @@ public class PushPopTest {
Runnable
runnable
=
new
Runnable
()
{
public
void
run
()
{
System
.
err
.
println
(
"Dummy from SunToolkit"
);
System
.
err
.
flush
();
}
};
InvocationEvent
ie
=
new
InvocationEvent
(
eq2
,
runnable
,
null
,
false
);
System
.
err
.
println
(
ie
);
//
System.err.println(ie);
SunToolkit
.
postEvent
(
SunToolkit
.
targetToAppContext
(
frame
),
ie
);
eq1
.
pop
();
frame
.
dispose
();
...
...
@@ -70,14 +72,14 @@ public class PushPopTest {
class
MyEventQueue1
extends
EventQueue
{
public
void
pop
()
throws
EmptyStackException
{
public
void
pop
()
{
super
.
pop
();
}
}
class
MyEventQueue2
extends
EventQueue
{
protected
void
pop
()
throws
EmptyStackException
{
protected
void
pop
()
{
System
.
err
.
println
(
"pop2()"
);
Thread
.
dumpStack
();
try
{
...
...
@@ -85,7 +87,8 @@ class MyEventQueue2 extends EventQueue {
public
void
run
()
{
Runnable
runnable
=
new
Runnable
()
{
public
void
run
()
{
System
.
err
.
println
(
"Dummy from here"
);
System
.
err
.
println
(
"Dummy from pop"
);
System
.
err
.
flush
();
}
};
InvocationEvent
ie
=
new
InvocationEvent
(
MyEventQueue2
.
this
,
runnable
,
null
,
false
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录