Reputation: 11431
I am reading a book on applied C++ about locking and design.
void addRef() { ref++; }
void subRef() { if(--ref == 0) delete this; }
Although a statement like ref++ looks trivial, there is no guarantee that it is atomic. But before you go and rewrite this code to add locking, you need to know how your application will use it. In this particular example, a bug is created if addRef is called after subRef. The problem is not with missing locks, it is poor design. If an object must persist beyond scope of a thread, it should be created and owned by a different thread that will not go out of scope.
My question on above text is
Upvotes: 0
Views: 114
Reputation: 153919
Who knows? You'd have to ask the author. This looks like
classical reference counting to me: to make it safe, you'd have
to either user a mutex to protect all accesses to ref
, or make
ref
some sort of atomic variable. (C++11 has a whole range of
functions on std::atomic<int>
which you can use.)
With regards to the quoted text: you can make anything unsafe if
you don't use it right. If two threads are accessing the same
instance, then ref
should already be at least 2, so that if
one thread drops the reference, the object will still continue
to exist. There is no need for any additional thread to
complicate matters.
Upvotes: 0
Reputation: 22251
void thread1work(RefCntObj* refcntObj)
{
refcntObj.addRef();
// any work
refcntObj.subRef();
}
int main(void) {
RefCntObj* refcntObj= new RefCntObj(); // I assume the constructor calls addRef()
std::thread t(thread1work, std::ref(f));
refcntObj->subRef(); // may be called after thread1Work or before it
}
There is no guarantee that the thread1work
will be called before main's refcntObj->subRef();
. In such case the object would already be deleted and the pointer invalid.
Upvotes: 1
Reputation: 1244
By poor design of code, the author means a poor construction of classes and methods ; where you place what and how that position makes your code accessible.
"If an object must persist beyond scope of a thread, it should be created and owned by a different thread that will not go out of scope."
Simply put, the above means that if you have B inside of A(Thread) but you need to use B also in C, than you must remove B from inside the thread(A) and make it independent from it, so you can use it in both A and C.
Upvotes: 0