Michael Glassford said:
[snip discussion of std::auto_ptr< boost::lock >(...), etc.]
Seriously, I'm against over complexity. The Boost solution is right
something between 90-95% of the time. All I'd ask for is access to
the underlying lock()/unlock() functions on mutex, so I can provide
a custom solution for the few remaining cases.
I'll add it to my list of things to think about. As a quick idea,
would adding protected lock() and unlock() members to the mutex
classes work? (Not public so they can't be called accidentally by
users of the class, not private so you can create a derived mutex
class that works in conjunction with a lock class that you design).
That sounds like a very good compromize; about the only possible
objection I can see is that it requires an abuse of derivation to use
the special functions.
In one project I worked on in the past, dangerous functions were
qualified with names beginning with "unsafe_"; what about calling them
"unsafe_lock" and "unsafe_unlock"? (OK, it's just an idea. I'm not
fully convinced myself.)
The real problem, I think, is that we are dealing with two levels of
abstraction, one very low level, where you are on your own, and one at a
higher level, which should be used most of the time. Normally, that
would be two, apparently separate classes, and as long as you dealt
strictly at the higher level, you wouldn't need to even be aware of the
lower level. That doesn't quite work here, because even as a client of
the higher level, you have to manage the lifetime and the sharing of the
lower level object; it would be very hard to use Lock if you couldn't
refer to the mutex it should lock on.
So even from a purely abstract design level, I'm not sure what the most
elegant solution would be. What I want is a low level interface that is
not normally available, but that can be made available if I do something
intentional to get to it. And in fact, the only solution I can think of
which meets exactly those requirements is protected. Even if that
wasn't really the original use protected was designed for. Who knows,
maybe we're even creating a new idiom. (It will be an easy idiom to
recognize. How often do you see protected elements in a class with no
virtual functions?)