Opened 10 years ago

Closed 10 years ago

#7923 closed Bugs (fixed)

Multiple consecutive named_mutex::remove

Reported by: cbarrioy <cbarrioy@…> 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)

win32_api.hpp (72.8 KB ) - added by Ion Gaztañaga 10 years ago.
New try adding process id to the random name

Download all attachments as: .zip

Change History (8)

comment:1 by cbarrioy <cbarrioy@…>, 10 years ago

Component: Noneinterprocess
Owner: set to Ion Gaztañaga

comment:2 by kamesh <kameshdeepakbetablet@…>, 10 years ago

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

comment:3 by Ion Gaztañaga, 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 Ion Gaztañaga, 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 cbarrioy <cbarrioy@…>, 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!

by Ion Gaztañaga, 10 years ago

Attachment: win32_api.hpp added

New try adding process id to the random name

comment:6 by Ion Gaztañaga, 10 years ago

I guess adding the current process id to the name could do the trick. See attached file for proposed solution.

comment:7 by Ion Gaztañaga, 10 years ago

Resolution: fixed
Status: newclosed

(In [82797]) Fixes #7923

Note: See TracTickets for help on using tickets.