Details
Description
Deadlock arises between the following threads:
Thread1:
"GatewayStateTimer" daemon prio=3 tid=0x04d65388 nid=0x2bef waiting for monitor entry [0x790ff000..0x790ff9f0]
at quickfix.SessionState.isLogonSent(SessionState.java:162)
- waiting to lock <0x9d12c020> (a quickfix.Session)
at quickfix.Session.sentLogon(Session.java:690)
at quickfix.Session.isLoggedOn(Session.java:731)
at quickfix.Session.sendRaw(Session.java:2151)
at quickfix.Session.send(Session.java:2213)
at quickfix.Session.sendToTarget(Session.java:590)
at com.greatBank.application.fix.Engine.sendMessage(Engine.java:54)
at com.greatBank.application.fix.Engine.pingFIX(Engine.java:191)
at com.greatBank.application.fix.Engine.access$0(Engine.java:186)
at com.greatBank.application.fix.Engine$PingTimerTask.run(Engine.java:176)
at java.util.TimerThread.mainLoop(Timer.java:512)
at java.util.TimerThread.run(Timer.java:462)
-> Thread1 is sending a message: it first acquires the lock senderMsgSeqNumLock and then tries to acquire a lock on the session instance
Thread2:
"QF/J Session dispatcher: FIX.4.2:SENDER1->TARGET1" daemon prio=3 tid=0x014e5ac8 nid=0x2bfc waiting on condition [0x794ff000..0x794ff970]
at sun.misc.Unsafe.park(Native Method)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:118)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:716)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:746)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1076)
at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:184)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:256)
at quickfix.SessionState.lockSenderMsgSeqNum(SessionState.java:322)
at quickfix.Session.sendRaw(Session.java:2117)
at quickfix.Session.generateLogout(Session.java:1293)
at quickfix.Session.generateLogout(Session.java:1284)
at quickfix.Session.reset(Session.java:756)
- locked <0x9d12c020> (a quickfix.Session)
at quickfix.Session.next(Session.java:836)
at quickfix.mina.ThreadPerSessionEventHandlingStrategy$MessageDispatchingThread.run(ThreadPerSessionEventHandlingStrategy.java:119)
-> Thread2: while processing an incoming message, the engine notices that it is in a new session time interval (StartTime/EndTime) and therefore a MsqSeqNum reset is started.
The reset method acquires a lock on the session and, when generating a Logout, tries to acquire the lock senderMsgSeqNumLock, and then deadlocks with Thread1
Thread1:
"GatewayStateTimer" daemon prio=3 tid=0x04d65388 nid=0x2bef waiting for monitor entry [0x790ff000..0x790ff9f0]
at quickfix.SessionState.isLogonSent(SessionState.java:162)
- waiting to lock <0x9d12c020> (a quickfix.Session)
at quickfix.Session.sentLogon(Session.java:690)
at quickfix.Session.isLoggedOn(Session.java:731)
at quickfix.Session.sendRaw(Session.java:2151)
at quickfix.Session.send(Session.java:2213)
at quickfix.Session.sendToTarget(Session.java:590)
at com.greatBank.application.fix.Engine.sendMessage(Engine.java:54)
at com.greatBank.application.fix.Engine.pingFIX(Engine.java:191)
at com.greatBank.application.fix.Engine.access$0(Engine.java:186)
at com.greatBank.application.fix.Engine$PingTimerTask.run(Engine.java:176)
at java.util.TimerThread.mainLoop(Timer.java:512)
at java.util.TimerThread.run(Timer.java:462)
-> Thread1 is sending a message: it first acquires the lock senderMsgSeqNumLock and then tries to acquire a lock on the session instance
Thread2:
"QF/J Session dispatcher: FIX.4.2:SENDER1->TARGET1" daemon prio=3 tid=0x014e5ac8 nid=0x2bfc waiting on condition [0x794ff000..0x794ff970]
at sun.misc.Unsafe.park(Native Method)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:118)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:716)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:746)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1076)
at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:184)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:256)
at quickfix.SessionState.lockSenderMsgSeqNum(SessionState.java:322)
at quickfix.Session.sendRaw(Session.java:2117)
at quickfix.Session.generateLogout(Session.java:1293)
at quickfix.Session.generateLogout(Session.java:1284)
at quickfix.Session.reset(Session.java:756)
- locked <0x9d12c020> (a quickfix.Session)
at quickfix.Session.next(Session.java:836)
at quickfix.mina.ThreadPerSessionEventHandlingStrategy$MessageDispatchingThread.run(ThreadPerSessionEventHandlingStrategy.java:119)
-> Thread2: while processing an incoming message, the engine notices that it is in a new session time interval (StartTime/EndTime) and therefore a MsqSeqNum reset is started.
The reset method acquires a lock on the session and, when generating a Logout, tries to acquire the lock senderMsgSeqNumLock, and then deadlocks with Thread1
Attachments
Issue Links
| This issue is duplicated by: | ||||
| QFJ-700 | QFJ Timer and QFJ message processor try to execute generateLogout() at the same time, resulting in QFJ Timer to stop |
|
|
|
Activity
| Repository | Revision | Date | User | Message |
| QuickFixJ Repository | #1072 | Mon Jul 30 09:33:02 CEST 2012 | chrjohn | - Removed synchronization from reset() method and introduced AtomicBoolean. - Added SessionResetTest which checks if a deadlock occurred when concurrently sending messages and calling Session.reset(). |
| Files Changed | ||||
|
MODIFY
/trunk/core/src/main/java/quickfix/Session.java
ADD /trunk/core/src/test/java/quickfix/SessionResetTest.java |
| Repository | Revision | Date | User | Message |
| QuickFixJ Repository | #1111 | Thu Dec 06 12:43:19 CET 2012 | chrjohn | - Disabled SessionResetTest since it breaks JDK1.4/1.5 compatibility. (uses ManagementFactory.getThreadMXBean().findDeadlockedThreads()) |
| Files Changed | ||||
|
MODIFY
/trunk/core/src/test/java/quickfix/SessionResetTest.java
|