Le 17/06/13 01:36, Klaim - Joël Lamotte a écrit :
On Sun, Jun 16, 2013 at 11:54 PM, Vicente J. Botet Escriba < vicente.botet@wanadoo.fr> wrote:
I was wondering if a not yet existing synchronized_value
could help in your context. You would need to declare a value and a reference. explicit Sequence( SequenceInfo info ) : m_value( info ), m_ref(M_value) { m_value.do_something(); // no need to lock.
}
It's closer to the ideal but I think it defeats the point of having only one way to access the member after the constructor is called. Right. The constructor of the instance could master the access to the unsynchronized value. It is similar to the wrapper solution.
class SequenceImpl { X m_value1; Y m_value2; public: synchronized_value<X> m_ref1; // only the synchronized parts are public. synchronized_value<X> m_ref2; SequenceImpl(SequenceInfo info) : m_value1(info), m_value2(info), m_ref1(m_value1), m_ref2(m_value2) { // Do whatever you want with m_value1, m_value2 without locking. } }; class Sequence : public SequenceImpl { public: Sequence(SequenceInfo info) : SequenceImpl(info) { } }; Some measures would be needed to ensure that there is no lost of efficiency while using a reference instead of a value in synchronized_value.
But the mix of this suggestion and my previous one reminded me unique_lock: you can not lock on construction with it. Maybe something similar could be done? So maybe something like that would work:
explicit Sequence( SequenceInfo info ) : m_value( info , synchronized_value::dont_lock_yet ) // optional { m_value->do_something(); // don't lock! ... m_value.begin_sync(); // (random name) from here the usual locking is mandatory to access the value.
m_value->do_something(); // locking }
void do_something() { m_value->do_something(); // locking m_value.begin_sync(); // throw exception or UB or nothing? }
I'm not sure if it would require changing the mutex concept though, but if it can be done with the current default one it would allow beginning the protection explicitly when needed but not removing it once it's active. Maybe just an atomic bool saying if the sync should happen or not, but then it's an additional test on access and with reading an atomic, which I have not a clear idea if it's expensive or not. Or maybe it would be a specialization.
What do you think?
This will make the whole lifetime of the instance less efficient, so globally you will lost efficiency. I don't think it is worth the effort to change anything. * The lost of efficiency should be minor and only on the constructor when the user can not use a factory (the type T is not copyable nor movable). * The solutions make the design must more complex. Best, Vicente