Boost logo

Boost :

From: William E. Kempf (williamkempf_at_[hidden])
Date: 2002-05-16 15:36:14


----- Original Message -----
From: "Dirk Gerrits" <dirkg_at_[hidden]>

> ----- Original Message -----
> From: "William E. Kempf" <williamkempf_at_[hidden]>
>
> > > I'm not 100% sure exactly which issues you mean. Surely, the
> > > issue that auto_ptrs can't be used in containers is not
> > > relevant here. ;)
> >
> > It's not relevant for auto_ptrs either. Seriously, that's precisely the
> > problem I'm referring to (though there are cases other then just adding
> them
> > to containers that have the same issues... you illustrate one below).
>
> Forgive my threading newbieness (that's probably not a word ;) but why
would
> you want to store locks in a container?

You wouldn't. But newbies do this sort of thing. For instance, you also
wouldn't want to pass a lock between thread boundaries, but despite the
documentation being clear that this is Bad (TM), I've had some reports of
buggy code caused by just this. In any event, like I said the problem is
the same, but the cases where it occurs is more then just when inserting in
containers.

> > > But 'pass by value acts like a sink' does apply here right?
> > >
> > > void func(auto_ptr ptr) {};
> > > {
> > > // code here
> > > } // ptr's value is destroyed [mutex is unlocked]
> > >
> > > int main()
> > > {
> > > auto_ptr<int> ptr(new int(0));
> > > // use ptr here, no problemo [use locked object]
> > >
> > > func(ptr);
> > >
> > > // use ptr again (as a null pointer!) [use object, now unlocked!]
> > >
> > > } // destructor is now a no-op
> > >
> > > I can see this would be problematic. But what other issues are
> > > you referring to?
> >
> > You're mixing "metaphors" here. The code shows only an auto_ptr, while
> your
> > comments refer to lock states. So I can't be 100% sure what you mean
> here,
> > though you have illustrated the issue I was referring to above (the same
> one
> > as there is for containers, actually). If "ptr" were instead a
ScopedLock
> > then after the call to func() (assuming it was pass by value) the lock
> > object would no longer be valid (this is stronger then just the object
> being
> > unlocked). If you know the rules and obey them this is not an issue...
> but
> > we know how that works in the real world.
>
> Sorry about the metaphors, I wasn't really trying to be a poet. :P I'll be
> more
> specific:
>
> // Proper includes here
>
> void func(NewMutex::destructive_copy_lock lock)
> {
> // function now 'owns' the IO lock, probably not a smart idea!
>
> std::cout << "Hello world!" << std::endl;
>
> }; // unlock (and as you say, invalidate the lock object)
>
> NewMutex iomutex;
> void threadFunc()
> {
> NewMutex::destructive_copy_lock lock(iomutex);
> std::cout << "Yo, I'm a thread!" << std::endl;
> func(lock);
> std::cout << "This is not good, right?" << std::endl:
>
> }; // what's up with ~destructive_copy_lock() ?
// The lock is no longer valid so ~destructive_copy_lock does nothing (the
mutex was unlocked
// by the copy made in func()

Yes, that's one issue with the idea. It can be worked around with "proper"
code like this (just showing the client code and not the change to func):

NewMutex::destructive_copy_lock lock(iomutex);
std::cout << "Yo, I'm a thread!" << std::endl;
lock = func(lock);
std::cout << "This is now OK." << std::endl;

Not that I'm advocating this, mind you, only showing that this use case can
be coded in a "correct" manner with the proposed semantics. But the move
semantic warts are showing here.

> // main function with several threads here
>
> Is this what you were thinking about?
>
> Dirk Gerrits
>
> P.S. a 'valid' use for passing auto_ptr by value is to delibarately
> relinquish
> ownership. Perhaps a 'valid' use of this new lock would be:
>
> void unlock(NewMutex::destructive_copy_lock) {};

It would be correct, but "valid" may be too strong, since the same thing can
be accomplished with

lock.unlock();

which won't invalidate the lock as well as unlock the mutex.

Bill Kempf


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