I'm working on win 32 multithreading with c++. Scenario: I have a function used by multiple threads. This function as a critical sections (or any kind of construct that can lock a resource). In the critical section an exception is thrown. At this point I need to take care of unlocking the resource in the exception catch block.
Is there any other way that this can be done? I mean, let's say that I don't want to have to remember to release the lock in the catch block, is there any common way to handle this problem to avoid this error prone scenario?
If you throw an exception, all functions will be exited back to the point where it finds a try... catch block with a matching catch type. If your function isn't called from within a try block, the program will exit with an unhandled exception.
This means that an exception thrown within a catch block will not be caught by the catch block it's in. Instead, it will be propagated up the stack to the caller. The exception thrown from the catch block can be an exception of any type -- it doesn't need to be the same type as the exception that was just caught.
C doesn't support exception handling. To throw an exception in C, you need to use something platform specific such as Win32's structured exception handling -- but to give any help with that, we'll need to know the platform you care about. ...and don't use Win32 structured exception handling.
It is up to you to ensure that the application is recovered into a stable state after catching the exception. Usually it is achieved by "forgetting" whatever operation or change(s) produced the exception, and starting afresh on a higher level.
The idea is to encapsulate the act of acquiring and releasing the critical section in an object such that constructing the object acquires the CS and destroying the object releases it.
struct CSHolder {
explicit CSHolder(CRITICAL_SECTION& cs): lock(cs) {
::EnterCriticalSection(&lock);
}
~CSHolder() { ::LeaveCriticalSection(&lock); }
CRITICAL_SECTION& lock;
};
CRITICAL_SECTION gLock;
void foo() {
CSHolder lockIt(gLock);
// lock is held until lockIt is destroyed
}
The concept is called RAII - Resource Acquisition is Initialization. It is a very common idiom in modern C++.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With