Reputation: 6230
void foo ( Bar* bar , void(Bar::*qux)(void) )
{
if ( bar )
{
bar->qux();
}
}
The problem is:
bar
can be deleted after the check by another thread.
I can not add a mutex member to Bar
in order to lock it.
Thus I wonder, if I can tell the processor to run this function atomically, and how would I do so? I've spent way to much time on Google, but found no understandable manuals...
P.S. Debian, gcc , Boost NOT allowed, C++11 IS allowed.
Upvotes: 6
Views: 12923
Reputation: 10357
The concept of atomic methods doesnt exist in C++ like it does in Java, where you can define a method as synchronized. The closest you can get to that in C++ would be to create a ScopedMutex class as follows:
class ScopedMutex {
public:
ScopedMutex(pthread_mutex *m) : theMutex_(m) {pthread_mutex_lock(theMutex_);}
~ScopedMutex() { pthread_mutex_unlock(theMutex_); }
// Add appropriate copy constructors and operator=() to disallow mutex copy
// Or consider passing in a reference
private:
pthread_mutex *theMutex_;
};
Then use it like this in your function:
void foo ( Bar* bar , void(Bar::*qux)(void) )
{
ScopedMutex m(&aMutex); // This mutex must be defined/initialized elsewhere
if ( bar )
{
bar->qux();
}
// The ScopedMutex goes out of scope when the function does,
// thus releasing the lock
}
But this wont do you any good unless you use the same mutex in every other method that uses the bar object.
Scoped Mutex are especially useful when you have a function with complicated logic where there are several return statements, so you dont have to manually unlock the mutex it will be unlocked when the function goes out of scope.
Upvotes: 3
Reputation: 254431
You want to temporarily share ownership of the object, in order to prevent another thread from deleting it. This is a job for shared_ptr
, using weak_ptr
to allow deletion when we don't need to access it:
void foo ( std::weak_ptr<Bar> weak_bar , void(Bar::*qux)(void) )
{
if (std::shared_ptr<Bar> bar = weak_bar.lock())
{
// We now share ownership of the object - it won't be deleted
bar->qux();
}
// We have released ownership - it can now be deleted
}
Of course, you still need synchronisation if multiple threads need to access the object; this only solves the problem of deletion specified in the question.
Upvotes: 4
Reputation: 136208
You probably want to use a smart pointer with shared ownership semantics (e.g. shared_ptr
, intrusive_ptr
) to make sure the object stays alive as long as you refer to it.
Upvotes: 4
Reputation: 490048
Sorry, but no. C++ doesn't have anything to support that. You don't necessarily need to add the mutex to Bar
, but to avoid it, you'll probably need a wrapper around Bar
, or something on that order.
Upvotes: 2