-
Notifications
You must be signed in to change notification settings - Fork 42
Fix Posix Serial Driver Not Unblocking Read on Close #1166
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,10 +14,10 @@ | |
# GNU Affero General Public License for more details. | ||
|
||
# Modified by OpenC3, Inc. | ||
# All changes Copyright 2022, OpenC3, Inc. | ||
# All changes Copyright 2024, OpenC3, Inc. | ||
# All Rights Reserved | ||
# | ||
# This file may also be used under the terms of a commercial license | ||
# This file may also be used under the terms of a commercial license | ||
# if purchased from OpenC3, Inc. | ||
|
||
require 'fcntl' | ||
|
@@ -82,12 +82,17 @@ def initialize(port_name = '/dev/ttyS0', | |
tio.ospeed = baud_rate | ||
@handle.tcflush(Termios::TCIOFLUSH) | ||
@handle.tcsetattr(Termios::TCSANOW, tio) | ||
|
||
@pipe_reader, @pipe_writer = IO.pipe | ||
@readers = [@handle, @pipe_reader] | ||
end | ||
|
||
# (see SerialDriver#close) | ||
def close | ||
if @handle | ||
# Close the serial Port | ||
@pipe_writer.write('.') | ||
@pipe_writer.close | ||
@handle.close | ||
@handle = nil | ||
end | ||
|
@@ -132,9 +137,19 @@ def read | |
begin | ||
data = @handle.read_nonblock(65535) | ||
rescue Errno::EAGAIN, Errno::EWOULDBLOCK | ||
result = IO.fast_select([@handle], nil, nil, @read_timeout) | ||
if result | ||
retry | ||
begin | ||
read_ready, _ = IO.fast_select(@readers, nil, nil, @read_timeout) | ||
rescue IOError | ||
@pipe_reader.close unless @pipe_reader.closed? | ||
return "" | ||
end | ||
if read_ready | ||
if read_ready.include?(@pipe_reader) | ||
@pipe_reader.close unless @pipe_reader.closed? | ||
return "" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why would you close the pipe_reader if the read_ready says it's ready? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. pipe_reader is only ever ready, if pipe_writer was written. That means we have been closed. |
||
else | ||
retry | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This jumps back to the read_nonblock right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes |
||
end | ||
else | ||
raise Timeout::Error, "Read Timeout" | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see how closing the pipe_reader is going to help with the serial port handle
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Closing the pipe reader is just to make sure we don't leave file handles open. Return "" means that we are dead and should no longer be used going forward. IOError should only occur if the serial port has already been closed.