|
Boost : |
From: Jonathan Turkanis (technews_at_[hidden])
Date: 2004-09-11 19:58:34
"George M. Garner Jr." <gmgarner_at_[hidden]> wrote in message
news:ci01a3$a6n$1_at_sea.gmane.org...
> Johnathan,
>
>
> > Now for some real fun. I am going to try and attach an overlapped filebuf
> > to one of your
> >> streams. :-)
> >
> > Good luck!
> >
>
> That worked without a hitch.
Great!
> But that is only because my overlapped_filebuf
> uses blocking semantics.
Yeah, I know.
> My original goal was to be able to transparently
> interchange regular files and sockets as "sinks" and this will allow me to
> do that. But the std stream and filebuf interfaces are really a
> straight-jacket when it comes to more advanced applications, such as truly
> asynchronous io; and the sooner we realize that the better.
I agree. If you haven't already read it see 'Future Directions'
(http://tinyurl.com/6r8p2).
Forgive me if I repeat myself a bit:
My view is that to handle asynchronous i/o properly one will need to define an
AsyncronousResource concept. Using AsyncronousResources and filters one should
be able to define a number of different i/o abstractions, some of which may be
standard streams and stream buffers, but some of which may be entirely
different.
I think the crucial design question now is to make sure that current filters
will work with future AsyncronousResources, and I have tentatively concluded
that it suffices to give filters a way to indicate that fewer than the requested
number of characters have been read or written, even though EOF has not been
reached and no error has occured.
The only hard part is the return type of the member function get() for an input
filter. I suggested that it could return a class type convertible to the
character type which can be explicitly tested for eof or temporary
unavailability of data.
It would work like this:
"Jonathan Turkanis" <technews_at_[hidden]> wrote:
> ... looking at the alphabet_input filter from the tutorial, instead of
>
> struct alphabetic_input_filter : public input_filter {
> template<typename Source>
> int get(Source& src)
> {
> int c;
> while ((c = boost::io::get(src)) != EOF && !isalpha(c))
> ;
> return c;
> }
> };
>
> you'd write:
>
> struct alphabetic_input_filter : public input_filter {
> template<typename Source>
> int get(Source& src)
> {
> character c;
> while ((c = boost::io::get(src)).good() && !isalpha(c))
> ;
> return c;
> }
> };
> Here, eof and fail values are passed on to the caller unchanged. If you want
to
> send an eof or fail notification explicitly, you'd write return eof() or
return
> fail().
I'd like to get your input on this idea.
> Imagine if, for
> example, instead of doing write(char_type*, size_t) you could do
> write(ref_string<char_type>&) or
> write(ref_string_plus_overlapped<char_type>&). An observer could
> transparently pass the buffer to the next layer without modification while
> an asynchronous sink could take ownership of buffer by calling a swap()
> member function and then pass the buffer to a waiting thread. The buffer
> could grow or shrink as it passes from one filter to another. The buffer
> could even pass in round robin fashion back to its origin if every observer
> or filter called swap() in turn. But that is just a dream.
My hope is that this will all be possible. It sounds like you think we might
need AynchronousFilters as well. Is that right? I'm hoping to avoid this, since
I wouldn't want to force people to write several versions of rhe same filter,
one for blocking i/o, one for asyn i/o, etc.
In particular, I'm interested in interoperability with Hugo Duncan's library
(see http://tinyurl.com/w0f7 and http://tinyurl.com/6w2l ), but I haven't
contacted hime yet.
By the way, if I'm not mistaken, you haven't yet submitted a formal review.
Would you care to do so?
Best Regards,
Jonathan
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk