Boost logo

Boost :

Subject: Re: [boost] [afio] Formal review of Boost.AFIO
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2015-08-28 18:36:56


On 28 Aug 2015 at 17:18, Gavin Lambert wrote:

> > afio::future<> has a single errored or exceptioned state.
>
> Then FYI, the wording of the first Description paragraph in
> https://boostgsoc13.github.io/boost.afio/doc/html/afio/reference/classes/future.html
> is potentially confusing in that regard, since it seems to be discussing
> error states for "both".

It means both get() and get_handle().

> > I suppose you're right, it's not far from being a
> > std::future<std::tuple<afio::handle_ptr, T>>. The big problem with
> > std::future<std::tuple<afio::handle_ptr, T>> is it's ABI poison
> > because of the unknown T passing through an ABI boundary, so you'd
> > have to type erase which means an extra memory allocation before
> > crossing the ABI.
>
> Perhaps I'm missing something again, but where do you need to do that?
>
> If you mean when passing preconditions back, that could still just
> discard T to void as you're doing now -- assuming you can convert a
> tuple<handle_ptr, T> to tuple<handle_ptr, void> or tuple<handle_ptr>.
>
> Again, I'm not sure how complex this is or whether it would be "worth
> it", but it does seem like a cleaner design to treat the handle and
> other data as the composite value of the future.

Maybe. Where I was coming from was that if you go with
std::future<std::tuple<afio::handle_ptr, T>>, it implies you are able
to send some T past the AFIO ABI which you cannot without losing ABI
stability. I would worry that by hiding the implicit conversion from
std::future<std::tuple<afio::handle_ptr, T>> into
std::future<std::tuple<afio::handle_ptr>> somewhere in
metaprogramming land instead of explicitly declaring in your public
API that you only accept std::future<std::tuple<afio::handle_ptr>>
and nothing but std::future<std::tuple<afio::handle_ptr>>, and
therefore that conversion happens in the end user's code, you are
opening up a can of worms regarding end user expectations.

In other words, if all APIs accept only
std::future<std::tuple<afio::handle_ptr>> there is no risk for
disappointment.

> Another possibility would be to explicitly separate the handle_ptr.
> Most functions would then change from accepting a future<void> to
> accepting a future<handle_ptr>, since that's the value they actually
> need to do the work. For dependency order tracking you can just use the
> depends() helper you mentioned earlier, eg:
>
> afio::future<handle_ptr> openfile = afio::async_file(...);
> afio::future<void> resizedfile = afio::async_truncate(openfile, 12);
> ...
> afio::future<void> written = afio::async_write(depends(resizedfile,
> openfile), buffers, 0);
> ...
>
> So the write depends on resizedfile being done, but that *doesn't* carry
> a file handle -- the only one that does is openfile. (depends, of
> course, would tolerate different Ts for its parameter futures, and will
> return the second one's type.)
>
> This is perhaps more like how people are used to working with futures,
> rather than having them carry around extra values.

I'd live comfortably with what you just proposed. In fact, it was my
second preference API design after the one I chose. I felt originally
that making the end user write depends() all over the place would be
irritating, but maybe it's better to force the end user to always be
explicit about what operations relate to which others.

Niall

-- 
ned Productions Limited Consulting
http://www.nedproductions.biz/ 
http://ie.linkedin.com/in/nialldouglas/



Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk