The context
I have a class (let's say Foo
) managing some centralized ressources as an history in a static map, with an accessor to read them and a function to add new data (there is no way to remove a key) :
class Foo
{
private:
static std::map<std::string,MyDataStructure> data;
public:
static const MyDataStructure& getData(const std::string& key)
{
assert(Foo::data.count(key) > 0); // Must exist
return Foo::data[key];
}
static void addData(const std::string& key, const MyDataStructure& d)
{
assert(Foo::data.count(key) == 0); // Can not already exist
Foo::data[key] = d;
}
};
In order to avoid concurrency problems, I added a mutex I manage like that :
class Foo
{
private:
static std::map<std::string,MyDataStructure> data;
static boost::mutex mutex_data;
public:
static const MyDataStructure& getData(const std::string& key)
{
boost::mutex::scoped_lock lock(Foo::mutex_data);
assert(Foo::data.count(key) > 0); // Must exist
return Foo::data[key];
}
static void addData(const std::string& key, const MyDataStructure& d)
{
boost::mutex::scoped_lock lock(Foo::mutex_data);
assert(Foo::data.count(key) == 0); // Can not already exist
Foo::data[key] = d;
}
};
My questions
- My first question is about the reference to
Foo::data
returned bygetData
: this reference is used out of the scope of the mutex, then is it possible to have a problem with that ? Is it possible to loose the reference due to another access adding data ? In brief : is the reference always the same once in the map ? - If yes, is the
assert
required inaddData
? Can the reference change if I change data linked to an existing key in the map ? - Is the lock required in
getData
? I think maybe not ifstd::map
is already multi-thread safe.