From fd082e7a9f9ddd9c74eeffdd7c4703aebfbac40c Mon Sep 17 00:00:00 2001 From: wj32 Date: Sat, 12 Sep 2009 02:34:48 +0000 Subject: [PATCH] improved async I/O git-svn-id: svn://svn.code.sf.net/p/processhacker/code@1871 21ef857c-d57f-4fe0-8362-d861dc6d29cd --- .../Objects/FileHandle.cs | 150 ++++++++++++------ .../Objects/ISynchronizable.cs | 6 +- 2 files changed, 103 insertions(+), 53 deletions(-) diff --git a/trunk/ProcessHacker.Native/Objects/FileHandle.cs b/trunk/ProcessHacker.Native/Objects/FileHandle.cs index 0749f224b..0284ea088 100644 --- a/trunk/ProcessHacker.Native/Objects/FileHandle.cs +++ b/trunk/ProcessHacker.Native/Objects/FileHandle.cs @@ -224,6 +224,58 @@ namespace ProcessHacker.Native.Objects this.Handle = handle; } + public AsyncIoContext BeginRead(MemoryRegion buffer) + { + NtStatus status; + AsyncIoContext asyncContext = new AsyncIoContext(this); + + asyncContext.KeepAlive(buffer); + + if ((status = Win32.NtReadFile( + this, + asyncContext.EventHandle, + null, + IntPtr.Zero, + asyncContext.StatusMemory, + buffer, + buffer.Size, + IntPtr.Zero, + IntPtr.Zero + )) >= NtStatus.Error) + Win32.ThrowLastError(status); + + if (status == NtStatus.Success) + asyncContext.CompletedSynchronously = true; + + return asyncContext; + } + + public AsyncIoContext BeginWrite(MemoryRegion buffer) + { + NtStatus status; + AsyncIoContext asyncContext = new AsyncIoContext(this); + + asyncContext.KeepAlive(buffer); + + if ((status = Win32.NtWriteFile( + this, + asyncContext.EventHandle, + null, + IntPtr.Zero, + asyncContext.StatusMemory, + buffer, + buffer.Size, + IntPtr.Zero, + IntPtr.Zero + )) >= NtStatus.Error) + Win32.ThrowLastError(status); + + if (status == NtStatus.Success) + asyncContext.CompletedSynchronously = true; + + return asyncContext; + } + public IoStatusBlock CancelIo() { NtStatus status; @@ -243,6 +295,26 @@ namespace ProcessHacker.Native.Objects Win32.ThrowLastError(status); } + public int EndRead(AsyncIoContext asyncContext) + { + asyncContext.Wait(); + + if (asyncContext.Status.Status >= NtStatus.Error) + Win32.ThrowLastError(asyncContext.Status.Status); + + return asyncContext.Status.Information.ToInt32(); + } + + public int EndWrite(AsyncIoContext asyncContext) + { + asyncContext.Wait(); + + if (asyncContext.Status.Status >= NtStatus.Error) + Win32.ThrowLastError(asyncContext.Status.Status); + + return asyncContext.Status.Information.ToInt32(); + } + public void EnumFiles(EnumFilesDelegate callback) { NtStatus status; @@ -574,28 +646,6 @@ namespace ProcessHacker.Native.Objects return isb.Information.ToInt32(); } - public NtStatus Read(MemoryRegion buffer, AsyncIoContext asyncContext) - { - NtStatus status; - - asyncContext.KeepAlive(buffer); - - if ((status = Win32.NtReadFile( - this, - asyncContext.EventHandle, - null, - IntPtr.Zero, - asyncContext.StatusMemory, - buffer, - buffer.Size, - IntPtr.Zero, - IntPtr.Zero - )) >= NtStatus.Error) - Win32.ThrowLastError(status); - - return status; - } - public void SetIoCompletion(IoCompletionHandle ioCompletionHandle, IntPtr keyContext) { FileCompletionInformation info = new FileCompletionInformation(); @@ -668,36 +718,15 @@ namespace ProcessHacker.Native.Objects return isb.Information.ToInt32(); } - - public NtStatus Write(MemoryRegion buffer, AsyncIoContext asyncContext) - { - NtStatus status; - - asyncContext.KeepAlive(buffer); - - if ((status = Win32.NtWriteFile( - this, - asyncContext.EventHandle, - null, - IntPtr.Zero, - asyncContext.StatusMemory, - buffer, - buffer.Size, - IntPtr.Zero, - IntPtr.Zero - )) >= NtStatus.Error) - Win32.ThrowLastError(status); - - return status; - } } - public sealed class AsyncIoContext : BaseObject + public sealed class AsyncIoContext : BaseObject, ISynchronizable { private EventHandle _eventHandle; private FileHandle _fileHandle; private MemoryAlloc _isb; private bool _canceled = false; + private bool _completedSynchronously = false; private List _keepAliveList = new List(); private object _tag; @@ -741,7 +770,13 @@ namespace ProcessHacker.Native.Objects get { return _eventHandle.GetBasicInformation().EventState != 0; } } - public EventHandle EventHandle + public bool CompletedSynchronously + { + get { return _completedSynchronously; } + internal set { _completedSynchronously = value; } + } + + internal EventHandle EventHandle { get { return _eventHandle; } } @@ -796,15 +831,30 @@ namespace ProcessHacker.Native.Objects obj.Reference(); } - public void Wait() + #region ISynchronizable Members + + [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + public IntPtr Handle { - _eventHandle.Wait(); + get { return _eventHandle.Handle; } } - public void Wait(int timeoutMilliseconds) + public NtStatus Wait() { - _eventHandle.Wait(timeoutMilliseconds * Win32.TimeMsTo100Ns); + return _eventHandle.Wait(); } + + public NtStatus Wait(bool alertable) + { + return _eventHandle.Wait(alertable); + } + + public NtStatus Wait(bool alertable, long timeout) + { + return _eventHandle.Wait(alertable, timeout); + } + + #endregion } public class FileEntry diff --git a/trunk/ProcessHacker.Native/Objects/ISynchronizable.cs b/trunk/ProcessHacker.Native/Objects/ISynchronizable.cs index 8fad492ff..0b45e0698 100644 --- a/trunk/ProcessHacker.Native/Objects/ISynchronizable.cs +++ b/trunk/ProcessHacker.Native/Objects/ISynchronizable.cs @@ -32,9 +32,9 @@ namespace ProcessHacker.Native.Objects { IntPtr Handle { get; } - NtStatus SignalAndWait(ISynchronizable waitObject); - NtStatus SignalAndWait(ISynchronizable waitObject, bool alertable); - NtStatus SignalAndWait(ISynchronizable waitObject, bool alertable, long timeout); + //NtStatus SignalAndWait(ISynchronizable waitObject); + //NtStatus SignalAndWait(ISynchronizable waitObject, bool alertable); + //NtStatus SignalAndWait(ISynchronizable waitObject, bool alertable, long timeout); NtStatus Wait(); NtStatus Wait(bool alertable); NtStatus Wait(bool alertable, long timeout);