[iostreams] Issue with closing of filters (esp. tee_filter)
I am running into an issue with iostreams related to the closing of filters
(tee_filter in particular) and I think I really need a little help. Thanks
in advance to anyone patient enough to read through the following.
I created a multichar_output_filter called ChecksumFilter. It outputs a crc
for every 4K of data streamed into it. I am using in conjunction with a
tee_filter to stream out a file of checksums in parallel with another file
stream.
Unfortunately, ChecksumFilter::close() is not invoked at times when I
believe it should be, resulting in the checksum for the final chunk of data
not getting pushed out.
The following code shows the problem:
typedef boost::iostreams::composite
From closer.hpp:
template<>
struct close_impl
From tee.hpp:
template<typename Device>
class tee_filter : public detail::basic_adapter<Device> {
public:
...
template<typename Next>
void close( Next&,
BOOST_IOS::openmode which =
BOOST_IOS::in | BOOST_IOS::out )
{ iostreams::close(this->component(), which); }
...
};
The original openmode at the start of the close chain is BOOST_IOS::out, but
the close_impl's two close methods discard that openmode when they call
t.close() or t.close(nb).
This means that tee_filter's close() sets openmode to its default value of
BOOST_IOS::in | BOOST_IOS::out. This mode is passed along to
iostreams::close(), which ends up back in close_impl close() again as it is
attempting to close the ChecksumFilter. However, now the check "if (in ==
((which & BOOST_IOS::in) != 0))" fails, and so ChecksumFilter.close() is
never invoked.
If I change the default value for openmode in tee_filter::close() to
BOOST_IOS::out, everything works OK for me, but I am not really sure that
this is the right thing to do.
It appears that some kind of custom closing in closer.hpp could be done for
tee_filters that would pass through the openmode, much like the handling for
classes that support the two_sequence tag (sorry if I am jumbling
terminology a bit here). But I am not sure my understanding of the overall
code is strong enough to do the right thing here either.
Can anyone help me out or put me in touch with someone who can?
Much thanks!
Chad Walters
PS: And if you read this far, you probably understand the iostreams library
more than well enough to confirm whether the possible (likely?) bug I
reported earlier this week is really a bug (nobody has replied as of yet):
At the bottom of concepts.hpp, the following typedefs appear:
typedef multichar_filter<input> multichar_input_filter;
typedef multichar_filter<input> multichar_input_wfilter;
typedef multichar_filter<output> multichar_output_filter;
typedef multichar_filter<output> multichar_output_wfilter;
typedef multichar_filter
Chad Walters wrote:
[...]
This means that tee_filter's close() sets openmode to its default value of BOOST_IOS::in | BOOST_IOS::out. This mode is passed along to iostreams::close(), which ends up back in close_impl close() again as it is attempting to close the ChecksumFilter. However, now the check "if (in == ((which & BOOST_IOS::in) != 0))" fails, and so ChecksumFilter.close() is never invoked.
If I change the default value for openmode in tee_filter::close() to BOOST_IOS::out, everything works OK for me, but I am not really sure that this is the right thing to do.
It seems like a issue with close_impl
PS: And if you read this far, you probably understand the iostreams library more than well enough to confirm whether the possible (likely?) bug I reported earlier this week is really a bug (nobody has replied as of yet):
At the bottom of concepts.hpp, the following typedefs appear:
typedef multichar_filter<input> multichar_input_filter; typedef multichar_filter<input> multichar_input_wfilter; typedef multichar_filter<output> multichar_output_filter; typedef multichar_filter<output> multichar_output_wfilter; typedef multichar_filter
multichar_dual_use_filter; typedef multichar_filter multichar_dual_use_wfilter; I think the wfilter versions of these typedefs should use multichar_wfilter<...>. Agreed?
A copy-n-paste bug !? My $0.02
participants (2)
-
Chad Walters
-
gchen