patterncppModerate
Prevent re-entrant function call in C++
Viewed 0 times
entrantpreventfunctioncall
Problem
The purpose of this is to prevent a re-entrant function call in a single thread, e.g. prevent the situation where
This is currently not used in any multithreaded code (and does not plan to be).
Usage:
Is there a better idiom for this, e.g. involving
Update: As pointed out by Greg Hewgill, if multiple functions use
(perhaps this could be controlled with a template parameter or something).
func() calls bar() which calls func().This is currently not used in any multithreaded code (and does not plan to be).
struct TranLock
{
static int count;
bool failed;
TranLock() { failed = count; if (!failed) ++count; }
~TranLock() { if (!failed) --count; }
};
int TranLock::count = 0;Usage:
void func()
{
TranLock lock;
if ( lock.failed )
return; // or take other action
// the function's logic here
}Is there a better idiom for this, e.g. involving
std::shared_ptr ? C++11 features OK.Update: As pointed out by Greg Hewgill, if multiple functions use
TranLock they will all have a shared lockout. Currently I only use it in one function, although it would be nice to see two different possible implementations:- Lock which can be shared amongst functions
- Individual lock per function
(perhaps this could be controlled with a template parameter or something).
Solution
The obvious problem with this is it will detect any function that uses
In order to make a lock like this that can be used with multiple functions, create a class with no static members, then in each function where you want to use a lock, create a
You could use a hybrid of these two techniques, for example
Finally, you don't really need to maintain an
TranLock calling any other function that also uses TranLock (since there is only a single global count). That is, if func() (which uses TranLock) calls bar() (which also uses TranLock) then bar() will erroneously fail.In order to make a lock like this that can be used with multiple functions, create a class with no static members, then in each function where you want to use a lock, create a
static instance of the class. That way, each function will have its own independent counter. However, you can't rely on the class destructor in this case because the destructor of static objects is not called when the object goes out of scope.You could use a hybrid of these two techniques, for example
struct TranLock
{
int &count;
TranLock(int &count): count(count) { failed = count; if (!failed) ++count; }
~TranLock() { if (!failed) --count; }
};
void func()
{
static int TranLock_count;
TranLock lock(TranLock_count);
if (lock.failed) {
...
}
...
}Finally, you don't really need to maintain an
int count at all. Since you only ever increment count when it is zero, a bool flag would do equally well.Code Snippets
struct TranLock
{
int &count;
TranLock(int &count): count(count) { failed = count; if (!failed) ++count; }
~TranLock() { if (!failed) --count; }
};
void func()
{
static int TranLock_count;
TranLock lock(TranLock_count);
if (lock.failed) {
...
}
...
}Context
StackExchange Code Review Q#54333, answer score: 11
Revisions (0)
No revisions yet.