Modify

Ticket #7923 (closed Bugs: fixed)

Opened 15 months ago

Last modified 15 months ago

Multiple consecutive named_mutex::remove

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

win32_api.hpp Download (72.8 KB) - added by igaztanaga 15 months ago.
New try adding process id to the random name

Change History

comment:1 Changed 15 months ago by cbarrioy <cbarrioy@…>

  • Owner set to igaztanaga
  • Component changed from None to interprocess

comment:2 Changed 15 months ago by kamesh <kameshdeepakbetablet@…>

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 Changed 15 months ago by igaztanaga

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 Changed 15 months ago by igaztanaga

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 Changed 15 months ago by cbarrioy <cbarrioy@…>

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!

Changed 15 months ago by igaztanaga

New try adding process id to the random name

comment:6 Changed 15 months ago by igaztanaga

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

comment:7 Changed 15 months ago by igaztanaga

  • Status changed from new to closed
  • Resolution set to fixed

(In [82797]) Fixes #7923

View

Add a comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
The resolution will be deleted. Next status will be 'reopened'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.