スレッドを超えて例外を伝播させる
今日は少し脱線して、以前から試してみたかった、スレッドを超えて例外を伝播させることに挑戦してみました。
propagate_test.cpp
とりあえず、g++限定です。
例外オブジェクトはスタックに置くことはできないので、ヒープや自由領域と似たメモリに置かれているはずで、そのポインタだけを付け替えるのであればノーコストで失敗しない(コピーによる例外発生の可能性がない)はずだという考えに基づいて、ごにょごにょやっています。
よく分かってないメンバとかあるので、多分メモリリークしてます。
テストコードはこんな感じです。
#include <boost/bind.hpp> #include <boost/thread.hpp> class my_thread { public: my_thread() : e_(0), t_(boost::bind(&my_thread::work, this)) { } void wait() { t_.join(); if (e_) rethrow_exception(e_); } private: boost::thread t_; my_cxa_exception* e_; void work() { try { throw std::runtime_error("error!"); } catch (...) { e_ = release_exception(); } } }; int main() { try { my_thread t; t.wait(); } catch (const std::runtime_error& e) { std::cout << "caught runtime_error: " << e.what() << std::endl; } catch (...) { std::cout << "unknown exception" << std::endl; } }
実行結果
caught runtime_error: error!
例外の連鎖なんかにも使えそうです。