<!-- 
RSS generated by JIRA (4.3.1#615-r147022) at Tue May 21 17:10:45 CEST 2013

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary add field=key&field=summary to the URL of your request.
For example:
http://www.quickfixj.org/jira/si/jira.issueviews:issue-xml/QFJ-645/QFJ-645.xml?field=key&field=summary
-->
<rss version="0.92" >
<channel>
    <title>QuickFIX/J Jira</title>
    <link>http://www.quickfixj.org/jira</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-uk</language>    <build-info>
        <version>4.3.1</version>
        <build-number>615</build-number>
        <build-date>25-03-2011</build-date>
        <edition>enterprise</edition>
    </build-info>

<item>
            <title>[QFJ-645] Deadlock between message sending and reset due to message reception on Session and senderMsgSeqNumLock</title>
                <link>http://www.quickfixj.org/jira/browse/QFJ-645</link>
                <project id="10000" key="QFJ">QuickFIX/J</project>
                        <description>Deadlock arises between the following threads:&lt;br/&gt;
&amp;nbsp;&lt;br/&gt;
Thread1:&lt;br/&gt;
&amp;quot;GatewayStateTimer&amp;quot; daemon prio=3 tid=0x04d65388 nid=0x2bef waiting for monitor entry [0x790ff000..0x790ff9f0]&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at quickfix.SessionState.isLogonSent(SessionState.java:162)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- waiting to lock &amp;lt;0x9d12c020&amp;gt; (a quickfix.Session)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at quickfix.Session.sentLogon(Session.java:690)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at quickfix.Session.isLoggedOn(Session.java:731)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at quickfix.Session.sendRaw(Session.java:2151)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at quickfix.Session.send(Session.java:2213)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at quickfix.Session.sendToTarget(Session.java:590)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at com.greatBank.application.fix.Engine.sendMessage(Engine.java:54)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at com.greatBank.application.fix.Engine.pingFIX(Engine.java:191)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at com.greatBank.application.fix.Engine.access$0(Engine.java:186)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at com.greatBank.application.fix.Engine$PingTimerTask.run(Engine.java:176)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at java.util.TimerThread.mainLoop(Timer.java:512)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at java.util.TimerThread.run(Timer.java:462)&lt;br/&gt;
&amp;nbsp;&lt;br/&gt;
-&amp;gt; Thread1 is sending a message: it first acquires the lock senderMsgSeqNumLock and then tries to acquire a lock on the session instance&lt;br/&gt;
&amp;nbsp;&lt;br/&gt;
&amp;nbsp;&lt;br/&gt;
Thread2:&lt;br/&gt;
&amp;quot;QF/J Session dispatcher: FIX.4.2:SENDER1-&amp;gt;TARGET1&amp;quot; daemon prio=3 tid=0x014e5ac8 nid=0x2bfc waiting on condition [0x794ff000..0x794ff970]&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at sun.misc.Unsafe.park(Native Method)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at java.util.concurrent.locks.LockSupport.park(LockSupport.java:118)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:716)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:746)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1076)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:184)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:256)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at quickfix.SessionState.lockSenderMsgSeqNum(SessionState.java:322)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at quickfix.Session.sendRaw(Session.java:2117)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at quickfix.Session.generateLogout(Session.java:1293)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at quickfix.Session.generateLogout(Session.java:1284)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at quickfix.Session.reset(Session.java:756)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;- locked &amp;lt;0x9d12c020&amp;gt; (a quickfix.Session)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at quickfix.Session.next(Session.java:836)&lt;br/&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at quickfix.mina.ThreadPerSessionEventHandlingStrategy$MessageDispatchingThread.run(ThreadPerSessionEventHandlingStrategy.java:119)&lt;br/&gt;
&amp;nbsp;&lt;br/&gt;
-&amp;gt; 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.&lt;br/&gt;
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</description>
                <environment></environment>
            <key id="10908">QFJ-645</key>
            <summary>Deadlock between message sending and reset due to message reception on Session and senderMsgSeqNumLock</summary>
                <type id="1" iconUrl="http://www.quickfixj.org/jira/images/icons/bug.gif">Bug</type>
                                <priority id="2" iconUrl="http://www.quickfixj.org/jira/images/icons/priority_critical.gif">Critical</priority>
                    <status id="5" iconUrl="http://www.quickfixj.org/jira/images/icons/status_resolved.gif">Resolved</status>
                    <resolution id="1">Fixed</resolution>
                                <assignee username="chrjohn">Christoph John</assignee>
                                <reporter username="msperisen">marc sperisen</reporter>
                        <labels>
                        <label>deadlock</label>
                    </labels>
                <created>Thu, 27 Oct 2011 11:42:47 +0200</created>
                <updated>Wed, 10 Oct 2012 18:46:30 +0200</updated>
                    <resolved>Tue, 31 Jul 2012 09:36:24 +0200</resolved>
                            <version>1.5.0</version>
                <version>1.5.1</version>
                                <fixVersion>1.5.3</fixVersion>
                                <component>Engine</component>
                        <due></due>
                    <votes>2</votes>
                        <comments>
                    <comment id="11593" author="peteclarkez" created="Thu, 12 Jan 2012 23:33:01 +0100"  >&lt;p&gt;Hi &lt;br/&gt;
I&apos;ve also seen this issue with our application. &lt;/p&gt;

&lt;p&gt;My solution to this was to remove the synchronized keyword from the Session.reset function.&lt;/p&gt;

&lt;p&gt;I&apos;ve also attached a unit test we have to check for the issue.&lt;/p&gt;

&lt;p&gt;Pete&lt;/p&gt;</comment>
                    <comment id="11596" author="pantolomin" created="Tue, 17 Jan 2012 12:25:08 +0100"  >&lt;p&gt;had this one too, but I haven&apos;t changed the library so I synchronized on the &quot;Session&quot; (=&amp;gt; so locks are taken in the same order).&lt;/p&gt;</comment>
                    <comment id="11605" author="pantolomin" created="Thu, 2 Feb 2012 13:08:31 +0100"  >&lt;p&gt;Erratum on the preceding comment.&lt;br/&gt;
Synchronizing &quot;send&quot; on the session created a huge performance hit when having heavy load.&lt;/p&gt;

&lt;p&gt;Peter&apos;s was solution was the best one from the beggining and my workarround is not that good ;o)&lt;/p&gt;

&lt;p&gt;I just put the code I used for the &quot;reset&quot; method :&lt;/p&gt;
&lt;div class=&quot;code panel&quot; style=&quot;border-style: solid;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeHeader panelHeader&quot; style=&quot;border-bottom-width: 1px;border-bottom-style: solid;&quot;&gt;&lt;b&gt;quickfix.Session&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;&lt;span class=&quot;code-keyword&quot;&gt;public&lt;/span&gt; void reset() &lt;span class=&quot;code-keyword&quot;&gt;throws&lt;/span&gt; IOException {
  &lt;span class=&quot;code-keyword&quot;&gt;if&lt;/span&gt; (!resetting.compareAndSet(&lt;span class=&quot;code-keyword&quot;&gt;false&lt;/span&gt;, &lt;span class=&quot;code-keyword&quot;&gt;true&lt;/span&gt;)) {
    &lt;span class=&quot;code-keyword&quot;&gt;return&lt;/span&gt;;
  }
  &lt;span class=&quot;code-keyword&quot;&gt;try&lt;/span&gt; {
    &lt;span class=&quot;code-keyword&quot;&gt;if&lt;/span&gt; (hasResponder()) {
      &lt;span class=&quot;code-keyword&quot;&gt;if&lt;/span&gt; (application != &lt;span class=&quot;code-keyword&quot;&gt;null&lt;/span&gt; &amp;amp;&amp;amp; application &lt;span class=&quot;code-keyword&quot;&gt;instanceof&lt;/span&gt; ApplicationExtended) {
        ((ApplicationExtended) application).onBeforeSessionReset(sessionID);
      }
      generateLogout();
      disconnect(&lt;span class=&quot;code-quote&quot;&gt;&quot;Session reset&quot;&lt;/span&gt;, &lt;span class=&quot;code-keyword&quot;&gt;false&lt;/span&gt;);
    }
    resetState();
  }
  &lt;span class=&quot;code-keyword&quot;&gt;finally&lt;/span&gt; {
    resetting.set(&lt;span class=&quot;code-keyword&quot;&gt;false&lt;/span&gt;);
  }
}&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;</comment>
                    <comment id="11677" author="chrjohn" created="Tue, 31 Jul 2012 09:38:47 +0200"  >&lt;p&gt;Peter and John,&lt;br/&gt;
thanks for your contributions. I have changed the reset() method accordingly and have added the UnitTest (I changed it slightly to work with a pausable Executor and made it detect the deadlock programmatically).&lt;/p&gt;</comment>
                </comments>
                <issuelinks>
                        <issuelinktype id="10000">
                <name>Duplicate</name>
                                                <inwardlinks description="is duplicated by">
                            <issuelink>
            <issuekey id="10971">QFJ-700</issuekey>
        </issuelink>
                    </inwardlinks>
                            </issuelinktype>
                    </issuelinks>
                <attachments>
                    <attachment id="10372" name="SessionResetTest.java" size="4342" author="peteclarkez" created="Thu, 12 Jan 2012 23:33:01 +0100" />
                </attachments>
            <subtasks>
        </subtasks>
        </item>
</channel>
</rss>