Changeset: c205dbf4bd36 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=c205dbf4bd36
Added Files:
        java/tests/Test_Csendthread.java
Modified Files:
        java/src/nl/cwi/monetdb/jdbc/MonetConnection.java
        java/tests/build.xml
Branch: Oct2012
Log Message:

SendThread: shutdown thread on Connection close

Wouter Alink reported a large number of "hanging" threads after having
used many Connections that had to send large queries (hence SendThread
started).  These were left-over SendThreads that were never cleaned up.

Cleanup SendThreads as part of the MonetConnection.close() method.  This
patch is inspired by the work of Wouter.


diffs (155 lines):

diff --git a/java/src/nl/cwi/monetdb/jdbc/MonetConnection.java 
b/java/src/nl/cwi/monetdb/jdbc/MonetConnection.java
--- a/java/src/nl/cwi/monetdb/jdbc/MonetConnection.java
+++ b/java/src/nl/cwi/monetdb/jdbc/MonetConnection.java
@@ -333,6 +333,11 @@ public class MonetConnection extends Mon
                        }
                        // close the socket
                        server.close();
+                       // close active SendThread if any
+                       if (sendThread != null) {
+                               sendThread.shutdown();
+                               sendThread = null;
+                       }
                        // report ourselves as closed
                        closed = true;
                }
@@ -2561,6 +2566,8 @@ public class MonetConnection extends Mon
                private final static int WAIT = 0;
                /** The state QUERY represents this thread to be executing a 
query */
                private final static int QUERY = 1;
+               /** The state SHUTDOWN is the final state that ends this thread 
*/
+               private final static int SHUTDOWN = -1;
 
                private String[] templ;
                private String query;
@@ -2596,6 +2603,8 @@ public class MonetConnection extends Mon
                                                        // woken up, eh?
                                                }
                                        }
+                                       if (state == SHUTDOWN)
+                                               break;
 
                                        // state is QUERY here
                                        try {
@@ -2630,7 +2639,7 @@ public class MonetConnection extends Mon
                        sendLock.lock();
                        try {
                                if (state != WAIT) 
-                                       throw new SQLException("SendThread 
already in use!", "M0M03");
+                                       throw new SQLException("SendThread 
already in use or shutting down!", "M0M03");
 
                                this.templ = templ;
                                this.query = query;
@@ -2652,18 +2661,30 @@ public class MonetConnection extends Mon
                        sendLock.lock();
                        try {
                                // make sure the thread is in WAIT state, not 
QUERY
-                               while (state != WAIT) {
+                               while (state == QUERY) {
                                        try {
                                                waiting.await();
                                        } catch (InterruptedException e) {
                                                // just try again
                                        }
                                }
+                               if (state == SHUTDOWN)
+                                       error = "SendThread is shutting down";
                        } finally {
                                sendLock.unlock();
                        }
                        return error;
                }
+
+               /**
+                * Requests this SendThread to stop. 
+                */
+               public void shutdown() {
+                       sendLock.lock();
+                       state = SHUTDOWN;
+                       sendLock.unlock();
+                       this.interrupt();  // break any wait conditions
+               }
        }
        // }}}
 }
diff --git a/java/tests/Test_Csendthread.java b/java/tests/Test_Csendthread.java
new file mode 100644
--- /dev/null
+++ b/java/tests/Test_Csendthread.java
@@ -0,0 +1,51 @@
+/*
+ * The contents of this file are subject to the MonetDB Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.monetdb.org/Legal/MonetDBLicense
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * The Original Code is the MonetDB Database System.
+ *
+ * The Initial Developer of the Original Code is CWI.
+ * Portions created by CWI are Copyright (C) 1997-July 2008 CWI.
+ * Copyright August 2008-2012 MonetDB B.V.
+ * All Rights Reserved.
+ */
+
+import java.sql.*;
+
+public class Test_Csendthread {
+       public static void main(String[] args) throws Exception {
+               Class.forName("nl.cwi.monetdb.jdbc.MonetDriver");
+
+               System.out.println("0. active threads: " + 
Thread.activeCount());
+
+               StringBuilder sb = new StringBuilder();
+               sb.append("SELECT 1");
+               for (int i = 0; i < 256; i++) {
+                       sb.append("-- ADDING DUMMY TEXT AS COMMENT TO MAKE THE 
QUERY VERY VERY VERY VERY LONG\n");
+               }
+               sb.append(";\n");
+               String longQuery = sb.toString();
+
+               for (int i = 0; i < 10; i++) {
+                       for (int j = 0; j < 10; j++) {
+                               Connection conn = 
DriverManager.getConnection(args[0]);
+                               try {
+                                       Statement st = conn.createStatement();
+                                       st.execute(longQuery);
+                                       st.close();
+                               } finally {
+                                       conn.close();
+                               }
+                       }
+                       System.out.println("1. active threads: " + 
Thread.activeCount());
+               }
+               System.out.println("2. active threads: " + 
Thread.activeCount());
+       }
+}
diff --git a/java/tests/build.xml b/java/tests/build.xml
--- a/java/tests/build.xml
+++ b/java/tests/build.xml
@@ -108,6 +108,8 @@ All Rights Reserved.
     <antcall target="Test_Creplysize" />
     <antcall target="Test_Csavepoints" />
     <antcall target="Test_Ctransaction" />
+    <antcall target="Test_Creplysize" />
+    <antcall target="Test_Csendthread" />
     <antcall target="Test_Dobjects" />
     <antcall target="Test_PSgeneratedkeys" />
     <antcall target="Test_PSlargeresponse" />
@@ -184,6 +186,12 @@ All Rights Reserved.
     </antcall>
   </target>
 
+  <target name="Test_Csendthread">
+    <antcall target="test_class">
+      <param name="test.class" value="Test_Csendthread" />
+    </antcall>
+  </target>
+
   <target name="Test_Dobjects">
     <antcall target="test_class">
       <param name="test.class" value="Test_Dobjects" />
_______________________________________________
checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to