C
Chris Thomasson
David Schwartz said:I agree. I would put it simply -- you cannot call 'AddRef' unless you
have an explicit or implicit reference to an object. The 'AddRef'
function is not special, it must be called with a reference just like
every other function.
The puzzle is this -- how did you get a pointer to object to call
'AddRef' on anyway?
This paper explains the puzzle, and a soultion:
http://citeseer.ist.psu.edu/cache/p...zSzpaperszSz01-podc.pdf/detlefs01lockfree.pdf
I've heard a lot of talk about strong thread safety and the like, but
I have to admit, I don't get it. In order to call 'AddRef' on an
object, you need a pointer to it, and how could you possibly have
gotten that pointer without something that already had a reference?
Think of the following scenario:
__________________________________________________
static atomic_ptr<foo> g_foo;
void writers() {
for(; {
local_ptr<foo> l_foo(new foo);
g_foo = l_foo;
}
}
void readers() {
for(; {
local_ptr<foo> l_foo(g_foo);
if (l_foo) {
l_foo->do_something();
}
}
}
__________________________________________________
Notice how the reader thread can grab a reference from 'g_foo' without
having a previous reference to an object contained within it? You can
download the sourcecode of atomic_ptr from:
http://sourceforge.net/project/showfiles.php?group_id=127837
(atomic-ptr-plus package)
Also, you can take a look at the source code for my proxy garbage collector:
http://appcore.home.comcast.net/misc/pc_sample_h_v1.html
The function that allows any thread to grab a reference to the current
region is 'pc_acquire()':
__________________________________________________
pc_region*
pc_acquire(
pc_master* const _this
) {
pc_sys_anchor cmp = _this->head, xchg;
do {
xchg.refcnt = cmp.refcnt + 2;
xchg.region = cmp.region;
} while (! DWCASPTR(&_this->head, &cmp, &xchg));
return cmp.region;
}
__________________________________________________
Notice how it updates the counter and grabs a pointer to the current region
in a single atomic operation (e.g., DWCAS-loop)? This is another solution to
your puzzle.
The existence of a pointer should mean the existence of a reference --
otherwise how can you know that pointer remains valid, whether a call
for AddRef or for any other purpose?
You need to load a pointer and increment the reference count in a single
atomic operation.