Peter Dimov said: > William E. Kempf wrote: >>>> R result() const >>>> { >>>> boost::mutex::scoped_lock lock(m_mutex); >>>> while (!m_result) >>>> m_cond.wait(lock); >>> >>> This changes result()'s semantics to "block until op() finishes"; >>> what happens if nobody calls op()? Or it throws an exception? >> >> Changes the semantics? I thought this was what was expected and >> illustrated in every example thus far? > > No, my example throws an exception when the call hadn't been made. It > would also throw when the call has been made but did not complete due to > an exception, had I added a try block in operator() that eats the > exception.
Would work, but can complicate (not prevent) usage patterns where the future<> is shared across threads. However, see below. >>>> future(const future<R>& other) >>>> { >>>> mutex::scoped_lock lock(m_mutex); >>> >>> I don't think you need a lock here, but I may be missing something. >> >> I have to double check the implementation of shared_ptr<>, but I was >> assuming all it did was to synchronize the ref count manipulation. >> Reads/writes of the data pointed at needed to be synchronized >> externally. > > Yes, you are right. The lock is necessary to achieve the level of thread > safety that you implemented. I think that a "thread neutral" (as safe as > an int) future<> would be acceptable, since this is the thread safety > level I expect from lightweight CopyConstructible components, but that's > not a big deal. I was focusing on making the type sharable across threads in a thread safe manner. However, stepping back and thinking on it, I think that may have been the wrong approach. Most usage patterns won't involve this sharing, so paying the cost for synchronization regardless is probably not a good idea. I think it would be better to take the "thread neutral" approach. Thanks for getting me to think about this issue. -- William E. Kempf _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost