views:

217

answers:

2

So App Verifier is throwing this exception. From what I gather, the text of this message is a little misleading. The problem appears to be that the the critical section was created by a thread that is being destroyed before the critical section is destroyed.

It's a relatively simple fix but does anyone know what the ramifications are for having a thread other than the creating one destroy the crticial section? How dangerous is it? Is the concern only that the critical section handle will "leak" or is there a more insidious side-effect?

Some other info:

  • App written in C++ (on Windows, of course)
  • Critical section created with InitializeCriticalSelection
  • Critical section is eventually deleted with DeleteCriticalSection
+1  A: 

I believe you are correct on the interpretation of the message. The only reference I can find is as follows. The stack trace is a good clue as the author suggests

I dug around for a bit and cannot find any specific reason why you cannot create and delete a critical section on different threads. However I do wonder why it is that you want to do so? It seems like best practice to have one thread own a critical section so to speak. Handing off the critical section between threads introduces another means of communication and potential error (can be done, just more fun).

JaredPar
Yeah, i agree. It's not desirable and will make changes to the code if there is a deleterious side-effect but the code I'm looking at is fragile and shouldn't be changed right now if it can be avoided. Thanks for your input!
Karim
+1  A: 

As opposed to beasts such as COM objects, critical sections life cycle is not bound to a certain thread. Critical sections are constructed in two stages: upon creation, they are merely made of a few structures. Upon contention of two or more threads, a kernel mutex is created to handle the synchronization properly. Both the structures and the mutex can be created, accessed and destructed by any thread, be it the one that created the critical section or not.

To answer your questions, the above means you should have no problems creating the CS in one thread and destroying it in another. This might, however, imply some problem with the design. If you're not doing that already, consider wrapping the CS with a class that will initialize the CS in its constructor, and destroy it in its destructor (MFC's CCriticalSection does that). Then, have the wrapper created on a higher scope than the one that uses it (global, static class member, whatever). Should make the creation and cleanup much easier.

And lastly, regarding the error message itself - is it possible the thread that is being deleted has entered the CS without having the chance to leave it (due to an exception or so)? If that is the case, you got a weird looking message that points to a real problem.

eran
@eran, i agree with all your points concerning the nature of the design. As I said earlier, this is a relatively fragile area of the code that is not the focus of my efforts the moment and I don't want inadvertently destabilize it - so now design changes if i can avoid it. Thank you for the insight into the way critical sections work internally.
Karim
I hear you... if possible, you can use those techniques to create a local build that will only be used to locate this one problem. Try creating a wrapper with Enter() and Leave() methods, that will also set a status flag. On the d'tor, assert if the flag says Leave() has not been called. This way you can locate the CS exit point, and add a try-catch or another LeaveCriticalSection in your original code.
eran