Re: RAII object in constructor
Marcel M??ller wrote:
boost::recursive_mutex
This won't help
Sorry, I misunderstood your question. But this should work:
1. Add a Lock::Unlock() to make your lock like a std::unique_lock
2. Derive Worker from AccessibleParams
3. Use a function-try-block for the Worker constructor
4. Unlock() at the end of the Worker constructor's body
The solution should be exception-safe. See the comments for more details.
Here it is:
#include <stdio.h>
// some mutex class
class Mutex
{
public:
// hold the Mutex (RAII)
struct Lock // make it like std::unique_lock
{ Lock(Mutex& mtx)
{ puts("Lock()\n");
// owned = true;
//..
}
void Unlock(Mutex& mtx) // noexcept
{ puts("Unlock()\n");
// owned = false;
// ..
}
~Lock()
{ puts("~Lock()\n");
// if (!owned) return;
// ..
}
};
// ..
};
// set of configuration parameters
struct Parameters
{ //...
};
class WorkerBase
{ //...
protected:
WorkerBase(const Parameters& params)
{ // do something with params...
}
};
struct AccessParams_ : Mutex::Lock
{
AccessParams_();
operator Parameters&();
};
class Worker : private AccessParams_, public WorkerBase
{
private:
static Parameters GlobalParams;
static Mutex ParamMtx; // protect the above
friend AccessParams_;
public:
// synchronized public access to the parameters
// make AccessParams available as before
typedef AccessParams_ AccessParams;
// should an exception be thrown from WorkerBase or Worker constructors,
// the Lock will be released automatically via ~Lock()
Worker() try : WorkerBase(GlobalParams)
{
// do something with params...
Unlock(ParamMtx); // no exceptions: we can unlock explicitly
}
catch (...) { } // re-throws
};
Parameters Worker::GlobalParams;
Mutex Worker::ParamMtx;
AccessParams_::AccessParams_() : Mutex::Lock(Worker::ParamMtx) {}
AccessParams_::operator Parameters&() {
return Worker::GlobalParams;
}
int main()
{ Worker worker;
// do something with worker...
}