Hi,
 
The following causes an assertion failure (in iostreams::detail::optional::operator*()) when destroying the filtering_stream:
 
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/code_converter.hpp>
#include <boost/iostreams/device/file_descriptor.hpp>
#include <windows.h>

namespace io = boost::iostreams;

int main (void)
{

io::wfiltering_stream<io::output> out;

HANDLE h = CreateFileW(L"test.txt",

GENERIC_WRITE | GENERIC_READ,

FILE_SHARE_READ,

NULL,

OPEN_ALWAYS,

0,

NULL );

out.push(

io::code_converter<io::file_descriptor_sink>(

io::file_descriptor_sink(h, true)

)
);

out << L"Hello world!";

 

return 0;

}

If I add "out.pop()" before returning, there is no assertion.
Looking deeper, it turns out that iostreams::chain's dtor calls close(); and reset();, and both end up calling close() on the code_converter. And code_converter is not "multi-closable". IOW, I get the same assertion failure with:

HANDLE h = CreateFile(/*...*/);

io::code_converter<io::file_descriptor_sink> cvt(io::file_descriptor_sink(h, true));

cvt.close();

cvt.close(); //<< Asserts here

To fix this, I made it possible to call code_converter::close() multiple times by simply adding:

if (!(this->is_open())){
return;
}

right at the beginning of code_converter::close().

 

Am I right in assuming that it should be possible to close() a Device or Filter multiple times ?

Anyone has comments on this proposed fix?

 

-----------------------------
Éric
Quidquid latine dictum sit, altum viditur.