
On Sat, 10 Mar 2007 01:54:57 +0200, Peter Dimov wrote:
Braddock Gaskill wrote: My current proposal for std::future<R> is available at http://www.pdimov.com/cpp/N2185.html and will be part of the pre-meeting mailing. We'll see how it fares.
Thanks Peter, I coded up a quick straight-forward implementation of your proposal. I'll make it available as soon as I test it a little. Maybe it can be grafted into the vault implementation to provide composites, etc. I have a few questions/comments: 1) void set_exception( exception_ptr p); This is tricky. I don't really want to pass and throw to the caller an exception pointer because responsibility for deleting the exception pointer will be very difficult to get right. Imagine the case where two objects each hold references to the same future, and so the exception gets re-thrown twice as they both try to access the value. Which one delete's the exception pointer? Should the future handle deletion responsibilty when the last future<> reference is gone? What type should the pointer be? We can't assume that all exceptions are even derived from std::exception. Passing by value is a no-go because of slicing issues due to the unknown exact type of the exception (even the calling code probably won't know). 2) Are multiple calls to set_value() permitted for a single future object? Your prior proposal (N2096) returned the value by reference, implying that multiple set_value() calls could not be allowed. This proposal returns by value, so multiple calls are at least possible. IMHO, it should not be allowed. The future object does not have any way to ensure that the "consumer" gets every successive value the "producer" might set. Too confusing. 3) What should 'timespec' be? I'm using boost::threads::xtime 4) set_cancel_handle(thread::handle ) This thread handle seems to assume that future<> is being used with a thread-per-invocation, and does not appear to provide a mechanism for canceling a queued invocaction, which is necessary for at least my application. I'd need a generic "callback-on-cancel()". 5) join()/try_join() vs wait()/ready() As far as I can tell, you renamed the wait() and ready() to join() and try_join(). In my opinion, these names are far less clear, and again my anti-thread-per-invocation bias doesn't like the implied thread semantics. In particular, try_join() makes little sense in a polling context. A naive programmer would be more likely to want to use has_value() instead, which would be WRONG if the method throws. while (!has_value()) //infinite loop if has_exception do something; 6) operator R() const; My opinion here, but if I understand this then the semantics of this are far too subtle. future<int> x = std::fork(myfunc); //200 lines later z = x + y; // this blocks or throws, mystifying young programmers everywhere I liked your prior proposal N2096 which would have: z = x() + y; // x is not your grandfather's variable Also, what is the meaning of: mysubroutine(x) // Does this block or throw, or just use a future argument? What is the meaning if mysubroutine is declared: template<T> mysubroutine(T a); Thanks, Braddock Gaskill Dockside Vision Inc