[jcifs] [PATCH] WaitNamedPipe example is not complete

David D. Kilzer ddkilzer at kilzer.net
Fri Sep 16 20:53:13 GMT 2005


The WaitNamedPipe example class in jCIFS is not complete.  Per the MSDN
documentation on the WaitNamedPipe() method [1] and a Microsoft
knowledgebase article about named pipes and SQL Server 6.5/7 [2], this
method is supposed to retry the connection to the named pipe if an "All
pipe instances are busy" error message (error code 231; "connection
busy" or "pipe busy") is received while connecting.

To make WaitNamedPipe behave more like its namesake, the changes in the
attached patch should be applied.  NOTE:  THESE CHANGES ARE UNTESTED!
The SmbNamedPipe.getNamedPipeInputStream() method may also have to be
wrapped.  Also note that I did not implement the "indefinite wait"
feature, although a sufficiently large long value would suffice.

I made similar changes to the jTDS JDBC driver [3] which have been
tested in our development environment against SQL Server 6.5 and are
working fine.  Note that these changes to jTDS wrapped both the
SmbNamedPipe.getNamedPipeOutputStream() and getNamedPipeInputStream()
methods, as well as the SmbNamedPipe constructor.  See also jTDS Bug
1277000 [4].

Dave

[1] http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ipc/base/waitnamedpipe.asp
[2] http://support.microsoft.com/default.aspx?scid=KB;EN-US;165189
[3] http://cvs.sourceforge.net/viewcvs.py/jtds/jtds/src/main/net/sourceforge/jtds/jdbc/ConnectionJDBC2.java?r1=1.96&r2=1.97
[4] http://sourceforge.net/tracker/index.php?func=detail&aid=1277000&group_id=33291&atid=407762
-------------- next part --------------
Index: examples/WaitNamedPipe.java
===================================================================
RCS file: /var/lib/cvs/isl/java-libraries/jcifs/jcifs-1.1.8/examples/WaitNamedPipe.java,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 WaitNamedPipe.java
--- examples/WaitNamedPipe.java	21 Feb 2005 21:19:45 -0000	1.1.1.1
+++ examples/WaitNamedPipe.java	16 Sep 2005 20:19:06 -0000
@@ -3,6 +3,8 @@
 import java.io.OutputStream;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Random;
 
 public class WaitNamedPipe {
 
@@ -17,7 +19,7 @@
         FileOutputStream fos = new FileOutputStream( argv[2] );
 
         SmbNamedPipe pipe = new SmbNamedPipe( argv[0], SmbNamedPipe.PIPE_TYPE_RDWR );
-        OutputStream out = pipe.getNamedPipeOutputStream();
+        OutputStream out = waitNamedPipeOutputStream( pipe, 20000 );
         InputStream in = pipe.getNamedPipeInputStream();
 
         int n = fin.read( b );
@@ -31,4 +33,47 @@
         fos.close();
         out.close();
     }
+
+    private static OutputStream waitNamedPipeOutputStream( SmbNamedPipe pipe, long timeout )
+            throws IOException {
+
+        OutputStream out = null;
+        IOException lastIOE = null;
+        final long startTimeout = System.currentTimeMillis();
+        final Random random = new Random( startTimeout );
+
+        do {
+            try {
+                out = pipe.getNamedPipeOutputStream();
+            }
+            catch( IOException ioe ) {
+                lastIOE = ioe;
+                if( ioe.getMessage().toLowerCase().indexOf( "all pipe instances are busy" ) >= 0 ) {
+                    // Per a Microsoft knowledgebase article for SQL Server 6.5/7, wait 200 ms
+                    // to 1 second each time we get an "All pipe instances are busy" error.
+                    // http://support.microsoft.com/default.aspx?scid=KB;EN-US;165189
+                    // See also this MSDN article on the WaitNamedPipe() method:
+                    // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ipc/base/waitnamedpipe.asp
+                    try {
+                        Thread.sleep( random.nextInt(800) + 200 );
+                    }
+                    catch( InterruptedException ie ) {
+                        // Do nothing; retry
+                    }
+                }
+                else {
+                    throw ioe;
+                }
+            }
+        } while( out != null && ( System.currentTimeMillis() - startTimeout ) < timeout );
+
+        if( out == null ) {
+            final IOException e = new IOException("Failed to connect output stream to named pipe");
+            e.initCause(lastIOE);
+            throw e;
+        }
+
+        return out;
+    }
+
 }


More information about the jcifs mailing list