CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 13 of 13
  1. #1
    Join Date
    Jul 2010
    Posts
    88

    Question Mutex never works

    Why does this code not deadlock when entering the same critical section 2 times in a row?

    Code:
    #define _WIN32_WINNT 0x0403
    #include <Windows.h>
    #include <stdio.h>
    #include <tchar.h>
    
    CRITICAL_SECTION Mutex;
    
    int _tmain(int argc, _TCHAR* argv[]) {
    	// Initialize the mutex
    	if (!InitializeCriticalSectionAndSpinCount(&Mutex,0x00000001)) {
    		wprintf(L"Could not initialize the mutex.");
    	}
    	
    	EnterCriticalSection(&Mutex);
    		EnterCriticalSection(&Mutex);
    			wprintf(L"This should be impossible to reach because of deadlock.");
    		LeaveCriticalSection(&Mutex);
    	LeaveCriticalSection(&Mutex);
    	
    	// Release the mutex
    	DeleteCriticalSection(&Mutex);
    	
    	return 0;
    }

  2. #2
    Join Date
    Oct 2006
    Location
    Sweden
    Posts
    3,654

    Re: Mutex never works

    Because multiple calls from the same thread doesn't block. It's all described here http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx

    Always read the documentation!
    Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible, you are, by
    definition, not smart enough to debug it.
    - Brian W. Kernighan

    To enhance your chance's of getting an answer be sure to read
    http://www.codeguru.com/forum/announ...nouncementid=6
    and http://www.codeguru.com/forum/showthread.php?t=366302 before posting

    Refresh your memory on formatting tags here
    http://www.codeguru.com/forum/misc.php?do=bbcode

    Get your free MS compiler here
    https://visualstudio.microsoft.com/vs

  3. #3
    Join Date
    Jul 2010
    Posts
    88

    Re: Mutex never works

    Multiple threads does not work either when I call my C++ component from Visual Basic 6. If Visual Basic make all calls from the same thread then this type of mutex is useless.
    Last edited by Dawoodoz; April 13th, 2012 at 05:16 PM.

  4. #4
    Join Date
    Oct 2006
    Location
    Sweden
    Posts
    3,654

    Re: Mutex never works

    Well, all I can say is that you probably do or get something wrong. You don't expect yourself to be the very first person that find a bug in EnterCriticalSection do you?
    Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible, you are, by
    definition, not smart enough to debug it.
    - Brian W. Kernighan

    To enhance your chance's of getting an answer be sure to read
    http://www.codeguru.com/forum/announ...nouncementid=6
    and http://www.codeguru.com/forum/showthread.php?t=366302 before posting

    Refresh your memory on formatting tags here
    http://www.codeguru.com/forum/misc.php?do=bbcode

    Get your free MS compiler here
    https://visualstudio.microsoft.com/vs

  5. #5
    Join Date
    Jul 2010
    Posts
    88

    Re: Mutex never works

    ok, thanks for your time anyway.

  6. #6
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,633

    Re: Mutex never works

    Quote Originally Posted by Dawoodoz View Post
    Multiple threads does not work either when I call my C++ component from Visual Basic 6. If Visual Basic make all calls from the same thread then this type of mutex is useless.
    So, what is the problem here? Multiple threads not working, or VB making calls in the same thread, or in your case this type of mutex being useless?

    Multiple threads work fine with critical sections, guaranteed. Nothing can I say about thread model of VB, but it's quite easy to figure out. And in case this what you tried seems useless for you, you always can go with some other solution.

    In the latter case you need to explain your design as well as show your real code but not this fake one.
    Best regards,
    Igor

  7. #7
    Join Date
    Jul 2010
    Posts
    88

    Re: Mutex never works

    My real code is around 100000 lines and not easy to show.
    If I understand the threading model correct then Visual Basic is going around the mutex because each call is made to a different copy of the engine in appartment threading.
    I need to make sure that only one call at once is made to the engine no matter what framework is calling the component.
    Raising an exception when a call is blocked would be okay because I just want to protect beginners from damaging the operative system.

  8. #8
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Mutex never works

    Quote Originally Posted by Dawoodoz View Post
    My real code is around 100000 lines and not easy to show.
    If I understand the threading model correct then Visual Basic is going around the mutex because each call is made to a different copy of the engine in appartment threading.
    What's confusing you is that you called your critical section "mutex". Why not create a mutex using CreateMutex?

    http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx

    As you can see there is a difference between a mutex and a critical section.

    From the link above:
    Note that critical section objects provide synchronization similar to that provided by mutex objects, except that critical section objects can be used only by the threads of a single process.
    So from what you're saying, you are using the incorrect synchronization object. You should have been using an actual mutex object, one created with CreateMutex, not a critical section.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; April 15th, 2012 at 11:10 AM.

  9. #9
    Join Date
    Jul 2010
    Posts
    88

    Re: Mutex never works

    That might solve it.

  10. #10
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: Mutex never works

    As synchroization objects, both critical sections and mutexes will behave similarly, if the calling thread already owns the synchronization object. To wait on a mutex, the calling thread calls WaitForSingleObject (or WaitForMultipleObject). If the calling thread already owns the mutex, then the call returns immediately with result code WAIT_OBJECT_0

    See the documentation for ReleaseMutex at http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx
    A thread can specify a mutex that it already owns in a call to one of the wait functions without blocking its execution. This prevents a thread from deadlocking itself while waiting for a mutex that it already owns. However, to release its ownership, the thread must call ReleaseMutex one time for each time that it obtained ownership (either through CreateMutex or a wait function).
    To the OP: Why do you need to "block" a second call to your function. It's not possible for a single thread to call the same function more than once at the same time. Other effects might arise within the context of a single thread (such as re-entrancy issues or deliberately recursive functions), but since these are all executed in the context of a single thread, there are always simple alternatives for dealing with the issue (e.g., set a flag in thread-local memory).

    Mike

  11. #11
    Join Date
    Jul 2010
    Posts
    88

    Re: Mutex never works

    When an application make multiple calls at once using a callback or delay, the engine will crash.
    With appartment threading, global variables for flags do not work between different simultaneous calls because they are working on different copies of the memory.
    Last edited by Dawoodoz; April 17th, 2012 at 06:24 AM. Reason: Typo

  12. #12
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,633

    Re: Mutex never works

    Quote Originally Posted by Dawoodoz View Post
    When an application make multiple calls at once using a callback or delay, the engine will crash.
    Which should be read: bad server implementation.
    With appartment threading, global variables for flags do not work between different simultaneous calls because they are working on different copies of the memory.
    Sure, because global variables are supposed to do only in case of singleton.
    Best regards,
    Igor

  13. #13
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: Mutex never works

    Quote Originally Posted by Dawoodoz View Post
    When an application make multiple calls at once using a callback or delay, the engine will crash.
    What is the relationship of this observation to your original question on threading and mutexes/critical sections? There doesn't seem to be any relation at all. What do you mean by "crash", which is a completely unhelpful description? So far, this problem sounds terribly ordinary, as if there is poorly synchronized access to memory across threads.

    Quote Originally Posted by Dawoodoz View Post
    With appartment threading, global variables for flags do not work between different simultaneous calls because they are working on different copies of the memory.
    If a variable is truly "global", then there cannot be "different copies of it in memory".

    I tend to think that there is an underlying bad architecture, or there is a poor understanding and/or usage of an otherwise good architecture. You mentioned that there are 100000 lines of code, but if this is an achitectural issue, then it should be straightforward to show the basics in a sample of far fewer lines of code. Please do so, or do a better job at explaining what you want.

    And let's look for a moment back at the code in your original post:
    Quote Originally Posted by Dawoodoz View Post
    Code:
    #define _WIN32_WINNT 0x0403
    #include <Windows.h>
    #include <stdio.h>
    #include <tchar.h>
    
    CRITICAL_SECTION Mutex;
    
    int _tmain(int argc, _TCHAR* argv[]) {
    	// Initialize the mutex
    	if (!InitializeCriticalSectionAndSpinCount(&Mutex,0x00000001)) {
    		wprintf(L"Could not initialize the mutex.");
    	}
    	
    	EnterCriticalSection(&Mutex);		// #1
    		EnterCriticalSection(&Mutex);	// #2
    			wprintf(L"This should be impossible to reach because of deadlock.");  // #3
    		LeaveCriticalSection(&Mutex);
    	LeaveCriticalSection(&Mutex);
    	
    	// Release the mutex
    	DeleteCriticalSection(&Mutex);
    	
    	return 0;
    }
    According to your post, it should not be possible to reach #3 because the attempt to EnterCriticalSection at #2 should be blocked by the previous acquisition of the critical section at #1.

    If this is correct, then there would be deadlock without possibility of escaping. Think about it: the thread that called EnterCriticalSection at #1 owns the critical section and is the only thread that can release it. But if the thread were blocked by the call to EnterCriticalSection at #2, then the thread becomes irretrievably deadlocked, because (under your scenario) it's the only one that could release the critical section but it can't do anything -- muchless release a critical section -- because it's blocked at #2.

    That of course is not the way that critical sections (or other synchronization primitives like mutexes) work, as explained in the documentation.

    Mike

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured