Sign in to follow this  

Mutex under Win32 (and std::vector)

This topic is 4059 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Mental block time: I have 2 classes and a struct: Mutex_Group - manages a group of mutexes allowing them to be easily refered to. Mutex - a mutex object that know about acquire / release and its own name mutex_X - a struct containing a Mutex and a direction (currently unused) When I create a mutex using Mutex.create(<name>) it creates a new mutex successfully (CreateMutex(...) as per win32), this mutex can then be successfully locked, unlocked etc. However if I create a temp object:
mutex_X temp;
temp.direction = 0;
temp.mutex.create(<name>);
list_of_mutexes.push_back(temp);
When I subsequently iterate through the vector the pushed back temp can be found by name, however the handle of the mutex, despite pointing to the same location in memory is now invalid, even though I had not attempted to kill it. Any thoughts? Do vectors do strange things with pointers?

Share this post


Link to post
Share on other sites
You probably want the temp mutex object to close the handle when it destructs. This is appropriate behavior. What you're probably missing is when the temp mutex object is copied. You need to add a reference for the new object, so that when the temp object closes the handle, the new object still refers to the mutex and it doesn't get closed. In this case, I believe DuplicateHandle() is what you need, and you need this for both the copy constructor and the assignment operator.


class Mutex
{
public:
//Main Constructor
Mutex(const std::string& Name);

//Copy Constructor
Mutex(const Mutex& mutex);

//Assignment Operator
Mutex& operator = (const Mutex& mutex);

//Destructor
~Mutex();

private:
void Destroy();

HANDLE mhMutex;
};

Mutex::Mutex(const std::string& Name) : mhMutex(NULL)
{
mhMutex = CreateMutex(NULL, FALSE, Name.c_str());
}

Mutex::Mutex(const Mutex& mutex) : mhMutex(NULL)
{
*this = mutex;
}

Mutex& Mutex::operator = (const Mutex& mutex)
{
if (this != &mutex)
{
Destroy();

DuplicateHandle(GetCurrentProcess(), mutex.mhMutex, GetCurrentProcess(), &mhMutex, 0, FALSE, DUPLICATE_SAME_ACCESS);
}
}

Mutex::~Mutex()
{
Destroy();
}

void Mutex::Destroy()
{
if (mhMutex != NULL)
{
CloseHandle(mhMutex);
mhMutex = NULL;
}
}

Share this post


Link to post
Share on other sites
I forgot the "return *this;" in operator =, you added that in correctly.

As for the const conversion, I don't know what to say. I just tested it in VC6 and VC8, and both compiled fine. What compiler do you have? Also, what is HANDLE #define-d or typedef-ed as? On my machine with both VC6 and VC8 it is typedef-ed as a void*; apparently the compilers don't mind ignoring const-correctness on void pointers?

Share this post


Link to post
Share on other sites

This topic is 4059 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this