MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Vladislav Vaintroub Date:October 13 2009 3:07am
Subject:bzr push into connector-net-trunk branch (vvaintroub:781 to 782)
View as plain text  
  782 Vladislav Vaintroub	2009-10-13
      Handle ERROR_PIPE_BUSY errors (possible if pipe is opened by many clients at the same time).Respect timeout when waiting for busy pipe.

    modified:
      MySql.Data/Provider/Source/common/NamedPipeStream.cs
      MySql.Data/Provider/Source/common/NativeMethods.cs
      MySql.Data/Provider/Source/common/StreamCreator.cs
  781 Reggie Burnett	2009-10-09
      a few changes to fix CF compilation and checking in a file that we left out of the logging refactoring cset

    removed:
      MySql.Data/Provider/Source/common/Utilities.cs
    added:
      MySql.Data/Provider/Source/TracingDriver.cs
    modified:
      MySQLClient.sln
      MySql.Data/Provider/MySql.Data.CF.csproj
      MySql.Data/Provider/MySql.Data.csproj
      MySql.Data/Provider/Source/Connection.cs
      MySql.Data/Provider/Source/Driver.cs
      MySql.Data/Provider/Source/MySqlConnectionStringBuilder.cs
      MySql.Data/Provider/Source/MySqlTrace.cs
      MySql.Data/Provider/Source/MysqlDefs.cs
      MySql.Data/Provider/Source/NativeDriver.cs
      MySql.Data/Provider/Source/PerformanceMonitor.cs
      MySql.Data/Provider/Source/ProcedureCache.cs
      MySql.Data/Provider/Source/command.cs
      MySql.Data/Provider/Source/datareader.cs
      MySql.Data/Tests/Source/ParameterTests.cs
      MySql.Data/Tests/Source/UsageAdvisor.cs
=== modified file 'MySql.Data/Provider/Source/common/NamedPipeStream.cs'
--- a/MySql.Data/Provider/Source/common/NamedPipeStream.cs	2009-09-26 12:32:55 +0000
+++ b/MySql.Data/Provider/Source/common/NamedPipeStream.cs	2009-10-13 03:07:05 +0000
@@ -26,6 +26,7 @@ using Microsoft.Win32.SafeHandles;
 using System.Threading;
 using System.Diagnostics;
 using System.Runtime.InteropServices;
+using System.ComponentModel;
 
 
 
@@ -40,11 +41,12 @@ namespace MySql.Data.Common
         Stream fileStream;
         int readTimeout = Timeout.Infinite;
         int writeTimeout = Timeout.Infinite;
+        const int ERROR_PIPE_BUSY = 231;
+        const int ERROR_SEM_TIMEOUT = 121;
 
-
-        public NamedPipeStream(string path, FileAccess mode)
+        public NamedPipeStream(string path, FileAccess mode, uint timeout)
         {
-            Open(path, mode);
+            Open(path, mode, timeout);
         }
 
         void CancelIo()
@@ -53,10 +55,40 @@ namespace MySql.Data.Common
             if (!ok)
                 throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());
         }
-        public void Open( string path, FileAccess mode )
+        public void Open( string path, FileAccess mode ,uint timeout )
         {
-            handle = new SafeFileHandle( NativeMethods.CreateFile(path, NativeMethods.GENERIC_READ | NativeMethods.GENERIC_WRITE,
-                         0, null, NativeMethods.OPEN_EXISTING, NativeMethods.FILE_FLAG_OVERLAPPED, 0),true);
+            IntPtr nativeHandle;
+            for (; ; )
+            {
+                nativeHandle = NativeMethods.CreateFile(path, NativeMethods.GENERIC_READ | NativeMethods.GENERIC_WRITE,
+                             0, null, NativeMethods.OPEN_EXISTING, NativeMethods.FILE_FLAG_OVERLAPPED, 0);
+                if (nativeHandle != IntPtr.Zero)
+                    break;
+
+                if (Marshal.GetLastWin32Error() != ERROR_PIPE_BUSY)
+                {
+                    throw new Win32Exception(Marshal.GetLastWin32Error(),
+                        "Error opening pipe");
+                }
+                LowResolutionStopwatch sw = LowResolutionStopwatch.StartNew();
+                bool success = NativeMethods.WaitNamedPipe(path, timeout);
+                sw.Stop();
+                if (!success)
+                {
+                    if (timeout < sw.ElapsedMilliseconds || 
+                        Marshal.GetLastWin32Error() == ERROR_SEM_TIMEOUT)
+                    {
+                        throw new TimeoutException("Timeout waiting for named pipe");
+                    }
+                    else
+                    {
+                        throw new Win32Exception(Marshal.GetLastWin32Error(), 
+                            "Error waiting for pipe");
+                    }
+                }
+                timeout -= (uint)sw.ElapsedMilliseconds;
+            }
+            handle = new SafeFileHandle(nativeHandle, true);
             fileStream = new FileStream(handle, mode, 4096, true);
         }
 
@@ -189,14 +221,14 @@ namespace MySql.Data.Common
             throw new NotSupportedException(Resources.NamedPipeNoSeek);
         }
      
-        internal static Stream Create(string pipeName, string hostname)
+        internal static Stream Create(string pipeName, string hostname, uint timeout)
         {
             string pipePath;
             if (0 == String.Compare(hostname, "localhost", true))
                 pipePath = @"\\.\pipe\" + pipeName;
             else
                 pipePath = String.Format(@"\\{0}\pipe\{1}", hostname, pipeName);
-            return new NamedPipeStream(pipePath, FileAccess.ReadWrite);
+            return new NamedPipeStream(pipePath, FileAccess.ReadWrite, timeout);
         }
     }
 }

=== modified file 'MySql.Data/Provider/Source/common/NativeMethods.cs'
--- a/MySql.Data/Provider/Source/common/NativeMethods.cs	2009-09-24 20:57:21 +0000
+++ b/MySql.Data/Provider/Source/common/NativeMethods.cs	2009-10-13 03:07:05 +0000
@@ -120,6 +120,8 @@ namespace MySql.Data.Common
         [DllImport("kernel32.dll", SetLastError = true)]
         public static extern int FlushViewOfFile(IntPtr address, uint numBytes);
 
+        [DllImport("kernel32.dll", SetLastError = true)]
+        public static extern bool WaitNamedPipe(string namedPipeName, uint timeOut);
 		#region Winsock functions
 
 		// SOcket routines

=== modified file 'MySql.Data/Provider/Source/common/StreamCreator.cs'
--- a/MySql.Data/Provider/Source/common/StreamCreator.cs	2009-10-07 20:30:34 +0000
+++ b/MySql.Data/Provider/Source/common/StreamCreator.cs	2009-10-13 03:07:05 +0000
@@ -72,7 +72,7 @@ namespace MySql.Data.Common
                     if (usePipe)
                     {
 #if !CF
-                        stream = NamedPipeStream.Create(pipeName, dnsHosts[index]);
+                        stream = NamedPipeStream.Create(pipeName, dnsHosts[index], timeout);
 #endif
                     }
                     else


Attachment: [text/bzr-bundle] bzr/vvaintroub@mysql.com-20091013030705-4xp5seq0n32o3bjj.bundle
Thread
bzr push into connector-net-trunk branch (vvaintroub:781 to 782)Vladislav Vaintroub13 Oct