Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenric Müller <hemuller@microsoft.com>2016-10-12 16:04:10 +0300
committerHenric Müller <hemuller@microsoft.com>2016-10-12 16:07:04 +0300
commit0aed701c96bfc3880076f2dcc53ef7fc2f749c9c (patch)
treef3a4bd1d7a9ea669b4fba504c5f997950a39f143 /mcs/class/System.Runtime.Remoting
parent082057e3d7247ac5c260355d8145960fbaaa8e76 (diff)
Making named pipe connects alertable on Windows
This fix makes sure that an aborted thread will wake up a blocking named pipe connect.
Diffstat (limited to 'mcs/class/System.Runtime.Remoting')
-rw-r--r--mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Ipc.Win32/NamedPipeHelper.cs7
-rw-r--r--mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Ipc.Win32/NamedPipeListener.cs52
2 files changed, 38 insertions, 21 deletions
diff --git a/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Ipc.Win32/NamedPipeHelper.cs b/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Ipc.Win32/NamedPipeHelper.cs
index 089cd330b62..974caaaaa8b 100644
--- a/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Ipc.Win32/NamedPipeHelper.cs
+++ b/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Ipc.Win32/NamedPipeHelper.cs
@@ -26,10 +26,9 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-
-using System;
using System.Runtime.InteropServices;
using System.Text;
+using System.Threading;
namespace System.Runtime.Remoting.Channels.Ipc.Win32
{
@@ -89,6 +88,7 @@ namespace System.Runtime.Remoting.Channels.Ipc.Win32
public const uint OPEN_EXISTING = 3;
public const uint OPEN_ALWAYS = 4;
public const uint TRUNCATE_EXISTING = 5;
+ public const uint FILE_FLAG_OVERLAPPED = 0x40000000;
// Access flags
public const uint GENERIC_READ = 0x80000000;
@@ -103,6 +103,7 @@ namespace System.Runtime.Remoting.Channels.Ipc.Win32
public const int ERROR_PIPE_NOT_CONNECTED = 233;
public const int ERROR_PIPE_CONNECTED = 535;
public const int ERROR_PIPE_LISTENING = 536;
+ public const int ERROR_IO_PENDING = 997;
public const int INVALID_HANDLE_VALUE = -1;
@@ -121,7 +122,7 @@ namespace System.Runtime.Remoting.Channels.Ipc.Win32
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool ConnectNamedPipe(
IntPtr hPipe,
- IntPtr lpOverlapped
+ [In] ref NativeOverlapped lpOverlapped
);
[DllImport("kernel32.dll", SetLastError = true)]
diff --git a/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Ipc.Win32/NamedPipeListener.cs b/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Ipc.Win32/NamedPipeListener.cs
index 8270e3d157f..7170b7e932a 100644
--- a/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Ipc.Win32/NamedPipeListener.cs
+++ b/mcs/class/System.Runtime.Remoting/System.Runtime.Remoting.Channels.Ipc.Win32/NamedPipeListener.cs
@@ -27,8 +27,8 @@
//
-using System;
using System.Runtime.InteropServices;
+using System.Threading;
namespace System.Runtime.Remoting.Channels.Ipc.Win32
{
@@ -74,7 +74,7 @@ namespace System.Runtime.Remoting.Channels.Ipc.Win32
{
IntPtr hPipe = NamedPipeHelper.CreateNamedPipe(
pipeName,
- NamedPipeHelper.PIPE_ACCESS_DUPLEX,
+ NamedPipeHelper.PIPE_ACCESS_DUPLEX | NamedPipeHelper.FILE_FLAG_OVERLAPPED,
NamedPipeHelper.PIPE_TYPE_MESSAGE
| NamedPipeHelper.PIPE_READMODE_MESSAGE
| NamedPipeHelper.PIPE_WAIT,
@@ -85,27 +85,43 @@ namespace System.Runtime.Remoting.Channels.Ipc.Win32
IntPtr.Zero
);
- if (hPipe.ToInt32() == NamedPipeHelper.INVALID_HANDLE_VALUE)
- {
- throw new NamedPipeException();
+ if (hPipe.ToInt32 () == NamedPipeHelper.INVALID_HANDLE_VALUE) {
+ throw new NamedPipeException (Marshal.GetLastWin32Error ());
}
- bool canConnect = NamedPipeHelper.ConnectNamedPipe(hPipe, IntPtr.Zero);
- int lastError = Marshal.GetLastWin32Error();
- if (!canConnect && lastError == NamedPipeHelper.ERROR_PIPE_CONNECTED)
- canConnect = true;
+ // Connect the named pipe with overlapped structure
+ // in order to make it altertable. This way we will
+ // wake up when someone aborts a thread waiting
+ // for this pipe.
+ NativeOverlapped overlapped = new NativeOverlapped ();
+ bool canConnect = NamedPipeHelper.ConnectNamedPipe (hPipe, ref overlapped);
- if (canConnect)
- {
- return new NamedPipeSocket(hPipe);
- }
- else
- {
- NamedPipeHelper.CloseHandle(hPipe);
- throw new NamedPipeException(lastError);
- }
+ int lastError = Marshal.GetLastWin32Error ();
+ if (!canConnect) {
+ if (lastError == NamedPipeHelper.ERROR_IO_PENDING) {
+ uint bytesTransferred = 0;
+ if (!GetOverlappedResultEx (hPipe, ref overlapped, out bytesTransferred, Timeout.Infinite, true)) {
+ lastError = Marshal.GetLastWin32Error ();
+ NamedPipeHelper.CloseHandle (hPipe);
+ throw new NamedPipeException (lastError);
+ }
+ canConnect = true;
+ } else if (lastError == NamedPipeHelper.ERROR_PIPE_CONNECTED)
+ canConnect = true;
+ }
+
+ if (!canConnect) {
+ NamedPipeHelper.CloseHandle (hPipe);
+ throw new NamedPipeException (lastError);
+ }
+
+ return new NamedPipeSocket (hPipe);
}
+ [DllImport("kernel32.dll", SetLastError = true)]
+ static extern bool GetOverlappedResultEx (IntPtr hFile, [In] ref System.Threading.NativeOverlapped lpOverlapped,
+ out uint lpNumberOfBytesTransferred, int dwMilliseconds, bool bAltertable);
+
}
}