
It's occurred to me that support for reference counting futures (which Peter Dimov has suggested a couple times) could be added simply by adding a method to the promise class bool promise::has_future() const; The has_future query would not alter the state of the promise (it wouldn't put it into some unusable "expired" state). It would simply allow the promise-setting thread to query if there are any futures and take whatever action it chooses. So it wouldn't put any burden on someone who wants to code a fire-and-forget function that returns a future that may be safely discarded. In a typical implementation, has_future might boil down to a call of shared_ptr::unique(). This works because threads don't block waiting on promises, only on futures. When a future's promise is destroyed without ever being fulfilled, action has to be taken to give the waiting futures an exception to prevent a thread from blocking forever in vain. But if a promise's last future disappears, it doesn't need to take any action. All it needs to do is provide a query that can be used by interested code to detect that fact. Also, for debugging a unsigned promise::future_count() const; method could be provided, which might be implemented by returning the value of shared_ptr::use_count minus one. Any thoughts? These functions could be added independently of whether or not an explicit future::cancel() is supported.

Frank Mori Hess-2 wrote:
It's occurred to me that support for reference counting futures (which Peter Dimov has suggested a couple times) could be added simply by adding a method to the promise class
bool promise::has_future() const;
The has_future query would not alter the state of the promise (it wouldn't put it into some unusable "expired" state). It would simply allow the promise-setting thread to query if there are any futures and take whatever action it chooses. So it wouldn't put any burden on someone who wants to code a fire-and-forget function that returns a future that may be safely discarded. In a typical implementation, has_future might boil down to a call of shared_ptr::unique().
This works because threads don't block waiting on promises, only on futures. When a future's promise is destroyed without ever being fulfilled, action has to be taken to give the waiting futures an exception to prevent a thread from blocking forever in vain. But if a promise's last future disappears, it doesn't need to take any action. All it needs to do is provide a query that can be used by interested code to detect that fact.
Also, for debugging a
unsigned promise::future_count() const;
method could be provided, which might be implemented by returning the value of shared_ptr::use_count minus one.
Any thoughts? These functions could be added independently of whether or not an explicit future::cancel() is supported.
Do you propose to remove reference counting from futures and use shared_ptr<future<..>> instead? I believe the main motivation for a unique_future was to be able to move large/expensive types in the get-function instead of copying them. shared_future<R> requires it's client to copy the data to move it into their own data structures. It has the following signature: R const & get() const; unique_future<R> moves the value out of the future and is "consumed" once get() has been called. It has the following signature: R&& get(); I don't like having both shared_future and unique_future either. One could perhaps distinguish between move-get and const_ref-get somehow and only allow the former if use_count == 1. One problem is that the promise typically belongs to some other thread and new futures can be created concurrently after having queried use_count. Another option is declaring whether the future is unique or shared as a parameter in the futures constuctor. An exception could be thrown if you try to create more futures from a uniquely "owned" promise. Not distuinguishing between unique and shared might remove some type safety and clarity in user code. Some of the N2627 future proposal authors can probably provide more insight. Johan -- View this message in context: http://www.nabble.com/-futures--reference-counted-futures-tp17503260p1750907... Sent from the Boost - Dev mailing list archive at Nabble.com.

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Wednesday 28 May 2008 05:55 am, Johan Torp wrote:
Do you propose to remove reference counting from futures and use shared_ptr<future<..>> instead?
No, the mentions I made of shared_ptr were not important. I was only trying to convey that promise::has_future could be easily implemented by imagining a typical implementation of promise/future where they both are implemented by having a shared_ptr to some common object.
I believe the main motivation for a unique_future was to be able to move large/expensive types in the get-function instead of copying them.
shared_future<R> requires it's client to copy the data to move it into their own data structures. It has the following signature: R const & get() const;
unique_future<R> moves the value out of the future and is "consumed" once get() has been called. It has the following signature: R&& get();
I don't like having both shared_future and unique_future either. One could perhaps distinguish between move-get and const_ref-get somehow and only allow the former if use_count == 1. One problem is that the promise typically belongs to some other thread and new futures can be created concurrently after having queried use_count. Another option is declaring whether the future is unique or shared as a parameter in the futures constuctor. An exception could be thrown if you try to create more futures from a uniquely "owned" promise.
Not distuinguishing between unique and shared might remove some type safety and clarity in user code. Some of the N2627 future proposal authors can probably provide more insight.
This seems unrelated to what I was trying to get at with promise::has_future. The idea is a promise-fulfilling thread can query promise::has_future if it likes, and choose to exit early if there are no futures out there that might be interested in its result value. Or, if the promise-fulfilling thread is intended to cause some side-effects independent of setting futures, it can proceed and ignore promise::has_future. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iD8DBQFIPVTC5vihyNWuA4URAnD6AJ9aIPeYkU59JV5i/XOAlN65rV3w2wCfbJs9 XjYN/k3k3HaOXslKjl24XCw= =YQS7 -----END PGP SIGNATURE-----
participants (3)
-
Frank Mori Hess
-
Frank Mori Hess
-
Johan Torp