-
Notifications
You must be signed in to change notification settings - Fork 765
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
[14385] Avoid data race on UDPChannelResource #2646
Conversation
Signed-off-by: Miguel Company <MiguelCompany@eprosima.com>
Signed-off-by: Miguel Company <MiguelCompany@eprosima.com>
Signed-off-by: Miguel Company <MiguelCompany@eprosima.com>
Signed-off-by: Miguel Company <MiguelCompany@eprosima.com>
asio::error_code ec; | ||
socket()->close(ec); |
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.
Why not use close() instead? We are not performing any error checking here.
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.
Because close()
can throw, and we are inside a destructor 😨
In |
The trick is using |
Is that not also a data race then as ASIO document it to be thread unsafe? |
The docs do not explicitly mention |
It may or may not be safe for the tested platform and version, but from what I read it's explicitly unsafe as socket is documented as thread unsafe with the exception of a few enumerated operations. The limitations of the synchronous interface is well known and most often the recommendation seems to be to use the async version to support cancellation or timeouts (see e.g. https://github.com/boostorg/asio/blob/develop/example/cpp11/timeouts/blocking_udp_client.cpp). This may come with an performance penalty though. Excerpt from https://www.boost.org/doc/libs/1_76_0/doc/html/boost_asio/reference/ip__udp/socket.html:
|
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.
LGTM
@xbreak I opened chriskohlhoff/asio#1046 so the ASIO maintainers tell us whether the In the meantime, we are going to merge and backport this PR, since it solves the data race on the supported platforms (at least according to the sanitizers. |
@Mergifyio backport 2.5.x 2.3.x 2.1.x |
* Refs #14367. Closing socket on UDPChannelResource destructor. Signed-off-by: Miguel Company <MiguelCompany@eprosima.com> * Refs #14367. Do not close socket on UDPChannelResource::release. Signed-off-by: Miguel Company <MiguelCompany@eprosima.com> * Refs #14367. Bonus: do not call socket->release() on TCP disconnect. Signed-off-by: Miguel Company <MiguelCompany@eprosima.com> * Refs #14367. Linters. Signed-off-by: Miguel Company <MiguelCompany@eprosima.com> (cherry picked from commit 184e982)
* Refs #14367. Closing socket on UDPChannelResource destructor. Signed-off-by: Miguel Company <MiguelCompany@eprosima.com> * Refs #14367. Do not close socket on UDPChannelResource::release. Signed-off-by: Miguel Company <MiguelCompany@eprosima.com> * Refs #14367. Bonus: do not call socket->release() on TCP disconnect. Signed-off-by: Miguel Company <MiguelCompany@eprosima.com> * Refs #14367. Linters. Signed-off-by: Miguel Company <MiguelCompany@eprosima.com> (cherry picked from commit 184e982)
* Refs #14367. Closing socket on UDPChannelResource destructor. Signed-off-by: Miguel Company <MiguelCompany@eprosima.com> * Refs #14367. Do not close socket on UDPChannelResource::release. Signed-off-by: Miguel Company <MiguelCompany@eprosima.com> * Refs #14367. Bonus: do not call socket->release() on TCP disconnect. Signed-off-by: Miguel Company <MiguelCompany@eprosima.com> * Refs #14367. Linters. Signed-off-by: Miguel Company <MiguelCompany@eprosima.com> (cherry picked from commit 184e982)
✅ Backports have been created
|
Description
This PR moves the close operation over the UDP socket from
UDPChannelResource::release
to the destructor ofUDPChannelResource
.As the destructor is called after calling
UDPChannelResource::clear
, the receiving thread would have been already joined, so the thread sanitizer should not complain.As a bonus, I introduced a small change on
TCPChannelResourceBasic::disconnect
that I think is responsible for leaving TCP sockets on a FIN_2 state sometimes.@Mergifyio backport 2.5.x 2.3.x 2.1.x
Contributor Checklist
versions.md
file (if applicable).Reviewer Checklist