thomasmoelhave / tpie

Templated Portable I/O Environment
Other
112 stars 24 forks source link

File stream throwing exception from compressor thread #189

Open svendcs opened 9 years ago

svendcs commented 9 years ago

Currently if writing fails when using a file stream, it throws an exception from the compressor thread, since this is the thread in which the file accessor is used. This, however, makes it difficult to catch the exception in client code.

The following example demonstrates this behaviour by writing to a read_only file stream. An uncaught exception is thrown from the compressor thread.

#include <iostream>
#include <tpie/stream.h>

 int main() {
    tpie::tpie_init();

    tpie::file_stream<int> fs;
    fs.open("file.txt", tpie::access_write);
    fs.write(42);
    fs.close();

    fs.open("file.txt", tpie::access_read);
    try {
        fs.write(42);
        fs.close();
    }
    catch(tpie::io_exception e) {
        std::cout << "Should throw exception" << std::endl;
    }

    tpie::tpie_finish();

    return 0;
 }

Output from LLDB:

(lldb) run
Process 65857 launched: '/Users/svendcs/Projects/TPIE_TESTING/program' (x86_64)
libc++abi.dylib: terminating with uncaught exception of type tpie::io_exception: Bad file descriptor
Process 65857 stopped
* thread #2: tid = 0x22fc9f, 0x00007fff96e3b286 libsystem_kernel.dylib`__pthread_kill + 10, stop reason = signal SIGABRT
    frame #0: 0x00007fff96e3b286 libsystem_kernel.dylib`__pthread_kill + 10
libsystem_kernel.dylib`__pthread_kill:
->  0x7fff96e3b286 <+10>: jae    0x7fff96e3b290            ; <+20>
    0x7fff96e3b288 <+12>: movq   %rax, %rdi
    0x7fff96e3b28b <+15>: jmp    0x7fff96e36c53            ; cerror_nocancel
    0x7fff96e3b290 <+20>: retq   
(lldb) bt
* thread #2: tid = 0x22fc9f, 0x00007fff96e3b286 libsystem_kernel.dylib`__pthread_kill + 10, stop reason = signal SIGABRT
  * frame #0: 0x00007fff96e3b286 libsystem_kernel.dylib`__pthread_kill + 10
    frame #1: 0x00007fff9614b42f libsystem_pthread.dylib`pthread_kill + 90
    frame #2: 0x00007fff893f5b53 libsystem_c.dylib`abort + 129
    frame #3: 0x00007fff93554a21 libc++abi.dylib`abort_message + 257
    frame #4: 0x00007fff9357c9b9 libc++abi.dylib`default_terminate_handler() + 243
    frame #5: 0x00007fff8a63f7eb libobjc.A.dylib`_objc_terminate() + 124
    frame #6: 0x00007fff9357a0a1 libc++abi.dylib`std::__terminate(void (*)()) + 8
    frame #7: 0x00007fff93579b30 libc++abi.dylib`__cxa_throw + 121
    frame #8: 0x0000000100015b74 program`tpie::file_accessor::posix::throw_errno() + 660 at posix.inl:36
    frame #9: 0x00000001000158a6 program`tpie::file_accessor::posix::write_i(this=0x00007fff5fbff924, data=0x0000000102700000, size=4) + 70 at posix.inl:86
    frame #10: 0x0000000100014e4e program`tpie::file_accessor::byte_stream_accessor<tpie::file_accessor::posix>::write(this=0x00007fff5fbff918, byteOffset=0, data=0x0000000102700000, size=4) + 110 at byte_stream_accessor.h:68
    frame #11: 0x0000000100014349 program`tpie::compressor_thread::impl::process_write_request(this=0x0000000100404bf0, wr=0x0000000102586d40) + 425 at thread.cpp:227
    frame #12: 0x000000010000e202 program`tpie::compressor_thread::impl::run(this=0x0000000100404bf0) + 1170 at thread.cpp:129
    frame #13: 0x000000010000d3d8 program`tpie::compressor_thread::run(this=0x00000001000d43c8) + 24 at thread.cpp:383
    frame #14: 0x000000010000d130 program`(anonymous namespace)::run_the_compressor_thread() + 16 at thread.cpp:325
    frame #15: 0x000000010000fb16 program`boost::detail::thread_data<void (*)()>::run(this=0x0000000100600640) + 22 at thread.hpp:116
    frame #16: 0x00000001003066c5 libboost_thread-mt.dylib`boost::(anonymous namespace)::thread_proxy(void*) + 53
    frame #17: 0x00007fff96149268 libsystem_pthread.dylib`_pthread_body + 131
    frame #18: 0x00007fff961491e5 libsystem_pthread.dylib`_pthread_start + 176
    frame #19: 0x00007fff9614741d libsystem_pthread.dylib`thread_start + 13
(lldb)