Re: Thread-safe reference counts.
"David Schwartz" <davids@webmaster.com> wrote in message
news:9ee8ea51-7f0e-4733-801e-e798d086d177@s8g2000prg.googlegroups.com...
This just means, that you are making a copy of an object where the
destructor is in progress. That's simply a bug and should be avoided ;-)
best regards,
Torsten
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?
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?
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?
Here is some code you can look at which implements strongly thread-safe
reference counting:
http://groups.google.com/group/comp.programming.threads/browse_frm/thread/d30ad3154c08d9dd
The 'foo_obj_acquire/release()' functions is where all the magic take place:
______________________________________________________________________
foo_obj* foo_obj_acquire(foo_obj** psrc) {
foo_obj* _this;
pc_region* const pcr = pc_acquire(&g_pcm);
if (_this = LOADPTR(psrc)) {
atomicword cmp = _this->refcnt;
do {
if (! cmp) {
_this = NULL;
break;
}
} while(! CASWORD(&_this->refcnt, &cmp, cmp + 1));
}
pc_release(pcr);
return _this;
}
void foo_obj_release(foo_obj* _this) {
if (XADDWORD(&_this->refcnt, -1) == 1) {
pc_mutate(&g_pcm, &_this->pcn);
}
}
______________________________________________________________________
Any thread can call 'foo_obj_acquire()' to grab a reference from a pointer
to a 'foo_obj*'. The following setup is perfectly legal:
_____________________________________________________________________
static foo_obj* g_foo = NULL;
void reader_threads(void) {
for (;;) {
foo_obj* const _this = foo_obj_acquire(&g_foo);
if (_this) {
foo_obj_release(_this);
}
}
}
void writer_threads(void) {
for (;;) {
foo_obj* const _this = foo_obj_ctor();
if (_this) {
foo_obj* prev = foo_obj_swap(&g_foo, _this);
if (prev) {
foo_obj_release(prev);
}
}
}
}
_____________________________________________________________________
reader threads can acquire reference's to 'foo_obj' objects on the fly,
without having to own a previous reference to them.