Comments (12)
Your suggestion unfortunately leads to the "resource temporarily unavailable" error when using bufio.ReadString('\n')
, but in general, the fact that Read() cannot be interrupted is very bad.
from go-serial.
That's the EAGAIN error which should be caught by poll, and it shouldn't matter if you're using bufio.ReadString
or just plain Read
: https://github.com/golang/go/blob/release-branch.go1.12/src/internal/poll/fd_unix.go#L168
What operating system are you using? Maybe the runtime failed to initialize polling on the file (https://github.com/golang/go/blob/release-branch.go1.12/src/os/file_unix.go#L156), but there's no easy way to detect that.
from go-serial.
@nkovacs The app I'm writing is for Linux/arm (Raspberry Pi).
I wasn't aware that Raspbian contains Go 1.7.4 (almost 3 years old), so I updated to Go 1.12.4 and there I get the expected behavior when I add syscall.SetNonblock(int(file.Fd()), true)
into my own code. Thanks!
from go-serial.
The poller was implemented for files in Go 1.9. One option is to use build tags and then use blocking mode in Go <1.9, but then Close won't work and will probably lead to a race condition as well. To make it work properly, you would have to wrap Read and Close, put a mutex in them, use non-blocking mode, vmin=0 and vtime>0, and if you get an EAGAIN, repeat the read (while letting Close interrupt it). This would waste cpu time of course, and Close would hang for up to vtime.
There's also the issue that we're assuming polling will always be available. If the poller fails to initialize, the file is not put into non-blocking mode (https://github.com/golang/go/blob/release-branch.go1.12/src/os/file_unix.go#L156), but since this package calls os.OpenFile
with O_NONBLOCK
, the file will be in non-blocking mode anyway, so there's no way to detect whether the poller init succeeded.
from go-serial.
@nkovacs Thank you for sharing the solution
from go-serial.
I've forked at GitHub.com/chmorgan/go-serial2 btw
I'm seeing this issue on my test target. Should there be an option to be blocking vs. non-blocking? I'm not super familiar with the poller support. It seems super helpful to support non-blocking reads as well, we can't expect data to be returned all of the time.
from go-serial.
From the perspective of your program, the read will still be blocking (with Go 1.9+), because the poller will handle all that (while the file is actually in non-blocking mode). That's the ideal situation, and there should be no reason to use blocking mode.
The main issue is that this package calls os.OpenFile
with syscall.O_NONBLOCK
, which unfortunately does two, separate things: it prevents the open from blocking for a long time and it sets the non-blocking flag. And because the non-blocking flag is set, this package cannot detect if Go's poller was successfully enabled for the file by checking if OpenFile
itself set the flag.
You could call OpenFile
without syscall.O_NONBLOCK
, and let stdlib handle it, then check whether the non-blocking flag is set on the file (indicating the poller successfully initialized on the file), and restore it if needed after calling Fd
(because Fd
sets it to blocking mode). If the poller failed, then there's not much that can be done. You could implement a workaround like I described in my previous comment, or you could just deal with Read not being interruptible with Close (if you don't need to Close during the lifetime of your program, you won't get goroutine leaks, for example).
Unfortunately, calling OpenFile
without syscall.O_NONBLOCK
might lead to the open blocking for a long time, and I don't know under which circumstances it would happen. So another option is to always put the file into non-blocking mode (like my fork), and wrap Read/Write and handle EAGAIN yourself, in case the poller failed (Go <1.9 or unsupported architecture or whatever other reason).
from go-serial.
@nkovacs you'd recommend I pull in nkovacs@a726144 and nkovacs@73fc76f then?
In terms of usage should we update the example to make use of the poller? I'm not familiar with that module but it looks like great functionality to have when working with fds.
from go-serial.
@nkovacs and I think its ok to assume Go >1.9 at this point, at least I'm not excited about adding support for such old versions at the moment. Someone else is welcome to though :-)
from go-serial.
Yes, I think using non-blocking mode with the poller is the way to go.
You can assume Go > 1.9, the issue is that the poller might not initialize in certain cases, but I don't know how common that is. I haven't had any problems on a Raspberry Pi.
from go-serial.
Ahh very good!
I’ll merge those changes this afternoon. I’m collecting all of the good fixes to the library so they are in one maintained repo. If you have any other suggestions I’d love to hear them.
from go-serial.
Thanks @nkovacs, changes merged into the go-serial2 fork, https://github.com/chmorgan/go-serial2
from go-serial.
Related Issues (20)
- How to set ioctl flags?
- Windows Timeout in Milliseconds HOT 1
- mipsle error
- mips error: serial.Open: SYS_IOCTL: inappropriate ioctl for device HOT 1
- windows pipe serial problem
- Feature Request: Send BREAK Signal HOT 1
- Help with preventing program from panicking out if no USB is found HOT 1
- 100% CPU on darwin
- On OpenWRT : error opening port:%!(EXTRA *os.SyscallError=SYS_IOCTL: inappropriate ioctl for device) HOT 17
- Linux and communication errors HOT 1
- Flush buffer HOT 3
- function read alway error on macOS
- How can I check CTS status?
- Linux 2 stop bits HOT 3
- Error opening serial port: SYS_IOCTL: inappropriate ioctl for device HOT 1
- Read() to buffer for specific time and then return
- Windows hardware flow control (DTR/CTS) HOT 2
- Please release v1.0.0 HOT 1
- Unable to properly reopen serial device after it disappears
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from go-serial.