RE: [Boost-Users] Returning a boost::scoped_lock by value
This issue has come up before on the development list (search for Boost.Threads Locking Delima). I'm not sure that it was resolved satisfactorily - move semantics for scoped_locks seemed to be the answer, but I think there were problems actually implementing that. The intent was that if move couldn't be implemented, then the mutex lock methods would have to be exposed.
-----Original Message----- From: Raoul Gough [mailto:yg-boost-users@m.gmane.org] Sent: Friday, 27 September 2002 9:44 PM To: boost-users@yahoogroups.com Subject: [Boost-Users] Returning a boost::scoped_lock by value
boost::scoped_lock is non-copyable, so it is impossible to return one from a function by value. However, I would like to be able to do something like this:
mt::holderstd::ostream logStream;
logStream() << "Hello world\n";
where the operator() returns a proxy object that contains a scoped_lock and a pointer to the data (the ostream). What I currently have is this:
(mt::proxystd::ostream (logStream)) << "Hello world\n";
So the client code has to know what type the proxy object is and construct one itself. If scoped_lock would provide access to its associated mutex object, this wouldn't be a necessary, because the proxy object could then have a copy-constructor, and operator() in the holder template would look like this:
proxy<T> operator() () { proxy<T> temp (*this); return temp; }
The proxy copy constructor would unlock() the original lock and construct the copy using the original's mutex (which is the part that can't currently work, because there is no public access to a lock's mutex). Assuming that the compiler implements the NRVO, the unlock/lock sequence wouldn't actually happen, and the client code just gets its proxy object constructed for it. If the compiler doesn't implement the NRVO, the code still works, but is less efficient.
I guess exposing the raw mutex from scoped_lock would break an important level of encapsulation. Still, it would be kind of nice in this case. Maybe if proxy<T> were part of the library and made a friend of scoped_lock? The only other alternative I've come up with is to allocate the lock on the heap and return an object containing a std::auto_ptr (which makes usage easier, but less efficient). Any comments or suggestions?
Regards, Raoul Gough.
// Returnable proxy template
template<typename T> class proxy { boost::mutex::scoped_lock mLock; T *mPtr;
boost::mutex &release() { mLock.unlock(); return mLock.mutex(); // <<<< doesn't work }
public:
proxy (proxy &other) : mLock (other.release()) , mPtr (other.mPtr) { }
// ... };
------------------------ Yahoo! Groups Sponsor ---------------------~--> Home Selling? Try Us! http://us.click.yahoo.com/QrPZMC/iTmEAA/MVfIAA> /EbFolB/TM
-------------------------------------------------------------- -------~->
Info: http://www.boost.org Wiki: http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl Unsubscribe: mailto:boost-users-unsubscribe@yahoogroups.com
Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
"Darryl Green"
From: Raoul Gough [mailto:yg-boost-users@m.gmane.org] Sent: Friday, 27 September 2002 9:44 PM [snip] The proxy copy constructor would unlock() the original lock and construct the copy using the original's mutex (which is the part that can't currently work, because there is no public access to a lock's mutex). Assuming that the compiler implements the NRVO, the unlock/lock sequence wouldn't actually happen, and the client code just gets its proxy object constructed for it. If the compiler doesn't implement the NRVO, the code still works, but is less efficient.
This issue has come up before on the development list (search for Boost.Threads Locking Delima). I'm not sure that it was resolved satisfactorily - move semantics for scoped_locks seemed to be the answer, but I think there were problems actually implementing that. The intent was that if move couldn't be implemented, then the mutex lock methods would have to be exposed.
Hi, Darryl. Thanks for the pointer - move semantics is what I was
looking for. How are things going at tabq?
If anyone is interested, I've come up with an improved proxy
implementation that provides move semantics using the existing
boost::scoped_lock. It stores its own reference to the original mutex,
which is only slightly less efficient than if scoped_lock had move
semantics itself. This allows code like the following:
void foo (mt::holder
participants (2)
-
Darryl Green
-
Raoul Gough