A: 

1.) Yes, the mutex is necessary. Although there is only one instance of the class in existence at any one time, multiple threads could still call process() on that instance at the same time (unless you design your app so that never happens).

2.) Anytime you use the value you should protect it with the mutex.

However, you don't mention a GetRootData and SetRootData in your class declaration above. Are these private (used only inside the class to access the data) or public (to allow other code to access the data directly)?

If you need to provide outside access to the data by making the GetRootData() function public, then you would need to return a copy, or your callers could then store a reference and manipulate the data after the lock has been released. Of course, then changes they made to the data wouldn't be reflected inside the singleton, which might not be what you want.

Nick Meyer
GetRootData and SetRootData are public function.Also, Please see the edited question. The mutex part.
Gautam Borad
+1  A: 

1] If the class is a singleton and mRootData is inside that class, is the Mutex gaurd really necessary?

Yes it is, since one thread may call process() while another is calling refresh().

2] Should i protect the i) data structure OR ii) function accessing the data structure.

Mutex is meant to protect a common code path, i.e. (part of) the function accessing the shared data. And it is easiest to use when locking and releasing happens within the same code block. Putting them into different methods is almost an open invitation for deadlocks, since it is up to the caller to ensure that every lock is properly released.

Update: if GetRootData and SetRootData are public functions too, there is not much point to guard them with mutexes in their current form. The problem is, you are publishing a reference to the shared data, after which it is completely out of your control what and when the callers may do with it. 100 callers from 100 different threads may store a reference to mRootData and decide to modify it at the same time! Similarly, after calling SetRootData the caller may retain the reference to the root data, and access it anytime, without you even noticing (except eventually from a data corruption or deadlock...).

You have the following options (apart from praying that the clients be nice and don't do nasty things to your poor singleton ;-)

  • create a deep copy of mRootData both in the getter and the setter. This keeps the data confined to the singleton, where it can be guarded with locks. OTOH callers of GetRootData get a snapshot of the data, and subsequent changes are not visible to them - this may or may not be acceptable to you.
  • rewrite RootData to make it thread safe, then the singleton needs to care no more about thread safety (in its current setup - if it has other data members, the picture may be different).

Update2:

  • or remove the getter and setter altogether (possibly together with moving data processing methods from other classes into the singleton, where these can be properly guarded by mutexes). This would be the simplest and safest, unless you absolutely need other parties to access mRootData directly.
Péter Török
Please see the edited question.
Gautam Borad
@Gautam, see my update.
Péter Török
RootData is a BIG structure with lots of smart_pointers and vectors, etc. So ive decided to return reference in GetRootData and protect the `process` and `refresh` functions with Mutex.Is this sufficient or should i return copy and hence, handle deep copy of structure.
Gautam Borad
@Gautam, see my update for a third option. As I explained above, returning a reference to the shared data means you have no control anymore over who uses the data and when, thus your code is not thread safe anymore.
Péter Török
@Peter, Thanks a lot. I have done exactly that. :-)
Gautam Borad