Boost logo

Boost Users :

From: Jonathan Turkanis (turkanis_at_[hidden])
Date: 2008-02-06 22:45:30


Stefan Arentz wrote:
>> Does anyone understand why the filtering and sink.write are not done
>> as part of the copy operation? The last two lines should be printed as
>> part of the copy process! It seems they are executed as part of
>> destructing these objects instead?
>
> I got a very useful hint on the #boost irc channel about this: calling
> out.reset() after the copy() made the code work correctly.
>
> I'm a confused about this though since the documentation of copy states:
>
> "The function template copy reads data from a given model of Source
> and writes it to a given model of Sink until the end of stream is
> reached. It then closes both components, using the function template
> close, and returns the number of characters written."
>
> But when looking at the source of copy() I see there is no close() done at all.

It's in there: see lines 132-33.

The problem is that filtering_stream does not model Closable, so close()
is a no-op. This is counterintuitive and probably represent a less than
ideal design, but when I wrote the library I couldn't think of a
satisfactory way to define close() for a filtering stream.

You might think that the way to define close() would simply be to close
all the filters and devices in the chain. Unfortunately, this is not
correct. The reason is that while filters are designed to be reusable,
devices are in general one-use only. For example, when a compression
filter is closed, it is expected to be in a state where it can be used
to compress a fresh stream of data. But when a file is closed, it is not
reset to the state it was in when it was first opened: it has to be
manually reopened with a new user-provided pathname. So simply closing
all the filters and devices in the chain would leave the chain in an
unusable state.

The closest I could come to defining a non-trivial close() for
filtering_streams was to have close() call pop() -- in effect, closing
all the filters and discarding the final device. However, my feeling was
that this behavior would be considered counterintuitive.

I knew this could cause problems with copy, but I decided to wait for
user feedback before making any changes. The issue never came up, and I
forgot about it until now. It could be that not many are using the
library, as you suggest, or that people discovered that you can solve
the problem by calling reset() or pop() -- as you heard on the IRC
channel -- and never bothered to bring it up on this list.

I've created a ticket for this issue:
http://svn.boost.org/trac/boost/ticket/1624. At the very least it should
be a FAQ.

> Is anyone actually using the library? I can't believe I'm the first
> finding a bug like this in a 5 year old library.
>
> S.

-- 
Jonathan Turkanis
CodeRage
http://www.coderage.com

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net