-
Notifications
You must be signed in to change notification settings - Fork 914
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
Unsafe Double-checked Locking #770
Comments
Can you please describe in more detail why you think this code is unsafe. To me it looks like that the outer condition is checked atomically. And if it is not yet initialized the inner check and creation of the singleton is properly protected by the mutex. |
I have little experience in C++, however, from my brief research, it is vulnerable in the same way Java code is. Consider the assignment statement. g_topic_manager = boost::make_shared<TopicManager>(); There are three things happening here:
Compilers are not forced to follow this ordering. This means that step 3 can occur before step 2, and here lies the problem.
If this does not make much sense, I will leave you with my references:
This is an issue only if multiple threads try to access the topic manager for the first time, at the same time. I am not familiar enough with the source code to know if this is possible (but I imagine it is, hence the mutex in the first place). |
Very interesting. Thanks for the detailed links. I will change the label to In the upcoming ROS Kinetic release we require a C++11 compiler. Probably the best solution is to change the code in a to be made kinetic-devel branch to use the local |
Thanks, I am glad I could help. |
Please see #776 for the proposed change in Kinetic. |
I realize this is being compiled with C++03, and, thus, the workarounds are not possible, as they require C++11. Here is the faulty code, in
roscpp/src/libros/topic_manager.cpp
(line 56).Double-checked locking as is done here is potentially unsafe; it is possible that a thread may read
g_topic_manager
before it is fully initialized. Of course, it depends on whether there are multiple threads contesting the access (which I am not sure about).Is lazy initialization really necessary here?
The text was updated successfully, but these errors were encountered: