A very small port.readTimeout may lead to a negative timeout if the
elapsed time between:
deadline = time.Now().Add(port.readTimeout)
and
timeout = time.Until(deadline)
is longer than port.readTimeout.
Fix#134
See https://stackoverflow.com/a/34945814/1655275
> pselect signals that file descriptor is ready and
> ioctl(fd, FIONREAD, &len) returns zero len.
Failure to detect this condition has been revealed by
the testsuite:
=== RUN TestDisconnectingPortDetection
2017/07/27 13:56:37 PR - Connecting to Probe
2017/07/27 13:56:37 > Searching for port 2341:8037
2017/07/27 13:56:37 Detected port '/dev/ttyACM0' 2341:8037
2017/07/27 13:56:37 Using '/dev/ttyACM0'
2017/07/27 13:56:37 Starting test (timeout 20s)
2017/07/27 13:56:37 PR - Turn ON target
2017/07/27 13:56:37 TR - Connecting to Target
2017/07/27 13:56:37 > Searching for port 2341:8036
2017/07/27 13:56:37 Detected port '/dev/ttyACM0' 2341:8037
[...cut...]
2017/07/27 13:56:46 > Searching for port 2341:8036
2017/07/27 13:56:46 Detected port '/dev/ttyACM0' 2341:8037
2017/07/27 13:56:46 Detected port '/dev/ttyACM1' 2341:8036
2017/07/27 13:56:46 Using '/dev/ttyACM1'
2017/07/27 13:56:46 T2 - Make a Read call
2017/07/27 13:56:46 T1 - Delay 200ms before disconnecting target
2017/07/27 13:56:46 T1 - Disconnect target
2017/07/27 13:56:46 PR - Turn OFF target
2017/07/27 13:56:46 T2 - Read returned: n=0 err=nil
--- FAIL: TestDisconnectingPortDetection (9.18s)
Error Trace: serial_test.go:100
Error: An error is expected but got nil. %s
Messages: Read returned no errors
this commit fix the problem above.
The only way to interrupt running Read() method of io.Reader is to call
Close from another goroutine. What happens is that go runtime builtin
race detector complains about unsynchronised access to "opened" member,
which is set in Close and checked in Read.
It doesn't seem to be dangerous, but 1) you never know, and 2) it makes
your life more difficult when you need to debug some other data races in
a complex project that uses serial.
Proposed fix changes simple access to "opened" to atomic operations.
It's also supposed to fix#38
This allows the last (most significant) bit to be set without
overflow errors. The error becomes visible after adding the
CRTSCTS constant on linux/386:
const tcCRTSCTS uint = 0x80000000