Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
d001e0ef
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看板
提交
d001e0ef
编写于
9月 22, 2008
作者:
S
sjiang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
6697180: JMX query results in java.io.IOException: Illegal state - also a deadlock can also be seen
Reviewed-by: emcmanus
上级
07a943c3
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
285 addition
and
30 deletion
+285
-30
src/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java
...ses/com/sun/jmx/remote/internal/ClientNotifForwarder.java
+29
-30
test/javax/management/remote/mandatory/connection/MultiThreadDeadLockTest.java
.../remote/mandatory/connection/MultiThreadDeadLockTest.java
+256
-0
未找到文件。
src/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java
浏览文件 @
d001e0ef
...
...
@@ -290,28 +290,6 @@ public abstract class ClientNotifForwarder {
infoList
.
clear
();
if
(
currentFetchThread
==
Thread
.
currentThread
())
{
/* we do not need to stop the fetching thread, because this thread is
used to do restarting and it will not be used to do fetching during
the re-registering the listeners.*/
return
tmp
;
}
while
(
state
==
STARTING
)
{
try
{
wait
();
}
catch
(
InterruptedException
ire
)
{
IOException
ioe
=
new
IOException
(
ire
.
toString
());
EnvHelp
.
initCause
(
ioe
,
ire
);
throw
ioe
;
}
}
if
(
state
==
STARTED
)
{
setState
(
STOPPING
);
}
return
tmp
;
}
...
...
@@ -353,8 +331,9 @@ public abstract class ClientNotifForwarder {
beingReconnected
=
false
;
notifyAll
();
if
(
currentFetchThread
==
Thread
.
currentThread
())
{
// no need to init, simply get the id
if
(
currentFetchThread
==
Thread
.
currentThread
()
||
state
==
STARTING
||
state
==
STARTED
)
{
// doing or waiting reconnection
// only update mbeanRemovedNotifID
try
{
mbeanRemovedNotifID
=
addListenerForMBeanRemovedNotif
();
}
catch
(
Exception
e
)
{
...
...
@@ -366,12 +345,23 @@ public abstract class ClientNotifForwarder {
logger
.
trace
(
"init"
,
msg
,
e
);
}
}
}
else
if
(
listenerInfos
.
length
>
0
)
{
// old listeners re-registered
init
(
true
);
}
else
if
(
infoList
.
size
()
>
0
)
{
// but new listeners registered during reconnection
init
(
false
);
}
}
else
{
while
(
state
==
STOPPING
)
{
try
{
wait
();
}
catch
(
InterruptedException
ire
)
{
IOException
ioe
=
new
IOException
(
ire
.
toString
());
EnvHelp
.
initCause
(
ioe
,
ire
);
throw
ioe
;
}
}
if
(
listenerInfos
.
length
>
0
)
{
// old listeners are re-added
init
(
true
);
// not update clientSequenceNumber
}
else
if
(
infoList
.
size
()
>
0
)
{
// only new listeners added during reconnection
init
(
false
);
// need update clientSequenceNumber
}
}
}
public
synchronized
void
terminate
()
{
...
...
@@ -486,6 +476,15 @@ public abstract class ClientNotifForwarder {
if
(
nr
==
null
||
shouldStop
())
{
// tell that the thread is REALLY stopped
setState
(
STOPPED
);
try
{
removeListenerForMBeanRemovedNotif
(
mbeanRemovedNotifID
);
}
catch
(
Exception
e
)
{
if
(
logger
.
traceOn
())
{
logger
.
trace
(
"NotifFetcher-run"
,
"removeListenerForMBeanRemovedNotif"
,
e
);
}
}
}
else
{
executor
.
execute
(
this
);
}
...
...
test/javax/management/remote/mandatory/connection/MultiThreadDeadLockTest.java
0 → 100644
浏览文件 @
d001e0ef
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
import
java.io.IOException
;
import
java.io.Serializable
;
import
java.net.Socket
;
import
java.rmi.server.RMIClientSocketFactory
;
import
java.util.HashMap
;
import
javax.management.MBeanServer
;
import
javax.management.MBeanServerFactory
;
import
javax.management.Notification
;
import
javax.management.NotificationBroadcasterSupport
;
import
javax.management.NotificationListener
;
import
javax.management.ObjectName
;
import
javax.management.remote.JMXConnector
;
import
javax.management.remote.JMXConnectorFactory
;
import
javax.management.remote.JMXConnectorServer
;
import
javax.management.remote.JMXConnectorServerFactory
;
import
javax.management.remote.JMXServiceURL
;
import
javax.management.remote.rmi.RMIConnectorServer
;
/*
* @test
* @bug 6697180
* @summary test on a client notification deadlock.
* @author Shanliang JIANG
* @run clean MultiThreadDeadLockTest
* @run build MultiThreadDeadLockTest
* @run main MultiThreadDeadLockTest
*/
public
class
MultiThreadDeadLockTest
{
private
static
long
serverTimeout
=
500L
;
public
static
void
main
(
String
[]
args
)
throws
Exception
{
print
(
"Create the MBean server"
);
MBeanServer
mbs
=
MBeanServerFactory
.
createMBeanServer
();
print
(
"Initialize environment map"
);
HashMap
env
=
new
HashMap
();
print
(
"Specify a client socket factory to control socket creation."
);
env
.
put
(
RMIConnectorServer
.
RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE
,
clientFactory
);
print
(
"Specify a server idle timeout to make a server close an idle connection."
);
env
.
put
(
"jmx.remote.x.server.connection.timeout"
,
serverTimeout
);
print
(
"Disable client heartbeat."
);
env
.
put
(
"jmx.remote.x.client.connection.check.period"
,
0
);
env
.
put
(
"jmx.remote.x.notification.fetch.timeout"
,
serverTimeout
);
print
(
"Create an RMI server"
);
JMXServiceURL
url
=
new
JMXServiceURL
(
"rmi"
,
null
,
0
);
JMXConnectorServer
server
=
JMXConnectorServerFactory
.
newJMXConnectorServer
(
url
,
env
,
mbs
);
server
.
start
();
url
=
server
.
getAddress
();
print
(
"Create jmx client on "
+
url
);
StateMachine
.
setState
(
CREATE_SOCKET
);
// allow to create client socket
client
=
JMXConnectorFactory
.
connect
(
url
,
env
);
Thread
.
sleep
(
100
);
totoName
=
new
ObjectName
(
"default:name=toto"
);
mbs
.
registerMBean
(
toto
,
totoName
);
print
(
"Register the mbean: "
+
totoName
);
print
(
"Add listener to toto MBean"
);
client
.
getMBeanServerConnection
().
addNotificationListener
(
totoName
,
myListener
,
null
,
null
);
Thread
.
sleep
(
10
);
print
(
"send notif, listener will block the fetcher"
);
toto
.
sendNotif
();
Thread
.
sleep
(
100
);
StateMachine
.
setState
(
NO_OP
);
print
(
"Sleep 3 times of server idle timeout: "
+
serverTimeout
+
", the sever should close the idle connection."
);
Thread
.
sleep
(
serverTimeout
*
3
);
print
(
"start the user thread to call mbean method, it will get IOexception"
+
" and start the reconnection, the socket factory will block the"
+
" socket creation."
);
UserThread
ut
=
new
UserThread
();
ut
.
start
();
Thread
.
sleep
(
10
);
print
(
"Free the listener, the fetcher will get IO and makes "
+
"a deadlock if the bug is not fixed."
);
StateMachine
.
setState
(
FREE_LISTENER
);
Thread
.
sleep
(
100
);
print
(
"Allow to create new socket for the reconnection"
);
StateMachine
.
setState
(
CREATE_SOCKET
);
print
(
"Check whether the user thread gets free to call the mbean."
);
if
(!
ut
.
waitDone
(
5000
))
{
throw
new
RuntimeException
(
"Possible deadlock!"
);
}
print
(
"Remove the listener."
);
client
.
getMBeanServerConnection
().
removeNotificationListener
(
totoName
,
myListener
,
null
,
null
);
Thread
.
sleep
(
serverTimeout
*
3
);
print
(
"\nWell passed, bye!"
);
client
.
close
();
Thread
.
sleep
(
10
);
server
.
stop
();
}
private
static
ObjectName
totoName
=
null
;
private
static
JMXConnector
client
;
public
static
class
UserThread
extends
Thread
{
public
UserThread
()
{
setDaemon
(
true
);
}
public
void
run
()
{
try
{
client
.
getMBeanServerConnection
().
invoke
(
totoName
,
"allowReturn"
,
null
,
null
);
}
catch
(
Exception
e
)
{
throw
new
Error
(
e
);
}
synchronized
(
UserThread
.
class
)
{
done
=
true
;
UserThread
.
class
.
notify
();
}
}
public
boolean
waitDone
(
long
timeout
)
{
synchronized
(
UserThread
.
class
)
{
if
(!
done
)
{
try
{
UserThread
.
class
.
wait
(
timeout
);
}
catch
(
Exception
e
)
{
throw
new
Error
(
e
);
}
}
}
return
done
;
}
private
boolean
done
=
false
;
}
public
static
interface
TotoMBean
{
public
void
allowReturn
();
}
public
static
class
Toto
extends
NotificationBroadcasterSupport
implements
TotoMBean
{
public
void
allowReturn
()
{
enter
(
"allowReturn"
);
leave
(
"allowReturn"
);
}
public
void
sendNotif
()
{
enter
(
"sendNotif"
);
sendNotification
(
new
Notification
(
"Toto"
,
totoName
,
0
));
leave
(
"sendNotif"
);
}
}
private
static
Toto
toto
=
new
Toto
();
public
static
NotificationListener
myListener
=
new
NotificationListener
()
{
public
void
handleNotification
(
Notification
notification
,
Object
handback
)
{
enter
(
"handleNotification"
);
StateMachine
.
waitState
(
FREE_LISTENER
);
leave
(
"handleNotification"
);
}
};
public
static
class
RMIClientFactory
implements
RMIClientSocketFactory
,
Serializable
{
public
Socket
createSocket
(
String
host
,
int
port
)
throws
IOException
{
enter
(
"createSocket"
);
//print("Calling createSocket(" + host + " " + port + ")");
StateMachine
.
waitState
(
CREATE_SOCKET
);
Socket
s
=
new
Socket
(
host
,
port
);
leave
(
"createSocket"
);
return
s
;
}
}
private
static
RMIClientFactory
clientFactory
=
new
RMIClientFactory
();
private
static
int
CREATE_SOCKET
=
1
;
private
static
int
FREE_LISTENER
=
3
;
private
static
int
NO_OP
=
0
;
public
static
class
StateMachine
{
private
static
int
state
=
NO_OP
;
private
static
int
[]
lock
=
new
int
[
0
];
public
static
void
waitState
(
int
s
)
{
synchronized
(
lock
)
{
while
(
state
!=
s
)
{
try
{
lock
.
wait
();
}
catch
(
InterruptedException
ire
)
{
// should not
throw
new
Error
(
ire
);
}
}
}
}
public
static
int
getState
()
{
synchronized
(
lock
)
{
return
state
;
}
}
public
static
void
setState
(
int
s
)
{
synchronized
(
lock
)
{
state
=
s
;
lock
.
notifyAll
();
}
}
}
private
static
void
print
(
String
m
)
{
System
.
out
.
println
(
m
);
}
private
static
void
enter
(
String
m
)
{
System
.
out
.
println
(
"\n---Enter the method "
+
m
);
}
private
static
void
leave
(
String
m
)
{
System
.
out
.
println
(
"===Leave the method: "
+
m
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录