Mutex under Win32 (and std::vector)

Started by
5 comments, last by Lord Darkblade 17 years, 5 months ago
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?
Advertisement
Ok ignore the above post, I was too cunning for my own good.

When the temp object was deleted it automatically closed the mutex handle... idiot dev. Thanks
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;  }}
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke
When I implement the Duplicatehandle line as you have it I get a C2662 error: Cannot convert from const class x to class x.

const_cast<x> () does not seem to want to remove this constness either, any hints?
What should the = operator return? I have it returning *this for now, it seems to quieten the compiler, off to google.
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?
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke
The original function returned an unsigned long*, changed that to a HANDLE and it doesn't mind here either.

Thanks

This topic is closed to new replies.

Advertisement