Boost logo

Boost Users :

From: C. Michailidis (dinom_at_[hidden])
Date: 2005-04-10 08:30:25


> > Answer.. Don't take the examples at their face value

Likewise.

> > you can do this:
> >
> > class counter
> > {
> > public:
> >     counter() : guard(this->mutex) {
> >        this->count = 0;
> >        this->guard.unlock();
> >     }
> >     void lock() {
> >        guard.lock();
> >     }
> >     int increment() {
> >         assert(this->guard.locked());
> >         return ++count;
> >     }
> >     void unlock {
> >         assert(!this->guard.locked());
> >         this->guard.unlock();
> >     }
> >     // ..Nothing to do here..
> >     // ~counter() {
> >     // }
> >
> > private:
> >     boost::mutex mutex;
> >     boost::mutex::scoped_lock guard;
> >     int count;
> > };
>
> This is not equivalent to the above scenario. You can't have two threads
> calling lock() at the same time, because a scoped_lock object (as currently
> specified) is not thread safe (whereas a mutex is, by its very nature.)
>

Ugh, it would seem you are right Peter! Again, I quote the docs: "sharing a
lock object between threads results in undefined behavior". Phooey!

>
> > class counter
> > {
> > public:
> >     counter() : count(0) {
> >     }
> >     void lock() {
> >        // nothing, methods act as self monitors
> >     }
> >     int increment() {
> >         boost::mutex::scoped_lock guard(this->mutex);
> >         return ++count;
> >     }
> >     void unlock {
> >         // nothing, methods act as self monitors
> >     }
> >     // ..Nothing to do here..
> >     // ~counter() {
> >     // }
> >
> > private:
> >     boost::mutex mutex;
> >     int count;
> > };
>
> This is also not quite equivalent to the original. In it, a lock() op1()
> op2() unlock() is a transaction; no other thread can inject its own op3
> between op1 and op2.

Exactly - this is why I said "likewise" earlier, d-oh!

> The closest you can get to the original, while somewhat respecting the
> requirement for it to be callable from outside C++, is:
>
> scoped_lock * lock()
> {
>     return new scoped_lock( mutex );
> }
>
> void unlock( scoped_lock * lock )
> {
>     delete lock;
> }

Although this respects the requirement that the code be callable from outside
C++, it completely ignores the requirement that the COM interface (i.e.
method prototype) should not change :-(

Anyway, the last suggestion (changing the COM interface and returning a
pointer to the scoped_lock) is probably the best I can do for now - I have
indeed already considered this. The practitioner in me says it should be
fine for my purposes. The theorist in me says I should keep moaning and
groaning until someone truly feels my pain.

soap_box->lock();

I've been making a stink largely because (IMHO) the decision to NOT expose
functionality as fundamental as mutex.lock() and mutex.unlock() seems
ridiculous! The boost library and accompanying docs should absolutely
encourage the use of scoped_locks - I agree 100%. But it certainly shouldn't
*disallow* me from using mutexes in the traditional way - to me this is a
shortcoming. Even if there is some kind of overly complicated way (perhaps
by deriving from mutex and calling some protected lock/unlock methods) I
still think lock/unlock functionality should be exposed by mutex objects.

Did you ever hear of the expression "you've polished the brass right off of
the hinges"? This honestly seems like arrogance on the boost development
team's part - why do they know how to use mutexes so much better than the
rest of us? What am I, chopped liver over here? It is belittling!

I'm not a child, whaaaaa!!!! ;-)

There is little sense in going to such extreme lengths to protect developers
from themselves - after all they are the ones writing the programs! Believe
me, I would love to live to see the day that I simply install the Boost
libraries and BINGO by some stroke of genius the program I intended to write
is already done. I have a feeling it will be some time before this happens,
until then my gun should shoot bullets wherever I point it, and I should be
allowed to point it wherever I want (not where the boost developers THINK it
should be pointed, but where I KNOW it should be pointed).

As they say, "guns don't kill people, people kill people", lol.

soap_box->unlock();

Just my 2 cents,
C. Michailidis


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net