Re: Thread-safe reference counts.
On Mar 31, 3:54 am, "Dmitriy V'jukov" <dvyu...@gmail.com> wrote:
Consider following example:
class application_settings;
application_settings* g_settings;
// replaces g_settings with new_settings,
// and releases previous value of g_settings
void update_settings(application_settings* new_settings);
// acquires and returns object stored in g_settings
application_settings* acquire_settings();
// releases settings object
void release_settings(application_settings* settings);
void reader_thread()
{
for(;;)
{
application_settings* settings = acquire_settings();
// use settings
release_settings(settings);
}
}
In this example acquire_settings() must act on pointer to object for
which it doesn't have reference yet.
Huh? Of course it does. You just keep one reference for whatever is
the currently valid settings.
How this pattern must be implemented in the right way (pointer ==
reference)?
Wherever 'acquire_settings' keeps a pointer to the current settings,
it also keeps a reference. Like this:
// replaces g_settings with new_settings,
// and releases previous value of g_settings
void update_settings(application_settings* new_settings)
{
new_settings->AddRef();
Lock();
if(g_settings!=NULL) g_settings->UnRef();
g_settings=new_settings;
Unlock();
}
// acquires and returns object stored in g_settings
application_settings* acquire_settings()
{
application_settings *ret=NULL;
Lock();
if(g_settings!=NULL)
{
g_settings->AddRef();
ret=g_settings();
}
Unlock();
return ret;
}
// releases settings object
void release_settings(application_settings* settings)
{
Lock();
if(g_settings!=NULL)
{
g_settings->UnRef();
g_settings=NULL;
}
Unlock();
}
Note that 'Lock' and 'Unlock' are notional. They can be a global lock
but they can also be atomic operations, a lock specific to the
implementation of g_settings, or anything else you like.
See how threads are not the only thing that can have a reference? The
global 'g_settings' pointer (and its associated lock if it has one)
can also have a reference.
DS