Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
f6adbf3a
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看板
提交
f6adbf3a
编写于
2月 17, 2017
作者:
S
ssadetsky
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
6980209: Make tracking SecondaryLoop.enter/exit methods easier
Reviewed-by: serb, ant
上级
b6396926
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
338 addition
and
89 deletion
+338
-89
src/share/classes/java/awt/WaitDispatchSupport.java
src/share/classes/java/awt/WaitDispatchSupport.java
+97
-89
test/java/awt/EventQueue/6980209/bug6980209.java
test/java/awt/EventQueue/6980209/bug6980209.java
+241
-0
未找到文件。
src/share/classes/java/awt/WaitDispatchSupport.java
浏览文件 @
f6adbf3a
...
@@ -65,6 +65,7 @@ class WaitDispatchSupport implements SecondaryLoop {
...
@@ -65,6 +65,7 @@ class WaitDispatchSupport implements SecondaryLoop {
private
AtomicBoolean
keepBlockingEDT
=
new
AtomicBoolean
(
false
);
private
AtomicBoolean
keepBlockingEDT
=
new
AtomicBoolean
(
false
);
private
AtomicBoolean
keepBlockingCT
=
new
AtomicBoolean
(
false
);
private
AtomicBoolean
keepBlockingCT
=
new
AtomicBoolean
(
false
);
private
AtomicBoolean
afterExit
=
new
AtomicBoolean
(
false
);
private
static
synchronized
void
initializeTimer
()
{
private
static
synchronized
void
initializeTimer
()
{
if
(
timer
==
null
)
{
if
(
timer
==
null
)
{
...
@@ -174,110 +175,116 @@ class WaitDispatchSupport implements SecondaryLoop {
...
@@ -174,110 +175,116 @@ class WaitDispatchSupport implements SecondaryLoop {
log
.
fine
(
"The secondary loop is already running, aborting"
);
log
.
fine
(
"The secondary loop is already running, aborting"
);
return
false
;
return
false
;
}
}
try
{
if
(
afterExit
.
get
())
{
log
.
fine
(
"Exit was called already, aborting"
);
return
false
;
}
final
Runnable
run
=
new
Runnable
()
{
final
Runnable
run
=
new
Runnable
()
{
public
void
run
()
{
public
void
run
()
{
log
.
fine
(
"Starting a new event pump"
);
log
.
fine
(
"Starting a new event pump"
);
if
(
filter
==
null
)
{
if
(
filter
==
null
)
{
dispatchThread
.
pumpEvents
(
condition
);
dispatchThread
.
pumpEvents
(
condition
);
}
else
{
}
else
{
dispatchThread
.
pumpEventsForFilter
(
condition
,
filter
);
dispatchThread
.
pumpEventsForFilter
(
condition
,
filter
);
}
}
}
}
};
};
// We have two mechanisms for blocking: if we're on the
// We have two mechanisms for blocking: if we're on the
// dispatch thread, start a new event pump; if we're
// dispatch thread, start a new event pump; if we're
// on any other thread, call wait() on the treelock
// on any other thread, call wait() on the treelock
Thread
currentThread
=
Thread
.
currentThread
();
Thread
currentThread
=
Thread
.
currentThread
();
if
(
currentThread
==
dispatchThread
)
{
if
(
currentThread
==
dispatchThread
)
{
if
(
log
.
isLoggable
(
PlatformLogger
.
Level
.
FINEST
))
{
log
.
finest
(
"On dispatch thread: "
+
dispatchThread
);
}
if
(
interval
!=
0
)
{
if
(
log
.
isLoggable
(
PlatformLogger
.
Level
.
FINEST
))
{
if
(
log
.
isLoggable
(
PlatformLogger
.
Level
.
FINEST
))
{
log
.
finest
(
"
scheduling the timer for "
+
interval
+
" ms"
);
log
.
finest
(
"
On dispatch thread: "
+
dispatchThread
);
}
}
timer
.
schedule
(
timerTask
=
new
TimerTask
()
{
if
(
interval
!=
0
)
{
@Override
if
(
log
.
isLoggable
(
PlatformLogger
.
Level
.
FINEST
))
{
public
void
run
()
{
log
.
finest
(
"scheduling the timer for "
+
interval
+
" ms"
);
if
(
keepBlockingEDT
.
compareAndSet
(
true
,
false
))
{
wakeupEDT
();
}
}
}
},
interval
);
timer
.
schedule
(
timerTask
=
new
TimerTask
()
{
}
@Override
// Dispose SequencedEvent we are dispatching on the the current
public
void
run
()
{
// AppContext, to prevent us from hang - see 4531693 for details
if
(
keepBlockingEDT
.
compareAndSet
(
true
,
false
))
{
SequencedEvent
currentSE
=
KeyboardFocusManager
.
wakeupEDT
();
getCurrentKeyboardFocusManager
().
getCurrentSequencedEvent
();
}
if
(
currentSE
!=
null
)
{
if
(
log
.
isLoggable
(
PlatformLogger
.
Level
.
FINE
))
{
log
.
fine
(
"Dispose current SequencedEvent: "
+
currentSE
);
}
currentSE
.
dispose
();
}
// In case the exit() method is called before starting
// new event pump it will post the waking event to EDT.
// The event will be handled after the the new event pump
// starts. Thus, the enter() method will not hang.
//
// Event pump should be privileged. See 6300270.
AccessController
.
doPrivileged
(
new
PrivilegedAction
<
Void
>()
{
public
Void
run
()
{
run
.
run
();
return
null
;
}
});
}
else
{
if
(
log
.
isLoggable
(
PlatformLogger
.
Level
.
FINEST
))
{
log
.
finest
(
"On non-dispatch thread: "
+
currentThread
);
}
synchronized
(
getTreeLock
())
{
if
(
filter
!=
null
)
{
dispatchThread
.
addEventFilter
(
filter
);
}
try
{
EventQueue
eq
=
dispatchThread
.
getEventQueue
();
eq
.
postEvent
(
new
PeerEvent
(
this
,
run
,
PeerEvent
.
PRIORITY_EVENT
));
keepBlockingCT
.
set
(
true
);
if
(
interval
>
0
)
{
long
currTime
=
System
.
currentTimeMillis
();
while
(
keepBlockingCT
.
get
()
&&
((
extCondition
!=
null
)
?
extCondition
.
evaluate
()
:
true
)
&&
(
currTime
+
interval
>
System
.
currentTimeMillis
()))
{
getTreeLock
().
wait
(
interval
);
}
}
else
{
while
(
keepBlockingCT
.
get
()
&&
((
extCondition
!=
null
)
?
extCondition
.
evaluate
()
:
true
))
{
getTreeLock
().
wait
();
}
}
}
},
interval
);
}
// Dispose SequencedEvent we are dispatching on the current
// AppContext, to prevent us from hang - see 4531693 for details
SequencedEvent
currentSE
=
KeyboardFocusManager
.
getCurrentKeyboardFocusManager
().
getCurrentSequencedEvent
();
if
(
currentSE
!=
null
)
{
if
(
log
.
isLoggable
(
PlatformLogger
.
Level
.
FINE
))
{
if
(
log
.
isLoggable
(
PlatformLogger
.
Level
.
FINE
))
{
log
.
fine
(
"
waitDone "
+
keepBlockingEDT
.
get
()
+
" "
+
keepBlockingCT
.
get
()
);
log
.
fine
(
"
Dispose current SequencedEvent: "
+
currentSE
);
}
}
}
catch
(
InterruptedException
e
)
{
currentSE
.
dispose
();
if
(
log
.
isLoggable
(
PlatformLogger
.
Level
.
FINE
))
{
}
log
.
fine
(
"Exception caught while waiting: "
+
e
);
// In case the exit() method is called before starting
// new event pump it will post the waking event to EDT.
// The event will be handled after the new event pump
// starts. Thus, the enter() method will not hang.
//
// Event pump should be privileged. See 6300270.
AccessController
.
doPrivileged
(
new
PrivilegedAction
<
Void
>()
{
public
Void
run
()
{
run
.
run
();
return
null
;
}
}
}
finally
{
});
}
else
{
if
(
log
.
isLoggable
(
PlatformLogger
.
Level
.
FINEST
))
{
log
.
finest
(
"On non-dispatch thread: "
+
currentThread
);
}
keepBlockingCT
.
set
(
true
);
synchronized
(
getTreeLock
())
{
if
(
afterExit
.
get
())
return
false
;
if
(
filter
!=
null
)
{
if
(
filter
!=
null
)
{
dispatchThread
.
removeEventFilter
(
filter
);
dispatchThread
.
addEventFilter
(
filter
);
}
try
{
EventQueue
eq
=
dispatchThread
.
getEventQueue
();
eq
.
postEvent
(
new
PeerEvent
(
this
,
run
,
PeerEvent
.
PRIORITY_EVENT
));
if
(
interval
>
0
)
{
long
currTime
=
System
.
currentTimeMillis
();
while
(
keepBlockingCT
.
get
()
&&
((
extCondition
!=
null
)
?
extCondition
.
evaluate
()
:
true
)
&&
(
currTime
+
interval
>
System
.
currentTimeMillis
()))
{
getTreeLock
().
wait
(
interval
);
}
}
else
{
while
(
keepBlockingCT
.
get
()
&&
((
extCondition
!=
null
)
?
extCondition
.
evaluate
()
:
true
))
{
getTreeLock
().
wait
();
}
}
if
(
log
.
isLoggable
(
PlatformLogger
.
Level
.
FINE
))
{
log
.
fine
(
"waitDone "
+
keepBlockingEDT
.
get
()
+
" "
+
keepBlockingCT
.
get
());
}
}
catch
(
InterruptedException
e
)
{
if
(
log
.
isLoggable
(
PlatformLogger
.
Level
.
FINE
))
{
log
.
fine
(
"Exception caught while waiting: "
+
e
);
}
}
finally
{
if
(
filter
!=
null
)
{
dispatchThread
.
removeEventFilter
(
filter
);
}
}
}
}
}
// If the waiting process has been stopped because of the
// time interval passed or an exception occurred, the state
// should be changed
keepBlockingEDT
.
set
(
false
);
keepBlockingCT
.
set
(
false
);
}
}
return
true
;
}
finally
{
keepBlockingEDT
.
set
(
false
);
keepBlockingCT
.
set
(
false
);
afterExit
.
set
(
false
);
}
}
return
true
;
}
}
/**
/**
...
@@ -288,7 +295,8 @@ class WaitDispatchSupport implements SecondaryLoop {
...
@@ -288,7 +295,8 @@ class WaitDispatchSupport implements SecondaryLoop {
log
.
fine
(
"exit(): blockingEDT="
+
keepBlockingEDT
.
get
()
+
log
.
fine
(
"exit(): blockingEDT="
+
keepBlockingEDT
.
get
()
+
", blockingCT="
+
keepBlockingCT
.
get
());
", blockingCT="
+
keepBlockingCT
.
get
());
}
}
if
(
keepBlockingEDT
.
compareAndSet
(
true
,
false
))
{
afterExit
.
set
(
true
);
if
(
keepBlockingEDT
.
getAndSet
(
false
))
{
wakeupEDT
();
wakeupEDT
();
return
true
;
return
true
;
}
}
...
...
test/java/awt/EventQueue/6980209/bug6980209.java
0 → 100644
浏览文件 @
f6adbf3a
/*
* Copyright (c) 2015, 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 6980209
@summary Make tracking SecondaryLoop.enter/exit methods easier
@author Semyon Sadetsky
*/
import
sun.util.logging.PlatformLogger
;
import
javax.swing.*
;
import
java.awt.*
;
import
java.awt.event.ActionEvent
;
import
java.awt.event.ActionListener
;
import
java.awt.event.KeyEvent
;
import
java.awt.event.KeyListener
;
public
class
bug6980209
implements
ActionListener
{
private
final
static
PlatformLogger
log
=
PlatformLogger
.
getLogger
(
"java.awt.event.WaitDispatchSupport"
);
public
static
final
int
ATTEMPTS
=
100
;
public
static
final
int
EVENTS
=
5
;
private
static
boolean
runInEDT
;
private
static
JFrame
frame
;
private
static
int
disorderCounter
=
0
;
private
static
Boolean
enterReturn
;
private
static
Boolean
exitReturn
;
private
static
int
dispatchedEvents
;
public
static
void
main
(
String
[]
args
)
throws
Exception
{
System
.
out
.
println
(
"PLEASE DO NOT TOUCH KEYBOARD AND MOUSE DURING THE TEST RUN!"
);
// log.setLevel(PlatformLogger.Level.FINE);
// log.setLevel(PlatformLogger.Level.FINEST);
try
{
SwingUtilities
.
invokeAndWait
(
new
Runnable
()
{
public
void
run
()
{
frame
=
new
JFrame
();
frame
.
setUndecorated
(
true
);
frame
.
setDefaultCloseOperation
(
JFrame
.
EXIT_ON_CLOSE
);
setup
(
frame
);
}
});
testExitBeforeEnter
();
System
.
out
.
println
(
"Run random test in EDT"
);
runInEDT
=
true
;
testRandomly
();
System
.
out
.
println
(
"Run random test in another thread"
);
runInEDT
=
false
;
testRandomly
();
System
.
out
.
println
(
"ok"
);
}
finally
{
SwingUtilities
.
invokeAndWait
(
new
Runnable
()
{
@Override
public
void
run
()
{
frame
.
dispose
();
}
});
}
}
private
static
void
testExitBeforeEnter
()
throws
Exception
{
final
SecondaryLoop
loop
=
Toolkit
.
getDefaultToolkit
().
getSystemEventQueue
()
.
createSecondaryLoop
();
loop
.
exit
();
Robot
robot
=
new
Robot
();
robot
.
mouseWheel
(
1
);
robot
.
waitForIdle
();
SwingUtilities
.
invokeAndWait
(
new
Runnable
()
{
@Override
public
void
run
()
{
if
(
loop
.
enter
())
{
throw
new
RuntimeException
(
"Wrong enter() return value"
);
}
}
});
}
private
static
void
testRandomly
()
throws
AWTException
{
disorderCounter
=
0
;
final
Robot
robot
=
new
Robot
();
for
(
int
i
=
0
;
i
<
ATTEMPTS
;
i
++)
{
enterReturn
=
null
;
exitReturn
=
null
;
dispatchedEvents
=
0
;
synchronized
(
bug6980209
.
class
)
{
try
{
for
(
int
j
=
0
;
j
<
EVENTS
;
j
++)
{
robot
.
keyPress
(
KeyEvent
.
VK_1
);
robot
.
keyRelease
(
KeyEvent
.
VK_1
);
}
// trigger the button action that starts secondary loop
robot
.
keyPress
(
KeyEvent
.
VK_SPACE
);
robot
.
keyRelease
(
KeyEvent
.
VK_SPACE
);
for
(
int
j
=
0
;
j
<
EVENTS
;
j
++)
{
robot
.
keyPress
(
KeyEvent
.
VK_1
);
robot
.
keyRelease
(
KeyEvent
.
VK_1
);
}
long
time
=
System
.
nanoTime
();
// wait for enter() returns
bug6980209
.
class
.
wait
(
1000
);
if
(
enterReturn
==
null
)
{
System
.
out
.
println
(
"wait time="
+
((
System
.
nanoTime
()
-
time
)
/
1
E9
)
+
" seconds"
);
throw
new
RuntimeException
(
"It seems the secondary loop will never end"
);
}
if
(!
enterReturn
)
disorderCounter
++;
robot
.
waitForIdle
();
if
(
dispatchedEvents
<
2
*
EVENTS
)
{
//check that all events are dispatched
throw
new
RuntimeException
(
"KeyEvent.VK_1 has been lost!"
);
}
}
catch
(
InterruptedException
e
)
{
throw
new
RuntimeException
(
"Interrupted!"
);
}
}
}
if
(
disorderCounter
==
0
)
{
System
.
out
.
println
(
"Zero disordered enter/exit caught. It is recommended to run scenario again"
);
}
else
{
System
.
out
.
println
(
"Disordered calls is "
+
disorderCounter
+
" from "
+
ATTEMPTS
);
}
}
private
static
void
setup
(
final
JFrame
frame
)
{
JButton
jButton
=
new
JButton
(
"Button"
);
frame
.
getContentPane
().
add
(
jButton
);
jButton
.
addActionListener
(
new
bug6980209
());
frame
.
pack
();
frame
.
setVisible
(
true
);
jButton
.
setFocusable
(
true
);
jButton
.
requestFocus
();
jButton
.
addKeyListener
(
new
KeyListener
()
{
@Override
public
void
keyTyped
(
KeyEvent
e
)
{
}
@Override
public
void
keyPressed
(
KeyEvent
e
)
{
if
(
e
.
getKeyChar
()
==
'1'
)
dispatchedEvents
++;
}
@Override
public
void
keyReleased
(
KeyEvent
e
)
{
if
(
e
.
getKeyChar
()
==
'1'
)
dispatchedEvents
++;
}
});
}
@Override
public
void
actionPerformed
(
ActionEvent
e
)
{
if
(
runInEDT
)
{
runSecondaryLoop
();
return
;
}
new
Thread
(
"Secondary loop run thread"
)
{
@Override
public
void
run
()
{
runSecondaryLoop
();
}
}.
start
();
}
private
static
void
runSecondaryLoop
()
{
log
.
fine
(
"\n---TEST START---"
);
final
SecondaryLoop
loop
=
Toolkit
.
getDefaultToolkit
().
getSystemEventQueue
()
.
createSecondaryLoop
();
final
Object
LOCK
=
new
Object
();
//lock to start simultaneously
Thread
exitThread
=
new
Thread
(
"Exit thread"
)
{
@Override
public
void
run
()
{
synchronized
(
LOCK
)
{
LOCK
.
notify
();
}
Thread
.
yield
();
exitReturn
=
loop
.
exit
();
log
.
fine
(
"exit() returns "
+
exitReturn
);
}
};
synchronized
(
LOCK
)
{
try
{
exitThread
.
start
();
LOCK
.
wait
();
}
catch
(
InterruptedException
e1
)
{
throw
new
RuntimeException
(
"What?"
);
}
}
enterReturn
=
loop
.
enter
();
log
.
fine
(
"enter() returns "
+
enterReturn
);
try
{
exitThread
.
join
();
}
catch
(
InterruptedException
e
)
{
throw
new
RuntimeException
(
"What?"
);
}
synchronized
(
bug6980209
.
class
)
{
bug6980209
.
class
.
notifyAll
();
}
log
.
fine
(
"\n---TEST END---"
);
}
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录