Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Different mutex handle even though it was created already?

Different mutex handle even though it was created already?

Scheduled Pinned Locked Moved C / C++ / MFC
databasehelpquestion
4 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Souldrift
    wrote on last edited by
    #1

    Hi again, I got another one. This time regarding mutexes. I am using the following locking routine:

    HANDLE Thread::Lock( const char* name )
    {
    // first convert const char* to LPCWSTR -> for CreateMutex()
    wchar_t buffer[FILENAME_MAX];
    mbstowcs_s( NULL, buffer, FILENAME_MAX, name, FILENAME_MAX-1 );

    HANDLE hMutex = CreateMutex(NULL, 
    			FALSE,    
    			buffer); 
    
    if (!hMutex)
    {
          return NULL;
    }
     
    if (GetLastError() == ERROR\_ALREADY\_EXISTS)
    {
    	// not really important, just for debugging
    }
    
    WaitForSingleObject(hMutex, INFINITE);
    
    return hMutex;
    

    }

    Now I found out that my locking mechanism does not work properly. And the thing is this: Thread 1 calls the Lock()-function. A Mutex is created and everything is fine. While it is locked the same thread actually (which is an error, but that´s how I found out) calls the Lock()-function again with the same name parameter. CreateMutex returns a DIFFERENT handle this time but the GetLastError query returns ERROR_ALREADY_EXISTS. But since it is a different handle WaitForSingleObject() grants access again, before the first Unlock() call occured. So how does this work. Shouldn´t I get the same handle everytime I call CreatMutex() with the same parameters? Otherwise I get a new handle everytime and nothing is really ever locked. Thanks again. Souldrift

    L J N 3 Replies Last reply
    0
    • S Souldrift

      Hi again, I got another one. This time regarding mutexes. I am using the following locking routine:

      HANDLE Thread::Lock( const char* name )
      {
      // first convert const char* to LPCWSTR -> for CreateMutex()
      wchar_t buffer[FILENAME_MAX];
      mbstowcs_s( NULL, buffer, FILENAME_MAX, name, FILENAME_MAX-1 );

      HANDLE hMutex = CreateMutex(NULL, 
      			FALSE,    
      			buffer); 
      
      if (!hMutex)
      {
            return NULL;
      }
       
      if (GetLastError() == ERROR\_ALREADY\_EXISTS)
      {
      	// not really important, just for debugging
      }
      
      WaitForSingleObject(hMutex, INFINITE);
      
      return hMutex;
      

      }

      Now I found out that my locking mechanism does not work properly. And the thing is this: Thread 1 calls the Lock()-function. A Mutex is created and everything is fine. While it is locked the same thread actually (which is an error, but that´s how I found out) calls the Lock()-function again with the same name parameter. CreateMutex returns a DIFFERENT handle this time but the GetLastError query returns ERROR_ALREADY_EXISTS. But since it is a different handle WaitForSingleObject() grants access again, before the first Unlock() call occured. So how does this work. Shouldn´t I get the same handle everytime I call CreatMutex() with the same parameters? Otherwise I get a new handle everytime and nothing is really ever locked. Thanks again. Souldrift

      L Offline
      L Offline
      led mike
      wrote on last edited by
      #2

      Souldrift wrote:

      But since it is a different handle WaitForSingleObject() grants access again, before the first Unlock() call occured.

      Or since the handle is to the same mutex and the thread already has a lock on it the wait call does not block. ;) Not all synchronization objects work the same, particularly when you lock them multiple times in the same thread. There are different object because they are designed to work differently. Also I seriously recommend one obtains a good book on multi-threading if one intends to learn the subject.

      1 Reply Last reply
      0
      • S Souldrift

        Hi again, I got another one. This time regarding mutexes. I am using the following locking routine:

        HANDLE Thread::Lock( const char* name )
        {
        // first convert const char* to LPCWSTR -> for CreateMutex()
        wchar_t buffer[FILENAME_MAX];
        mbstowcs_s( NULL, buffer, FILENAME_MAX, name, FILENAME_MAX-1 );

        HANDLE hMutex = CreateMutex(NULL, 
        			FALSE,    
        			buffer); 
        
        if (!hMutex)
        {
              return NULL;
        }
         
        if (GetLastError() == ERROR\_ALREADY\_EXISTS)
        {
        	// not really important, just for debugging
        }
        
        WaitForSingleObject(hMutex, INFINITE);
        
        return hMutex;
        

        }

        Now I found out that my locking mechanism does not work properly. And the thing is this: Thread 1 calls the Lock()-function. A Mutex is created and everything is fine. While it is locked the same thread actually (which is an error, but that´s how I found out) calls the Lock()-function again with the same name parameter. CreateMutex returns a DIFFERENT handle this time but the GetLastError query returns ERROR_ALREADY_EXISTS. But since it is a different handle WaitForSingleObject() grants access again, before the first Unlock() call occured. So how does this work. Shouldn´t I get the same handle everytime I call CreatMutex() with the same parameters? Otherwise I get a new handle everytime and nothing is really ever locked. Thanks again. Souldrift

        J Offline
        J Offline
        Joe Woodbury
        wrote on last edited by
        #3

        The main problem here is that you are returning a local variable. In addition, every time your function is called, it creates a new mutex handle (referencing the same mutex.) You are leaking handles like crazy. To properly use a mutex you need to first create it (and you don't need to do a conversion from a char to wide string--just call CreateMutexA.) The locking is done separately. BTW, only use mutexes if you are synchronizing between processes or you have to have multiple waits on a lock, otherwise use critical sections.

        Anyone who thinks he has a better idea of what's good for people than people do is a swine. - P.J. O'Rourke

        1 Reply Last reply
        0
        • S Souldrift

          Hi again, I got another one. This time regarding mutexes. I am using the following locking routine:

          HANDLE Thread::Lock( const char* name )
          {
          // first convert const char* to LPCWSTR -> for CreateMutex()
          wchar_t buffer[FILENAME_MAX];
          mbstowcs_s( NULL, buffer, FILENAME_MAX, name, FILENAME_MAX-1 );

          HANDLE hMutex = CreateMutex(NULL, 
          			FALSE,    
          			buffer); 
          
          if (!hMutex)
          {
                return NULL;
          }
           
          if (GetLastError() == ERROR\_ALREADY\_EXISTS)
          {
          	// not really important, just for debugging
          }
          
          WaitForSingleObject(hMutex, INFINITE);
          
          return hMutex;
          

          }

          Now I found out that my locking mechanism does not work properly. And the thing is this: Thread 1 calls the Lock()-function. A Mutex is created and everything is fine. While it is locked the same thread actually (which is an error, but that´s how I found out) calls the Lock()-function again with the same name parameter. CreateMutex returns a DIFFERENT handle this time but the GetLastError query returns ERROR_ALREADY_EXISTS. But since it is a different handle WaitForSingleObject() grants access again, before the first Unlock() call occured. So how does this work. Shouldn´t I get the same handle everytime I call CreatMutex() with the same parameters? Otherwise I get a new handle everytime and nothing is really ever locked. Thanks again. Souldrift

          N Offline
          N Offline
          norish
          wrote on last edited by
          #4

          It is not important the handle value of CreateMutex are different or same becuase the handle will never be compared its value but only be used with WaitForXXXXXX function. Others wrote that mutex can not lock with the same thread and this implementation may cause handle leaks. I suggest another locking mechanism using InterlockedIncrement and InterlockedDecrement like;

          extern long some_locker = 0;

          bool lock(long& name) {
          if (1 == InterlockedIncrement(&name))
          return true;
          InterlockedDecrement(&name);
          return false;
          }

          void unlock(long& name) {
          InterlockedDecremtn(&name);
          }

          Note that this implementation dose not wait, so you must write wait loop for this for example;

          while (!lock(some_locker)) Sleep(10);
          // ... some task
          unlock(some_locker);

          This may not be quite your requirement, but one way of some practical technique.

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups