Boost logo

Boost :

From: klaus triendl (klaus_at_[hidden])
Date: 2008-03-17 17:36:54


Hi,

Phil Endecott schrieb:
> I've mentioned something like this here a couple of times; did you see
> my Proto review? http://thread.gmane.org/gmane.comp.lib.boost.devel/171620

I've just taken a look at your proto review and to me it just asserts
the usefulness of a lockable.

The same goes for Frank's monitoring_ptr. My feeling is that some sort
of type/mutex pairing and an expressive threadsafe access is desirable.

> My feeling is that the basic Lockable<T> that pairs a mutex with the
> data that it locks is by itself too trivial for Boostification. Where
> it gets interesting is when you provide an interface to do automatic
> locking and unlocking, i.e. your locking pointer; I'd be interested to
> see some example usage for your version. In my case I found that the
> locking pointer (or locking reference) was actually more verbose than
> explicitly locking the mutex and accessing the data, so the only
> benefit is that the locking can be mandatory. But normally the only
> "enforcement" that I need is a comment: /* lock this before writing
> that */. Perhaps you have something more concise than I managed.

Well, you are right, a lockable<T> is a very trivial wrapper; however
under the premise that I like encapsulation :) it does more than that:

- it encapsulates a certain feature and gives it a (hopefully) sound
name, still being generic
- you can clearly express in a relatively easy technical way your
intention that a variable should be accessed in a threadsafe manner. If
I see a lockable eventually together with a lock_acquirer I immediately
know that some threadsafe access is happening
- a lockable<T> is easier to share with a shared_ptr<lockable<T>>
between multiple threads and places of code than something else
- transitive constness: no matter whether the lockable<T> is shared
const (even if T is non-const) or T itself is const or the programmer
requires read-only access, she only gets const-access to T (which
doesn't mean that she gets non-const access to const T if she requires
write access)
- if lockable<T>'s T is only accessible through interface methods you
can clearly see in which way you access T
- encapsulation of volatile-ness: I don't know how important the
volatile qualifier is for a lockable but since my lockable<T> stores T
volatile and the proper interface methods and the lock_aqcuirer gives me
non-volatile access I don't have to think so much about some type being
volatile or not. Having read Andrei's article on ddj (btw:
http://www.ddj.com/dept/cpp/184403766) I had the impression that the
volatile qualifier is quite important.

The lock_acquirer functions with lockables as well as with free-floating
variables and mutexes. It's more a locking reference than a pointer;
first I considered pointer semantics but it is even safer to have a
protected friend template function (access_acquiree) that requires a
named lock_acquirer object and that is only accessible by its
unqualified name through ADL.

Sure, the creation of a named lock_acquirer is quite verbose - I thought
already of the c++09 auto typing feature together with RVO (return value
optimization) like:
auto some_lock = make_lock_acquirer(some_lockable);

Still, to me the syntactic overhead seems worth the effort and might be
solved by other ways yet to be found.

Please have a look at my code, it can be found in the boost vault, name
"thread_lockable.zip". The project contains a solution for msvc 2008 but
should be easy to compile with any compiler.

Klaus


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk