Changeset: 8fc3225c9198 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=8fc3225c9198
Modified Files:
        
Branch: default
Log Message:

Merged from Dec2011


diffs (225 lines):

diff --git a/java/ChangeLog.Dec2011 b/java/ChangeLog.Dec2011
--- a/java/ChangeLog.Dec2011
+++ b/java/ChangeLog.Dec2011
@@ -1,3 +1,7 @@
 # ChangeLog file for java
 # This file is updated with Maddlog
 
+* Tue Feb 14 2012 Fabian Groffen <[email protected]>
+- Resolved a bug where JDBC and Control connections could terminate
+  abruptly with 'Connection closed' messages
+
diff --git a/java/src/nl/cwi/monetdb/client/JMonetDB.java 
b/java/src/nl/cwi/monetdb/client/JMonetDB.java
--- a/java/src/nl/cwi/monetdb/client/JMonetDB.java
+++ b/java/src/nl/cwi/monetdb/client/JMonetDB.java
@@ -59,12 +59,9 @@ public class JMonetDB {
                                "Use the given hash algorithm during challenge 
response.  " +
                                "Supported algorithm names: SHA256, SHA1, 
MD5.");
                // arguments which can have zero or one argument(s)
-               copts.addOption(null, "Xdebug", CmdLineOpts.CAR_ZERO_ONE, null,
+               copts.addOption(null, "Xdebug", CmdLineOpts.CAR_ONE, null,
                                "Writes a transmission log to disk for 
debugging purposes.  " +
-                               "If a file name is given, it is used, otherwise 
a file " +
-                               "called monet<timestamp>.log is created.  A 
given file " +
-                               "never be overwritten; instead a unique 
variation of the " +
-                               "file is used.");
+                               "A file name must be given.");
 
                try {
                        copts.processArgs(args);
@@ -133,6 +130,11 @@ copts.produceHelpMessage()
                }
                // FIXME: Control needs to respect Xhash
 
+               if (copts.getOption("Xdebug").isPresent()) {
+                       String fname = copts.getOption("Xdebug").getArgument();
+                       ctl.setDebug(fname);
+               }
+
                String[] commands = copts.getOption("command").getArguments();
                if (commands[0].equals("status")) {
                        List<SabaothDB> sdbs;
diff --git a/java/src/nl/cwi/monetdb/mcl/net/MapiSocket.java 
b/java/src/nl/cwi/monetdb/mcl/net/MapiSocket.java
--- a/java/src/nl/cwi/monetdb/mcl/net/MapiSocket.java
+++ b/java/src/nl/cwi/monetdb/mcl/net/MapiSocket.java
@@ -795,10 +795,12 @@ public final class MapiSocket {
                 * on the BufferedInputStream.  We want to benefit from the
                 * Buffered pre-fetching, but not dealing with half blocks.
                 * Changing this class to be able to use the partially received
-                * data will greatly complicate matters, while an performance
+                * data will greatly complicate matters, while a performance
                 * improvement is debatable given the relatively small size of
                 * our blocks.  Maybe it does speed up on slower links, then
                 * consider this method a quick bug fix/workaround.
+                *
+                * @return false if reading the block failed due to EOF
                 */
                private boolean _read(byte[] b, int len) throws IOException {
                        int s;
@@ -818,6 +820,8 @@ public final class MapiSocket {
                                                                
con.getInetAddress().getHostName() + ":" +
                                                                con.getPort() + 
": Incomplete block read from stream");
                                        }
+                                       if (debug)
+                                               logRd("server closed the 
connection (EOF)");
                                        return(false);
                                }
                                len -= s;
@@ -850,12 +854,10 @@ public final class MapiSocket {
                 * If the stream is not positioned correctly, hell will break
                 * loose.
                 */
-               private void readBlock() throws IOException {
+               private int readBlock() throws IOException {
                        // read next two bytes (short)
-                       if (!_read(blklen, 2)) throw
-                               new IOException("Read from " +
-                                               
con.getInetAddress().getHostName() + ":" +
-                                               con.getPort() + ": End of 
stream reached");
+                       if (!_read(blklen, 2))
+                               return(-1);
 
                        // Get the short-value and store its value in blockLen.
                        blockLen = (short)(
@@ -879,13 +881,10 @@ public final class MapiSocket {
                                                "larger than BLOCKsize: " +
                                                blockLen + " > " + 
block.length);
                        if (!_read(block, blockLen))
-                               new IOException("Read from " +
-                                               
con.getInetAddress().getHostName() + ":" +
-                                               con.getPort() + ": End of 
stream reached");
+                               return(-1);
 
-                       if (debug) {
+                       if (debug)
                                logRx(new String(block, 0, blockLen, "UTF-8"));
-                       }
 
                        // if this is the last block, make it end with a 
newline and
                        // prompt
@@ -900,13 +899,19 @@ public final class MapiSocket {
                                if (debug)
                                        logRd("inserting prompt");
                        }
+
+                       return(blockLen);
                }
 
                public int read() throws IOException {
-                       if (available() == 0)
-                               readBlock();
+                       if (available() == 0) {
+                               if (readBlock() == -1)
+                                       return(-1);
+                       }
+                               
                        if (debug)
                                logRx(new String(block, readPos, 1, "UTF-8"));
+
                        return((int)block[readPos++]);
                }
 
@@ -915,22 +920,19 @@ public final class MapiSocket {
                }
 
                public int read(byte[] b, int off, int len) throws IOException {
-                       int t = available();
-                       boolean hasAvailable = t + super.available() > 0;
+                       int t;
                        int size = 0;
                        while (size < len) {
+                               t = available();
                                if (t == 0) {
-                                       if (hasAvailable || size == 0) {
-                                               // shortcut some instructions, 
but make sure we
-                                               // always read *something* 
(block) for a read
-                                               // call, unless size == 0
-                                               readBlock();
-                                               t = available();
-                                       } else {
-                                               // nothing here, nothing 
waiting return what we
-                                               // have
+                                       if (size != 0)
+                                               break;
+                                       if (readBlock() == -1) {
+                                               if (size == 0)
+                                                       size = -1;
                                                break;
                                        }
+                                       t = available();
                                }
                                if (len > t) {
                                        System.arraycopy(block, readPos, b, 
off, t);
@@ -944,8 +946,6 @@ public final class MapiSocket {
                                        size += len;
                                        break;
                                }
-                               t = available();
-                               hasAvailable = t + super.available() > 0;
                        }
                        return(size);
                }
diff --git a/java/src/nl/cwi/monetdb/merovingian/Control.java 
b/java/src/nl/cwi/monetdb/merovingian/Control.java
--- a/java/src/nl/cwi/monetdb/merovingian/Control.java
+++ b/java/src/nl/cwi/monetdb/merovingian/Control.java
@@ -60,6 +60,8 @@ public class Control {
        private final int port;
        /** The passphrase to use when connecting */
        private final String passphrase;
+       /** The file we should write MapiSocket debuglog to */
+       private String debug;
 
 
        /**
@@ -76,6 +78,18 @@ public class Control {
                this.passphrase = passphrase;
        }
 
+       /**
+        * Instructs to write a MCL protocol debug log to the given file.
+        * This affects any newly performed command, and can be changed
+        * inbetween commands.  Passing null to this method disables the
+        * debug log.
+        *
+        * @param filename the filename to write debug information to, or null
+        */
+       public void setDebug(String filename) {
+               this.debug = filename;
+       }
+
        private String controlHash(String pass, String salt) {
                long ho;
                long h = 0;
@@ -115,11 +129,16 @@ public class Control {
                MapiSocket ms = new MapiSocket();
                ms.setDatabase("merovingian");
                ms.setLanguage("control");
-               ms.debug("test.log");
+               if (debug != null)
+                       ms.debug(debug);
                try {
                        ms.connect(host, port, "monetdb", passphrase);
                        min = ms.getReader();
                        mout = ms.getWriter();
+               } catch (MCLParseException e) {
+                       throw new MerovingianException(e.getMessage());
+               } catch (MCLException e) {
+                       throw new MerovingianException(e.getMessage());
                } catch (AssertionError e) { // mcl panics
                        ms.close();
                        
@@ -191,13 +210,9 @@ public class Control {
                                out.close();
                                s.close();
                        }
-               } catch (MCLException e) {
-                       throw new MerovingianException(e.getMessage());
-               } catch (MCLParseException e) {
-                       throw new MerovingianException(e.getMessage());
                }
 
-               mout.writeLine(database + " " + command +"\n");
+               mout.writeLine(database + " " + command + "\n");
                ArrayList<String> l = new ArrayList<String>();
                String tmpLine = min.readLine();
                int linetype = min.getLineType();
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list

Reply via email to