private unsafe int ProcessRead(SerialStreamIORequest r) { Span <byte> buff = r.Buffer.Span; fixed(byte *bufPtr = buff) { // assumes dequeue-ing happens on a single thread int numBytes = Interop.Serial.Read(_handle, bufPtr, buff.Length); if (numBytes < 0) { Interop.ErrorInfo lastError = Interop.Sys.GetLastErrorInfo(); // ignore EWOULDBLOCK since we handle timeout elsewhere if (lastError.Error != Interop.Error.EWOULDBLOCK) { r.Complete(Interop.GetIOException(lastError)); } } else if (numBytes > 0) { r.Complete(numBytes); return(numBytes); } else // numBytes == 0 { RaiseDataReceivedEof(); } } return(0); }
private unsafe int ProcessWrite(SerialStreamIORequest r) { ReadOnlySpan <byte> buff = r.Buffer.Span; fixed(byte *bufPtr = buff) { // assumes dequeue-ing happens on a single thread int numBytes = Interop.Serial.Write(_handle, bufPtr, buff.Length); if (numBytes <= 0) { Interop.ErrorInfo lastError = Interop.Sys.GetLastErrorInfo(); // ignore EWOULDBLOCK since we handle timeout elsewhere // numBytes == 0 means that there might be an error if (lastError.Error != Interop.Error.SUCCESS && lastError.Error != Interop.Error.EWOULDBLOCK) { r.Complete(Interop.GetIOException(lastError)); } } else { r.ProcessBytes(numBytes); if (r.Buffer.Length == 0) { r.Complete(); } return(numBytes); } } return(0); }
public override Task WriteAsync(byte[] array, int offset, int count, CancellationToken cancellationToken) { CheckWriteArguments(array, offset, count); if (count == 0) { return(Task.CompletedTask); // return immediately if no bytes to write; no need for overhead. } Memory <byte> buffer = new Memory <byte>(array, offset, count); SerialStreamIORequest result = new SerialStreamIORequest(cancellationToken, buffer); _writeQueue.Enqueue(result); EnsureIOLoopRunning(); return(result.Task); }