Boost logo

Boost :

Subject: [boost] [iostreams] Inconsistency of "faiture" of writes in Sinks and filters
From: Artyom (artyomtnk_at_[hidden])
Date: 2010-10-23 15:29:30


Hello,

I implement the sink device that sometimes may fail on writes.

When Sink is implemented it should throw an exception on fault. To notify
the stream on error.

However it is not always works this way. I've got the exception to "leak" to the
main program when I combine in the filter gzip_comressor() filter that writes
to output device that its Sink is full. When I call reset on the filter
the exception in leaking to the program instead of being caught.

Is it bug or (accidental) feature?

On the other hand, if I don't throw but rather return 0, I get into infinite
loop
in the boost::iostreams::non_blocking_adapter::write when I call filter.reset().

So I how can I write a sink device that reports errors?

In following example the exception is caught when filter.reset() is called:

    #include <boost/iostreams/stream.hpp>
    #include <boost/iostreams/filtering_stream.hpp>
    #include <boost/iostreams/filter/gzip.hpp>
    #include <boost/iostreams/tee.hpp>
    #include <iostream>

    class my_small_device : public boost::iostreams::sink
    {
        int count;
    public:
        my_small_device() : count(1000) {}
        std::streamsize write(char const *d,std::streamsize n)
        {
            if(count < n)
                throw std::runtime_error("Device is full");
            count-=n;
            return n;
        }
    };

    int main()
    {
        try {
            using namespace boost::iostreams;
            boost::iostreams::stream<my_small_device>
output(my_small_device(),10);
            {
                boost::iostreams::filtering_ostream filter;
                filter.push(gzip_compressor());
                filter.push(output);
                for(int i=0;i<10000000;i++) {
                    if(!(filter << i << '\n')) {
                        std::cerr << "Fail!" << std::endl;
                        break;
                    }
                }
                std::cout << "Closing filter" << std::endl;
                filter.reset();
            }

            std::cout << "ok" << std::endl;
            return 0;
        }catch(std::exception const &e) {
            std::cerr << "Catched " << e.what() << std::endl;
            return 1;
        }
    }

Thanks,
   Artyom

      


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