I have a pool of threads that asynchronously acquire and execute tasks in a queue. Some of these tasks operate over some shared resources. I would like to:
- Provide a contract that separates shared resources from task-specific resources
- Through this contract, ensure that all shared resources are guarded by an appropriate lock (e.g., a mutex)
One option is a generalization of the solution provided here. You provide some sort of
SharedResource<T> class template. An instance of
SharedResource<T> owns a shared resource of type
T along with a mutex. It exposes some
acquire() method that locks the internal mutex and returns a
LockedResource<T> object, which holds the lock and a reference to the shared resource. On destruction, the
LockedResource<T> object releases its lock.
LockedResource<T> forwards all calls to the underlying
T resource (e.g., by implementing
operator->()). To support shared ownership of the underlying resource across tasks, you could also wrap the
SharedResource<T> object's resource and mutex in an automatic reference counter (e.g., a
std::shared_ptr<std::tuple<T, std::mutex>>). As intended, the effect of this solution is that it is necessary to acquire the lock prior to accessing the underlying resource.
This all seems very doable. Yet, it also seems like a convenient solution to a common problem, which makes me think it's probably already been solved by some library. Does the C++ standard library or Boost provide anything like this? If not, do any other libraries come to mind?