private void ThrowException() { if (m_Dll == null) { return; } SysErrNo managedErrNo; string sysDescription; try { // These methods were first added in libnserial 1.1 managedErrNo = m_Dll.netfx_errno(m_Dll.errno); sysDescription = m_Dll.netfx_errstring(m_Dll.errno); } catch (System.EntryPointNotFoundException) { #if NETSTANDARD15 ThrowExceptionNetStandard(); #else ThrowExceptionMono(); #endif throw; } string libDescription = m_Dll.serial_error(m_Handle); string description = string.Format("{0} ({1}; {2})", libDescription, m_Dll.errno, sysDescription); switch (managedErrNo) { case SysErrNo.NETFX_OK: case SysErrNo.NETFX_EINTR: case SysErrNo.NETFX_EAGAIN: case SysErrNo.NETFX_EWOULDBLOCK: // We throw here in any case, as the methods that call ThrowException don't // expect it to return. This would mean something that needs to be debugged // and fixed (probably in the C Interop Code). throw new InternalApplicationException(description); case SysErrNo.NETFX_EINVAL: throw new ArgumentException(description); case SysErrNo.NETFX_EACCES: throw new UnauthorizedAccessException(description); case SysErrNo.NETFX_ENOMEM: throw new OutOfMemoryException(description); case SysErrNo.NETFX_EBADF: throw new InvalidOperationException(description); case SysErrNo.NETFX_ENOSYS: throw new PlatformNotSupportedException(description); case SysErrNo.NETFX_EIO: throw new IOException(description); default: throw new InvalidOperationException(description); } }
private void ThrowException() { if (m_Dll == null) { return; } #if NETSTANDARD15 throw new Exception(string.Format("Error {0}", m_Dll.errno)); #else Mono.Unix.Native.Errno errno = Mono.Unix.Native.NativeConvert.ToErrno(m_Dll.errno); string description = m_Dll.serial_error(m_Handle); switch (errno) { case Mono.Unix.Native.Errno.EINVAL: throw new ArgumentException(description); case Mono.Unix.Native.Errno.EACCES: throw new UnauthorizedAccessException(description); default: throw new InvalidOperationException(description); } #endif }
private void ThrowException() { Mono.Unix.Native.Errno errno = Mono.Unix.Native.NativeConvert.ToErrno(m_Dll.errno); string description = m_Dll.serial_error(m_Handle); switch (errno) { case Mono.Unix.Native.Errno.EINVAL: throw new ArgumentException(description); case Mono.Unix.Native.Errno.EACCES: throw new UnauthorizedAccessException(description); default: throw new InvalidOperationException(description); } }
private unsafe void ReadWriteThread() { WaitHandle[] handles = new WaitHandle[] { m_StopRunning, m_Buffer.Serial.ReadBufferNotFull, m_Buffer.Serial.WriteBufferNotEmpty }; m_Buffer.WriteEvent += SerialBufferWriteEvent; while (m_IsRunning) { SerialReadWriteEvent rwevent = SerialReadWriteEvent.NoEvent; int handle = WaitHandle.WaitAny(handles, -1); switch (handle) { case 0: // StopRunning - Should abort m_IsRunning = false; continue; } // These are not in the switch statement to ensure that we can actually // read/write simultaneously. if (m_Buffer.Serial.ReadBufferNotFull.WaitOne(0)) { rwevent |= SerialReadWriteEvent.ReadEvent; } if (m_Buffer.Serial.WriteBufferNotEmpty.WaitOne(0)) { rwevent |= SerialReadWriteEvent.WriteEvent; } SerialReadWriteEvent result = m_Dll.serial_waitforevent(m_Handle, rwevent, 500); if (result == SerialReadWriteEvent.Error) { SerialTrace.TraceSer.TraceEvent(System.Diagnostics.TraceEventType.Error, 0, "{0}: ReadWriteThread: Error waiting for event; errno={1}; description={2}", m_Name, m_Dll.errno, m_Dll.serial_error(m_Handle)); m_IsRunning = false; continue; } else { SerialTrace.TraceSer.TraceEvent(System.Diagnostics.TraceEventType.Verbose, 0, "{0}: ReadWriteThread: serial_waitforevent({1}, {2}) == {3}", m_Name, m_Handle, rwevent, result); } if (result.HasFlag(SerialReadWriteEvent.ReadEvent)) { int rresult; fixed(byte *b = m_Buffer.Serial.ReadBuffer.Array) { byte *bo = b + m_Buffer.Serial.ReadBuffer.End; int length = m_Buffer.Serial.ReadBuffer.WriteLength; rresult = m_Dll.serial_read(m_Handle, (IntPtr)bo, length); if (rresult == -1) { SerialTrace.TraceSer.TraceEvent(System.Diagnostics.TraceEventType.Error, 0, "{0}: ReadWriteThread: Error reading data; errno={1}; description={2}", m_Name, m_Dll.errno, m_Dll.serial_error(m_Handle)); m_IsRunning = false; continue; } else { SerialTrace.TraceSer.TraceEvent(System.Diagnostics.TraceEventType.Verbose, 0, "{0}: ReadWriteThread: serial_read({1}, {2}, {3}) == {4}", m_Name, m_Handle, (IntPtr)bo, length, rresult); m_Buffer.Serial.ReadBufferProduce(rresult); } } if (rresult > 0) { OnDataReceived(this, new SerialDataReceivedEventArgs(SerialData.Chars)); } } if (result.HasFlag(SerialReadWriteEvent.WriteEvent)) { int wresult; fixed(byte *b = m_Buffer.Serial.WriteBuffer.Array) { byte *bo = b + m_Buffer.Serial.WriteBuffer.Start; int length = m_Buffer.Serial.WriteBuffer.ReadLength; wresult = m_Dll.serial_write(m_Handle, (IntPtr)bo, length); if (wresult == -1) { SerialTrace.TraceSer.TraceEvent(System.Diagnostics.TraceEventType.Error, 0, "{0}: ReadWriteThread: Error writing data; errno={1}; description={2}", m_Name, m_Dll.errno, m_Dll.serial_error(m_Handle)); m_IsRunning = false; continue; } else { SerialTrace.TraceSer.TraceEvent(System.Diagnostics.TraceEventType.Verbose, 0, "{0}: ReadWriteThread: serial_write({1}, {2}, {3}) == {4}", m_Name, m_Handle, (IntPtr)bo, length, wresult); m_Buffer.Serial.WriteBufferConsume(wresult); m_Buffer.Serial.TxEmptyEvent(); } } } } m_Buffer.WriteEvent -= SerialBufferWriteEvent; // Clear the write buffer. Anything that's still in the driver serial buffer will continue to write. The I/O was cancelled // so no need to purge the actual driver itself. m_Buffer.Serial.Purge(); // We must notify the stream that any blocking waits should abort. m_Buffer.Serial.DeviceDead(); }