On 27 Aug 2015 at 16:33, Gavin Lambert wrote:
If on the other hand you DO always want to delete and close the file no matter what happened before you would write:
auto a=async_file(); auto b=async_read(a); auto c=async_truncate(b); auto d=async_rmfile(depends(c, a)); auto e=async_close(d);
The depends(precondition, input) function swaps the second future for the first when the first completes. It is implemented as:
precondition.then([input](future &&f) { return input; }
That's handy but possibly a little unobvious (not that I can think of a better way to do it at the moment).
(Also, what happens if the passed/returned future isn't ready yet? Does the caller cascade the wait / re-register itself as a continuation? Or is that an error?)
If the future is not ready, it schedules a continuation. If the future is ready, it executes the continuation immediately (as per the Concurrency TS).
It occurs to me that the above is exactly what should be on a first page of a tutorial. To be honest, it never occurred to me the above wasn't totally obvious. So I've logged that to https://github.com/BoostGSoC13/boost.afio/issues/97.
Thanks Gavin.
Sounds good.
I know error-checking is often elided from examples for brevity, but it does seem like it needs covering somewhere. Although I'm also being a bit nit-picky, admittedly.
Not at all. I've taken pains to make utterly sure that errors are never lost and never cause data loss. The AFIO engine also prints a stack backtrace of where an error occurred, both within the engine and where in user code the operation was scheduled. Indeed, I may have been a bit excessive, and let me explain. Nobody seems to have noticed yet that if a precondition is errored at the point of entering a function trying to schedule things against it, it will immediately rethrow its error as if .get() had been called upon it e.g. auto a=async_file(); auto b=async_read(a); // we go do something for a while, and during that time the // async_read fails causing b to become errored auto c=async_truncate(b); // this will throw, immediately The advantage of this is that errors appear as soon as possible. The disadvantage is that it makes every single afio::async_* function a potential throw point which only throws under very exceptional circumstances e.g. thrashing the swap file which is therefore likely to not be well tested. Another disadvantage is you are converting any error_code based state into an exception throw, and it's extra handling to reverse that conversion. I was hoping for boost-dev feedback on this design choice, and if it is felt this is being overly paranoid, would simply pretending the precondition state is not known be safe? Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/