Boost logo

Boost Users :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2008-03-27 13:12:47


Patrick Loney:

> I've got some objects which are stored in a DB that are being used in a
> multi-threaded application. I'm trying to avoid loading the same object
> from the db and would like the added bonus of changes made by one thread
> being instantly available to all others (with suitable mutex protection
> provided during a change but they are predominantly read-only)

...

The shared_ptr portion is easy: you can use a map<string, weak_ptr<Record>>
as a cache:

static map<string, weak_ptr<Record> > s_cache;

shared_ptr<Record> get_object( string id )
{
    if( shared_ptr<Record> pr = s_cache[ id ].lock() )
    {
        return pr;
    }

    shared_ptr<Record> pr2( new Record( id ) );
    s_cache[ id ] = pr2;
    return pr2;
}

The synchronization that would make this suitably thread-safe is harder
though. You need to protect s_cache with a mutex. You need to protect
modifications to a particular Record with a mutex. Finally, if ~Record
writes to the database, you have to protect against the race that occurs
when the last shared_ptr<Record> to record "X" dies, which enters ~Record,
and another thread enters get_object("X"), loading the old state of "X"
before ~Record has had the chance to update it. I'm not sure if this race is
solvable, so it might be better to write to the DB in a separate
Record::update method(s) while the shared_ptr is still alive.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net