[Seasar-user:2416] Re: S2.2.7以降S2DBCPでデッドロックが発生することがある

Koichi Kobayashi koichik
2005年 7月 24日 (日) 02:46:30 JST


小林 (koichik) です.

Date:    Sat, 23 Jul 2005 13:51:31 +0900
From:    Hikaru Taniguchi <[E-MAIL ADDRESS DELETED]>
To:      seasar-users <[E-MAIL ADDRESS DELETED]>
Subject: [Seasar-user:2415] S2.2.7以降S2DBCPでデッドロックが発生することがある

> S2.2.7で S2DBCPのConnectionPoolImplの排他制御が変更されていますが、こ
> のバージョン以降、スレッド間でデッドロックが発生することがあるという問
> 題に遭遇したため、報告とお願いとしてメールさせていただきます。

詳細な調査ありがとうございました.
次のテストで再現することを確認しました.

Index: ConnectionPoolImplTest.java
===================================================================
RCS file: /cvsroot/seasar/seasar2/src/test/org/seasar/extension/dbcp/impl/ConnectionPoolImplTest.java,v
retrieving revision 1.5
diff -u -r1.5 ConnectionPoolImplTest.java
--- ConnectionPoolImplTest.java	29 Jun 2005 18:13:35 -0000	1.5
+++ ConnectionPoolImplTest.java	23 Jul 2005 17:43:50 -0000
@@ -214,6 +214,17 @@
         thread.interrupt();
     }
 
+	public void testExpired() throws Exception {
+        ((ConnectionPoolImpl) pool_).setTimeout(0);
+        synchronized (pool_) {
+	        ConnectionWrapper con = pool_.checkOut();
+	        con.close();
+	        Thread.sleep(200);
+	        con = pool_.checkOut();
+	        con.close();
+        }
+    }
+
 	protected void setUp() throws Exception {
         include(PATH);
     }


どのような対応をするか,慎重に検討したいと思いますので,
しばし時間をください.

暫定として,私の方で修正&確認を行ったパッチを添付します.
この対応が適切かどうか,影響範囲も含めて確認が不十分ですが,
もしお急ぎでしたらお試しください.


Index: TimeoutManager.java
===================================================================
RCS file: /cvsroot/seasar/seasar2/src/org/seasar/extension/timer/TimeoutManager.java,v
retrieving revision 1.1
diff -u -r1.1 TimeoutManager.java
--- TimeoutManager.java	13 Dec 2004 04:20:12 -0000	1.1
+++ TimeoutManager.java	23 Jul 2005 17:37:15 -0000
@@ -1,5 +1,9 @@
 package org.seasar.extension.timer;
 
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
 import org.seasar.framework.util.SLinkedList;
 
 public class TimeoutManager implements Runnable {
@@ -33,7 +37,8 @@
 	}
 
 	public void run() {
-		while (true) {
+	    List expiredTask = new ArrayList();
+		while (thread_ != null) {
 			try {
 				synchronized (timeoutTaskList_) {
 					while (timeoutTaskList_.isEmpty()) {
@@ -51,15 +56,21 @@
 							continue;
 						}
 						if (task.isExpired()) {
-							task.expired();
-							if (task.isPermanent()) {
-								task.restart();
-							} else {
+							expiredTask.add(task);
+							if (!task.isPermanent()) {
 								e.remove();
 							}
 						}
 					}
 				}
+				for (Iterator it = expiredTask.iterator(); it.hasNext(); ) {
+					TimeoutTask task = (TimeoutTask) it.next();
+					task.expired();
+					if (task.isPermanent()) {
+						task.restart();
+					}
+				}
+				expiredTask.clear();
 				Thread.sleep(1000);
 			} catch (InterruptedException ignore) {
 			}


-- 
<signature>
    <name>Koichi Kobayashi</name>
    <e-mail>[E-MAIL ADDRESS DELETED]</e-mail>
</signature>




Seasar-user メーリングリストの案内