private unsafe IAsyncResult BeginWriteCore(byte[] array, int offset, int count, AsyncCallback userCallback, Object stateObject) { Debug.Assert(userCallback == null); Debug.Assert(stateObject == null); CheckParametersForBegin(array, offset, count); AsyncFileStream_AsyncResult asyncResult = new AsyncFileStream_AsyncResult(userCallback, stateObject, true); if (count == 0) { asyncResult.SignalCompleted(); } else { // Keep the array in one location in memory until the OS writes the // relevant data into the array. Free GCHandle later. asyncResult.PinBuffer(array); fixed(byte *p = array) { uint numBytesWritten = 0; bool res; byte[] byteArray = new byte[count]; Marshal.Copy(new IntPtr(p + offset), byteArray, 0, count); //res = Native.ReadFile(m_handle.DangerousGetHandle(), p + offset, count, out numBytesRead, asyncResult.OverlappedPtr); res = WinUsbDevice.WinUsb_WritePipe( m_winUsbDevice.DeviceInfo.winUsbHandle, System.Convert.ToByte(m_winUsbDevice.DeviceInfo.bulkOutPipe), byteArray, (uint)count, ref numBytesWritten, System.IntPtr.Zero); if (res == false) { if (HandleErrorSituation("BeginWrite", true)) { asyncResult.SignalCompleted(); } else { m_outstandingRequests.Add(asyncResult); } } else { asyncResult.m_numBytes = (int)numBytesWritten; asyncResult.SignalCompleted(); } } } return(asyncResult); }
public void CancelPendingIO() { lock (m_outstandingRequests.SyncRoot) { for (int i = m_outstandingRequests.Count - 1; i >= 0; i--) { AsyncFileStream_AsyncResult asfar = (AsyncFileStream_AsyncResult)m_outstandingRequests[i]; asfar.SignalCompleted(); } m_outstandingRequests.Clear(); } }
public override void EndWrite(IAsyncResult asyncResult) { AsyncFileStream_AsyncResult afsar = CheckParameterForEnd(asyncResult, true); afsar.WaitCompleted(); m_outstandingRequests.Remove(afsar); // Now check for any error during the write. if (afsar.m_errorCode != 0) { throw new IOException("Async Write failed", afsar.m_errorCode); } }
public override int EndRead(IAsyncResult asyncResult) { AsyncFileStream_AsyncResult afsar = CheckParameterForEnd(asyncResult, false); afsar.WaitCompleted(); m_outstandingRequests.Remove(afsar); // Now check for any error during the read. if (afsar.m_errorCode != 0) { throw new IOException("Async Read failed", afsar.m_errorCode); } return(afsar.m_numBytes); }
private AsyncFileStream_AsyncResult CheckParameterForEnd(IAsyncResult asyncResult, bool isWrite) { if (asyncResult == null) { throw new ArgumentNullException("asyncResult"); } AsyncFileStream_AsyncResult afsar = asyncResult as AsyncFileStream_AsyncResult; if (afsar == null || afsar.m_isWrite != isWrite) { throw new ArgumentException("asyncResult"); } if (afsar.m_EndXxxCalled) { throw new InvalidOperationException("EndRead called twice"); } afsar.m_EndXxxCalled = true; return(afsar); }
// this callback is called by a free thread in the threadpool when the IO operation completes. unsafe private static void DoneCallback(uint errorCode, uint numBytes, NativeOverlapped *pOverlapped) { if (errorCode == Native.ERROR_OPERATION_ABORTED) { numBytes = 0; errorCode = 0; } // Unpack overlapped Overlapped overlapped = Overlapped.Unpack(pOverlapped); // Free the overlapped struct in EndRead/EndWrite. // Extract async result from overlapped AsyncFileStream_AsyncResult asyncResult = (AsyncFileStream_AsyncResult)overlapped.AsyncResult; asyncResult.m_numBytes = (int)numBytes; asyncResult.m_errorCode = (int)errorCode; asyncResult.SignalCompleted(); }
private unsafe IAsyncResult BeginWriteCore(byte[] array, int offset, int count, AsyncCallback userCallback, Object stateObject) { CheckParametersForBegin(array, offset, count); AsyncFileStream_AsyncResult asyncResult = new AsyncFileStream_AsyncResult(userCallback, stateObject, true); if (count == 0) { asyncResult.SignalCompleted(); } else { asyncResult.m_numBytes = count; // Keep the array in one location in memory until the OS writes the // relevant data into the array. Free GCHandle later. asyncResult.PinBuffer(array); fixed(byte *p = array) { int numBytesWritten = 0; bool res; res = Native.WriteFile(m_handle.DangerousGetHandle(), p + offset, count, out numBytesWritten, asyncResult.OverlappedPtr); if (res == false) { if (HandleErrorSituation("BeginWrite", true)) { asyncResult.SignalCompleted(); } else { m_outstandingRequests.Add(asyncResult); } } } } return(asyncResult); }
private unsafe IAsyncResult BeginWriteCore(byte[] array, int offset, int count, AsyncCallback userCallback, Object stateObject) { Debug.Assert(userCallback == null); Debug.Assert(stateObject == null); CheckParametersForBegin(array, offset, count); AsyncFileStream_AsyncResult asyncResult = new AsyncFileStream_AsyncResult(userCallback, stateObject, true); if(count == 0) { asyncResult.SignalCompleted(); } else { // Keep the array in one location in memory until the OS writes the // relevant data into the array. Free GCHandle later. asyncResult.PinBuffer(array); fixed (byte* p = array) { uint numBytesWritten = 0; bool res; byte[] byteArray = new byte[count]; Marshal.Copy(new IntPtr(p + offset), byteArray, 0, count); //res = Native.ReadFile(m_handle.DangerousGetHandle(), p + offset, count, out numBytesRead, asyncResult.OverlappedPtr); res = WinUsbDevice.WinUsb_WritePipe( m_winUsbDevice.DeviceInfo.winUsbHandle, System.Convert.ToByte(m_winUsbDevice.DeviceInfo.bulkOutPipe), byteArray, (uint)count, ref numBytesWritten, System.IntPtr.Zero); if(res == false) { if(HandleErrorSituation("BeginWrite", true)) { asyncResult.SignalCompleted(); } else { m_outstandingRequests.Add(asyncResult); } } else { asyncResult.m_numBytes = (int)numBytesWritten; asyncResult.SignalCompleted(); } } } return asyncResult; }
//--// //--// //--// private unsafe IAsyncResult BeginReadCore(byte[] array, int offset, int count, AsyncCallback userCallback, Object stateObject) { Debug.Assert(userCallback == null); Debug.Assert(stateObject == null); CheckParametersForBegin(array, offset, count); AsyncFileStream_AsyncResult asyncResult = new AsyncFileStream_AsyncResult(userCallback, stateObject, false); if(count == 0) { asyncResult.SignalCompleted(); } else { // Keep the array in one location in memory until the OS writes the // relevant data into the array. Free GCHandle later. asyncResult.PinBuffer(array); int totalRead = 0; int availableToTransfer = 0; fixed (byte* dst = array) { // if we already have available data, then we need to use it lock(syncRW) { System.Diagnostics.Debug.Assert(count == m_bytesAvailable); if(m_bytesAvailable > 0) { // truncate availableToTransfer = Math.Min(count, (int)m_bytesAvailable); // copy over to the application buffer Marshal.Copy(m_buffer, 0, new IntPtr(dst + offset), availableToTransfer); // update the available bytes count m_bytesAvailable -= (uint)availableToTransfer; totalRead += availableToTransfer; // adjust the buffering if there is a left over // this will never happen if application call AvailableBytes and the reads them if(m_bytesAvailable > 0) { fixed (byte* copy = m_buffer) { Marshal.Copy(new IntPtr(copy), m_buffer, (int)availableToTransfer, (int)m_bytesAvailable); } } } } // if we need to read more, then we shoudl go to the stream directly int remainder = count - availableToTransfer; if(remainder > 0) { byte[] byteArray = new byte[remainder]; Array.Clear(byteArray, 0, byteArray.Length); fixed (byte* p = byteArray) { uint numBytesRead = 0; bool res; res = WinUsbDevice.WinUsb_ReadPipe( m_winUsbDevice.DeviceInfo.winUsbHandle, System.Convert.ToByte(m_winUsbDevice.DeviceInfo.bulkInPipe), byteArray, (uint)remainder, ref numBytesRead, System.IntPtr.Zero); if(res == false) { if(HandleErrorSituation("BeginRead", false)) { asyncResult.SignalCompleted(); } else { m_outstandingRequests.Add(asyncResult); } } else { Marshal.Copy(byteArray, 0, new IntPtr(dst + totalRead + offset), (int)numBytesRead); totalRead += (int)numBytesRead; } } } if(totalRead > 0) { asyncResult.m_numBytes = (int)totalRead; asyncResult.SignalCompleted(); } } } return asyncResult; }
private unsafe IAsyncResult BeginWriteCore( byte[] array, int offset, int count, AsyncCallback userCallback, Object stateObject ) { CheckParametersForBegin( array, offset, count ); AsyncFileStream_AsyncResult asyncResult = new AsyncFileStream_AsyncResult( userCallback, stateObject, true ); if(count == 0) { asyncResult.SignalCompleted(); } else { // Keep the array in one location in memory until the OS writes the // relevant data into the array. Free GCHandle later. asyncResult.PinBuffer( array ); fixed(byte* p = array) { int numBytesWritten = 0; bool res; res = Native.WriteFile( m_handle.DangerousGetHandle(), p + offset, count, out numBytesWritten, asyncResult.OverlappedPtr ); if(res == false) { if(HandleErrorSituation( "BeginWrite", true )) { asyncResult.SignalCompleted(); } else { m_outstandingRequests.Add( asyncResult ); } } } } return asyncResult; }
//--// //--// //--// private unsafe IAsyncResult BeginReadCore(byte[] array, int offset, int count, AsyncCallback userCallback, Object stateObject) { Debug.Assert(userCallback == null); Debug.Assert(stateObject == null); CheckParametersForBegin(array, offset, count); AsyncFileStream_AsyncResult asyncResult = new AsyncFileStream_AsyncResult(userCallback, stateObject, false); if (count == 0) { asyncResult.SignalCompleted(); } else { // Keep the array in one location in memory until the OS writes the // relevant data into the array. Free GCHandle later. asyncResult.PinBuffer(array); int totalRead = 0; int availableToTransfer = 0; fixed(byte *dst = array) { // if we already have available data, then we need to use it lock (syncRW) { System.Diagnostics.Debug.Assert(count == m_bytesAvailable); if (m_bytesAvailable > 0) { // truncate availableToTransfer = Math.Min(count, (int)m_bytesAvailable); // copy over to the application buffer Marshal.Copy(m_buffer, 0, new IntPtr(dst + offset), availableToTransfer); // update the available bytes count m_bytesAvailable -= (uint)availableToTransfer; totalRead += availableToTransfer; // adjust the buffering if there is a left over // this will never happen if application call AvailableBytes and the reads them if (m_bytesAvailable > 0) { fixed(byte *copy = m_buffer) { Marshal.Copy(new IntPtr(copy), m_buffer, (int)availableToTransfer, (int)m_bytesAvailable); } } } } // if we need to read more, then we shoudl go to the stream directly int remainder = count - availableToTransfer; if (remainder > 0) { byte[] byteArray = new byte[remainder]; Array.Clear(byteArray, 0, byteArray.Length); fixed(byte *p = byteArray) { uint numBytesRead = 0; bool res; res = WinUsbDevice.WinUsb_ReadPipe( m_winUsbDevice.DeviceInfo.winUsbHandle, System.Convert.ToByte(m_winUsbDevice.DeviceInfo.bulkInPipe), byteArray, (uint)remainder, ref numBytesRead, System.IntPtr.Zero); if (res == false) { if (HandleErrorSituation("BeginRead", false)) { asyncResult.SignalCompleted(); } else { m_outstandingRequests.Add(asyncResult); } } else { Marshal.Copy(byteArray, 0, new IntPtr(dst + totalRead + offset), (int)numBytesRead); totalRead += (int)numBytesRead; } } } if (totalRead > 0) { asyncResult.m_numBytes = (int)totalRead; asyncResult.SignalCompleted(); } } } return(asyncResult); }