-
-
Notifications
You must be signed in to change notification settings - Fork 30.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
termios.tcdrain hangs on MacOS #97001
Comments
This could be a difference between Linux and macOS, possibly with a different definition of what 'transmitted to the terminal' means. The termios library is a thin wrapper around a system API and inherits its behaviour from the system. The implementation of termios.tcdrain does not release the GIL, which might be related: main thread is waiting for the tcdrain(3), while the secondary thread doesn't make progress because it cannot acquire the GIL. I've done an experiment with a patched version of the termios extension that releases the GIL during calls to tcdrain and that fixes the issue for me. I'll see if I can create a PR that releases the GIL for all functions in the termios extension during the weekend (available time being the main challenge). Note that such a bug fix won't be backported to 3.9, that version is in security fix mode and this is not a security issue. |
@ronaldoussoren sounds great! This one has been puzzling me for ages, so I'm really pleased to hear you made some progress with it. Even if it's not fixed for a while, people can still see this if they come across it. One thing still puzzles me: when should we use |
I have no idea to be honest, I barely use ptys myself and have never used termios. The Linux manpage suggests that the API waits until all data in the kernel buffers have been send. That's probably more noticeable when using a real TTY device. |
Without releasing the GIL calls to termios APIs might block the entire interpreter.
Without releasing the GIL calls to termios APIs might block the entire interpreter. (cherry picked from commit 959ba45) Co-authored-by: Ronald Oussoren <ronaldoussoren@mac.com>
This is viable since [^1]. There are some minor differences to note: - SensorReader._cmd uses Serial.flush(), but this shouldn't be an issue in newer versions of Python [^2]. - SensorReader._cmd reads all available input into the buffer and only calls Serial.reset after a "_read", or if the buffer turns out to be invalid. This is less robust than just calling Serial.reset before each command, but it seems to work. - SensorReader.open does an additional check to verify the sensor. [^1]: avaldebe/PyPMS#33 [^2]: python/cpython#97001
This is viable since [^1]. There are some minor differences to note: - SensorReader._cmd uses Serial.flush(), but this shouldn't be an issue in newer versions of Python [^2]. - SensorReader._cmd reads all available input into the buffer and only calls Serial.reset after a "_read", or if the buffer turns out to be invalid. This is less robust than just calling Serial.reset before each command, but it seems to work. - SensorReader.open does an additional check to verify the sensor. [^1]: avaldebe/PyPMS#33 [^2]: python/cpython#97001
On MacOS, `termiois.tcdrain` and `termios.tcsetattr(tty_fd, termios.TCSADRAIN, attrs)` hang up until 3.9.8. See python/cpython#97001
On MacOS, `termiois.tcdrain` and `termios.tcsetattr(tty_fd, termios.TCSADRAIN, attrs)` hang up until 3.9.8. See python/cpython#97001
On MacOS, `termiois.tcdrain` and `termios.tcsetattr(tty_fd, termios.TCSADRAIN, attrs)` hang up until 3.9.8. See python/cpython#97001
On MacOS, `termiois.tcdrain` and `termios.tcsetattr(tty_fd, termios.TCSADRAIN, attrs)` hang up until 3.9.8. See python/cpython#97001
Bug report
The following Python program hangs forever on MacOS, but does not hang on Linux:
Reading the data in a thread should mean there's absolutely no reason for
tcdrain
to hang. The docs say it only waits for the data to be "transmitted", which sounds different to "read". And there's the fact this works on Linux.Any single-threaded call to
tcdrain()
usingtty_fd
also hangs, even if theos.write
line is removed i.e. there's nothing fortcdrain
to wait for write. When I try with a real file descriptor or a pipe I get an error:'Inappropriate ioctl for device'
- it's unclear if it's the combination oftcdrain
andopenpty
or justtcdrain
that's causing the issue.When I sample the process using the MacOS Activity Monitor I get the following at the bottom of the call graph for the main thread (unchanging) and the secondary "read" thread (bottommost lines vary per sample) respectively:
The questions I'm struggling to answer:
tcdrain
in this scenario?Your environment
I've also tested on MacOS with an Intel CPU and another developer has tested on Linux (to prove it terminates there). Originally I thought the issue might be an OS issue and posted in the Apple dev forum about it.
Linked PRs
The text was updated successfully, but these errors were encountered: