On 17 Apr 2013 at 17:13, Holger Joukl wrote: > // the global per-thread exception storage > boost::unordered_map<pthread_t, boost::exception_ptr> exception_map;
You can't assume pthread_t is of integral type. You can a thread_t (from C11) I believe. You may not care on your supported platforms though. > throw std::runtime_error("throwing up"); If you're going to use Boost's exception_ptr implementation, you really ought to throw using Boost's exception throw macro. Otherwise stuff become unreliable. > void guarded_callback_with_exception(cb_arg_t arg) { > std::cout << "--> guarded exception-throwing CPP callback" << arg << > std::endl; > try { > throw std::runtime_error("throwing up"); > } catch (...) { > std::cout << "storing exception in exception map" << std::endl; > pthread_t current_thread = pthread_self(); > exception_map[current_thread] = boost::current_exception(); > exception_map.erase(current_thread); > //global_exception_holder = boost::current_exception(); > } > std::cout << "<-- guarded exception-throwing CPP callback" << arg << > std::endl; > } If you're just going to do this, I'd suggest you save yourself some hassle and look into packaged_task which is a std::function combined with a std::future. It takes care of the exception trapping and management for you. Do bear in mind there is absolutely no reason you can't use a future within a single thread to traverse some state over third party binary blob code, indeed I do this in my own code at times e.g. if Qt, which doesn't like exceptions, stands between my exception throwing code at the end of a Qt signal and my code which called Qt. > pthread_t current_thread = pthread_self(); > if (exception_map.find(current_thread) != exception_map.end()) { > try { > std::cout << "rethrowing exception from exception map" << > std::endl; > boost::rethrow_exception(exception_map[current_thread]); > } catch (const std::exception& exc) { > std::cout << "caught callback exception: " << exc.what() << > std::endl; > } > } Why not using thread local storage? > Which doesn't respect call function depth (how would I do that?) Keep a count of nesting levels, so if a callback calls a callback which calls a callback etc. > and doesn't use a queue; I suppose you mean using the lockfree queue for > threadsafe > access to the hash table. Maybe a hash table of lockfree queues. Depends on your needs. > I think I don't even need that for my use case as I basically > - call dispatch on a Boost.Python wrapped object > - which invokes the C libs dispatcher function > - which invokes the registered callbacks (these will usually be implemented > in Python) > > i.e. the same thread that produced the exception will need to handle it. Another possibly useful idea is to have the C libs dispatcher dispatch packaged_task's into a per-thread lock free queue which you then dispatch on control return when the C library isn't in the way anymore. Call it deferred callbacks :) > Thanks for the valuable hints! You're welcome. Niall -- Any opinions or advice expressed here do NOT reflect those of my employer BlackBerry Inc. Work Portfolio: http://careers.stackoverflow.com/nialldouglas/
SMime.p7s
Description: S/MIME cryptographic signature
_______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig