
Hi, the combination of asio and coroutines would seem to represent a little bit of magic (layering a linear code model over an async event framework and without the attendant issues involved in multithreading). However the coroutine library seems to be exception throwing in an unanticipated way when performing a wait on a future<> during the execution of an asio async operation. I am following the documention and am reasonably familiar with asio from other projects - but have only just worked through some of the examples from the coroutines documention. i am using the vault freeze version of coroutines from 2006 - i understand from perusing these lists that the library author is currently rewritting boost::coroutine around a continuation framework to simplify and in the hope that the library may be an official boost inclusion. Much kudos for contributing to c++ in a significant way ;-) the documentation seems to have some errors http://www.crystalclearsoftware.com/soc/coroutine/coroutine/asio.html - guidance is given to use shared_coroutine in preference to coroutine in asio context although this is not present in the example - asio uses the boost::system error classes in the boost namespace when not freestanding - the example calls wait() on source which is a socket type rather than a future I have attempted to work up an example which looks logical - but cant get around the throw that occurs at /boost/coroutine/detail/context_base.hpp:213 // linux 2.6.23, g++ (GCC) 4.1.2 // g++ -g main.cpp -lboost_coroutine-mt -lboost_system-mt #include <iostream> #include <boost/bind.hpp> #include <boost/ref.hpp> #include <boost/coroutine/coroutine.hpp> #include <boost/coroutine/generator.hpp> #include <boost/coroutine/future.hpp> #include <boost/asio.hpp> namespace coro = boost::coroutines; using namespace coro; typedef boost::asio::io_service service_type; //typedef coro::coroutine< void()> foo_coroutine_type; //typedef coro::coroutine< void( service_type &service)> foo_coroutine_type; typedef coro::shared_coroutine< void( service_type &service)> foo_coroutine_type; void foo( foo_coroutine_type::self &self, service_type &service) { typedef boost::system::error_code error_type; typedef boost::asio::ip::tcp::resolver::query query_type; typedef boost::asio::ip::tcp::resolver::iterator iterator_type; boost::asio::ip::tcp::resolver resolver( service); query_type query( "www.boost.org", 80 ); coro::future< error_type, iterator_type> future( self); resolver.async_resolve( query, coro::make_callback( future)); assert( !future); // wait throws here --> /boost/coroutine/detail/context_base.hpp:213 coro::wait( future); assert( future); error_type &error = future->get< 0>(); if( error) std::cout << "error resolving " << error.message() << std::endl; else { iterator_type ip = future->get< 1>(); while( ip != iterator_type()) std::cout << ip->endpoint() << std::endl; } } int main() { service_type service; foo_coroutine_type cfoo( boost::bind( &foo, _1, boost::ref( service))); cfoo(); // service.post( boost::bind( &foo_coroutine_type::operator(void ), &cfoo)); service.run(); }