Opened 10 years ago
Closed 10 years ago
#7923 closed Bugs (fixed)
Multiple consecutive named_mutex::remove
Reported by: | Owned by: | Ion Gaztañaga | |
---|---|---|---|
Milestone: | To Be Determined | Component: | interprocess |
Version: | Boost 1.52.0 | Severity: | Problem |
Keywords: | named_mutex remove | Cc: |
Description
I have three named_mutex that need to be removed from system in the same inizialization function to ensure the unique existence of the named resources.
The problem appear with multiple consecutive calls to named_mutex::remove with the three named_mutex, obtaining "false" return value randomly.
I can see that named_mutex::remove use a temporal file and rename it with a name generated randomly, using process/system info data, however I obtain the same generated name in two consecutive calls and consequently remove method fails
Maybe a precision issue with time used to construct the randomly generated name.
I make a simple program to reproduce the problem. With this example you can obtain "false" sometimes in the first iteration, sometimes at iteration 11000, 23000, 90000...
#include <boost/interprocess/sync/named_mutex.hpp> #include <boost/interprocess/exceptions.hpp> #include <boost/scoped_ptr.hpp> #include <boost/lexical_cast.hpp> #include <boost/thread.hpp> using namespace std; void sharedMemoryTest() { boost::scoped_ptr<boost::interprocess::named_mutex> mutex; boost::scoped_ptr<boost::interprocess::named_mutex> mutex2; std::string mutexName = "ASYSTEM_00000_mutex"; std::string mutexName2 = "ASYSTEM_00001_mutex"; bool error = false; int count = 0; while(!error) { try { mutex.reset(new boost::interprocess::named_mutex(boost::interprocess::create_only, mutexName.c_str())); error = error || !boost::interprocess::named_mutex::remove(mutexName.c_str()); mutex2.reset(new boost::interprocess::named_mutex(boost::interprocess::create_only, mutexName2.c_str())); error = error || !boost::interprocess::named_mutex::remove(mutexName2.c_str()); ++count; } catch(boost::interprocess::interprocess_exception& ie) { cout<<"Error "<<ie.what() <<" on iteration: "<<count<<std::endl; error = true; } } cout<<"Error on iteration: "<<count<<std::endl; } int _tmain(int argc, _TCHAR* argv[]) { sharedMemoryTest(); return 0; }
Attachments (1)
Change History (8)
comment:1 by , 10 years ago
Component: | None → interprocess |
---|---|
Owner: | set to |
comment:2 by , 10 years ago
comment:3 by , 10 years ago
Thanks for the report, the test case and the time precission problem hint. I expecto to have some time to investigate this the following days.
@kamesh:I don't think the cygwin issue is the same as the one pointed by the reporter.
comment:4 by , 10 years ago
Please, can you try with the attached modified file? It includes a new unlink implementation with the following changes:
- A static atomically incremented count is added to each rename operation.
- Memory allocation is minimized querying the win kernel instead of allocatin a 32K buffer.
- Delete on close flag is applied only if renaming was successful.
comment:5 by , 10 years ago
I have tested the attached file for many hours and everything seems to work fine, however I think that it could have some problem if two parallel processes(both started at the same time) try to remove two different named resources at the same time, the static counter will have the same value for both processes. Maybe some type of process identifier is needed for this case too, like PID.
what do you think? Anyway, nice work!
comment:6 by , 10 years ago
I guess adding the current process id to the name could do the trick. See attached file for proposed solution.
I was able to re-produce the issue on cygwin. The "0" iteration fails with message "Error File exists on iteration: 0". Now the problem is there is no directory called /tmp/boost_interprocess , but still it fails and $TMP=/tmp