improved async I/O

git-svn-id: svn://svn.code.sf.net/p/processhacker/code@1871 21ef857c-d57f-4fe0-8362-d861dc6d29cd
This commit is contained in:
wj32
2009-09-12 02:34:48 +00:00
parent 621fee758a
commit fd082e7a9f
2 changed files with 103 additions and 53 deletions
+100 -50
View File
@@ -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<BaseObject> _keepAliveList = new List<BaseObject>();
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
@@ -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);