-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
zmq::condition_variable_t needs cleanup #3404
Comments
Agree, if std:: conditional_variable is used we should use all std primitives for synchronization. |
@bluca This is not Windows-specific, it applies to all C++11-enabled platforms. |
An sorry, got tricked by the ifdef |
This is the bit that makes me suspicious:
What appears to be happening is that the method is using a local variable for the condition variable, but the order of lock/unlocks looks wrong to me. I would generally expect to see the lock/unlocks nested, like so, if the purpose of the local (outer) mutex is to protect the inner mutex:
Instead, the locks "cross" each other, so there is a possibility that the inner mutex can be locked by another thread between step 3 and step 4:
Maybe this is deliberate? But again it made me suspicious because it doesn't fit the usual pattern. Frankly, it's also not at all clear to me what the code intends, and apparently I'm not the only one who finds it confusing. P.S. If the locks/unlocks are re-ordered, there would be no need to explicitly unlock the outer mutex -- RAII would take care of it. |
At least I'm not the only one ;-) Just a thought -- but at some point would it be preferable to break out the implementation into separate header files (e.g., condition_variable_vxworks.hpp etc.) to make it more readable? |
Yes, the ifdef is confusing, I think I mistook it somehow as well, either what I wrote in the issue is not correct, or my later assumption is not. But I don't see a reason why the C++11 construct should only be used on Windows. The conditions should be cleaned up to be less confusing as well. With respect to splitting into multiple files: I am not sure if this should be done, it has benefits but also drawbacks (e.g. when changes in the API are made, it is harder to see the different places where changes must be done, for other platforms that the person doing the change has not in focus). But if it is done, it should be done consistently throughout libzmq IMO. |
A couple of points:
I'm happy to submit a PR for this, although it's simply a matter of deleting the existing checks.
|
iirc if you force the compiler to use a version of the standar, then all the definitions will respect that |
That's true, but what I'm referring to is the way the standard is set:
|
right, try to pass the CXXFLAGS manually and see if cmake appends or prefixes - if the former, then it should just work as the last argument wins |
One thing that will actually make the conditional variable code easier is to merge it with mutex code. So we can merge the code of the conditional variable into the mutex class. Create both of them on the constructor and providing the conditional variable method on the mutex as well. |
I think if there are multiple implementations that can be used in an environment, the choice should be made during configuration (e.g. CMake call, configure call), not "automatically" during compilation. A reasonable default should be chosen (e.g. use the C++11 implementation if available), but this should be overridable by the user. This does not only apply to condition_variable_t, but also to several other aspects. If this is done systematically, I think the ifdef conditions will get much simple throughout the source code. I have had this thought for quite some time, but did not find time to do this. But for now, I can start with this particular issue. |
In C# Mutex and Conditional Variable is actually the same class, I think we can benefit from that as well in libzmq. https://docs.microsoft.com/en-us/dotnet/api/system.threading.monitor?view=netframework-4.7.2 |
Quite agree with @sigiesec on this. A good model is ENABLE_DRAFTS -- this is defaulted based on the presence or absence of a .git directory, but can be overridden on command line. While Luca's suggestion likely works (haven't tried it though), it's a bit "opaque" and Simon's approach is, I think, cleaner. |
Having flags is fine, I was just suggesting a way to try it immediately without code changes |
zmq::condition_variable_t needs some cleanup:
As pointed out in #3373 (comment), the current implementation in the second case seems to have a race condition related to handling the two mutexes. This would be automatically resolved by the improvements suggested above.
The text was updated successfully, but these errors were encountered: