void CPluginTransportTCP::handleAsyncConnect(const boost::system::error_code & err, boost::asio::ip::tcp::resolver::iterator endpoint_iterator) { delete m_Resolver; m_Resolver = NULL; if (!err) { m_bConnected = true; m_Socket->async_read_some(boost::asio::buffer(m_Buffer, sizeof m_Buffer), boost::bind(&CPluginTransportTCP::handleRead, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); if (ios.stopped()) // make sure that there is a boost thread to service i/o operations { ios.reset(); _log.Log(LOG_NORM, "PluginSystem: Starting I/O service thread."); boost::thread bt(boost::bind(&boost::asio::io_service::run, &ios)); } } else { delete m_Socket; m_Socket = NULL; // _log.Log(LOG_ERROR, "Plugin: Connection Exception: '%s' connecting to '%s:%s'", err.message().c_str(), m_IP.c_str(), m_Port.c_str()); } ConnectedMessage* Message = new ConnectedMessage(m_HwdID, err.value(), err.message()); boost::lock_guard<boost::mutex> l(PluginMutex); PluginMessageQueue.push(Message); }
void io_service_work( boost::asio::io_service& ios ) { while( !boost::this_thread::interruption_requested() ){ try{ ios.run(); }catch( boost::system::error_code &e ){ shot<connect_error>( boost::ref(e) ); }catch( boost::system::system_error & e ){ shot<system_error>( boost::ref(e) ); }catch( std::exception& e ){ shot<exception>( boost::ref(e) ); }catch(...){ assert(0); } if( ios.stopped() ){ boost::this_thread::sleep( boost::posix_time::milliseconds(10) ); ios.reset(); } } }
// MsgWaitForMultipleObjectsEx 集成进去. static inline void avloop_run_gui(boost::asio::io_service& io_service) { using namespace ::detail; boost::asio::io_service::work work(io_service); if (!boost::asio::has_service<IdleService>(io_service)) boost::asio::add_service(io_service, new IdleService(io_service)); if (!boost::asio::has_service<Win32MsgLoopService>(io_service)) boost::asio::add_service(io_service, new Win32MsgLoopService(io_service)); while (!io_service.stopped()) { // 首先处理 asio 的消息. while (io_service.poll()) { // 然后执行 gui 循环,看有没有 gui 事件. if (boost::asio::use_service<Win32MsgLoopService>(io_service).has_message()) { // 执行以下. boost::asio::use_service<Win32MsgLoopService>(io_service).poll_one(); } } // 然后执行 gui 循环,看有没有 gui 事件. while(boost::asio::use_service<Win32MsgLoopService>(io_service).has_message()) { // 执行以下. boost::asio::use_service<Win32MsgLoopService>(io_service).poll_one(); } // 执行 idle handler! if (boost::asio::use_service<IdleService>(io_service).has_idle()) boost::asio::use_service<IdleService>(io_service).poll_one(); // 都没有事件了,执行 一次 1ms 的超时等待. auto ret = MsgWaitForMultipleObjectsEx(0, nullptr, 1, QS_ALLEVENTS, MWMO_WAITALL|MWMO_ALERTABLE | MWMO_INPUTAVAILABLE); // 可能是有 gui 消息了, 呵呵, 从头来吧. } }
static inline void avloop_run(boost::asio::io_service& io_service) { using namespace ::detail; if (!boost::asio::has_service<IdleService>(io_service)) boost::asio::add_service(io_service, new IdleService(io_service)); while (!io_service.stopped()) { if(!boost::asio::use_service<IdleService>(io_service).has_idle()) { if (!io_service.run_one()) break; } else { while (io_service.poll()); // 执行 idle handler! boost::asio::use_service<IdleService>(io_service).poll_one(); } } }
bool CPluginTransportTCP::handleConnect() { try { if (!m_Socket) { m_bConnected = false; m_Resolver = new boost::asio::ip::tcp::resolver(ios); m_Socket = new boost::asio::ip::tcp::socket(ios); boost::system::error_code ec; boost::asio::ip::tcp::resolver::query query(m_IP, m_Port); boost::asio::ip::tcp::resolver::iterator iter = m_Resolver->resolve(query); boost::asio::ip::tcp::endpoint endpoint = *iter; // // Async resolve/connect based on http://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/example/http/client/async_client.cpp // m_Resolver->async_resolve(query, boost::bind(&CPluginTransportTCP::handleAsyncResolve, this, boost::asio::placeholders::error, boost::asio::placeholders::iterator)); if (ios.stopped()) // make sure that there is a boost thread to service i/o operations { ios.reset(); _log.Log(LOG_NORM, "PluginSystem: Starting I/O service thread."); boost::thread bt(boost::bind(&boost::asio::io_service::run, &ios)); } } } catch (std::exception& e) { // _log.Log(LOG_ERROR, "Plugin: Connection Exception: '%s' connecting to '%s:%s'", e.what(), m_IP.c_str(), m_Port.c_str()); ConnectedMessage* Message = new ConnectedMessage(m_HwdID, -1, std::string(e.what())); boost::lock_guard<boost::mutex> l(PluginMutex); PluginMessageQueue.push(Message); return false; } return true; }
service( boost::asio::io_service & io_svc) : boost::asio::io_service::service( io_svc), work_{ new boost::asio::io_service::work( io_svc) } { io_svc.post([&io_svc](){ //] //[asio_rr_service_lambda while ( ! io_svc.stopped() ) { if ( boost::fibers::has_ready_fibers() ) { // run all pending handlers in round_robin while ( io_svc.poll() ); // run pending (ready) fibers this_fiber::yield(); } else { // run one handler inside io_service // if no handler available, block this thread if ( ! io_svc.run_one() ) { break; } } } //] //[asio_rr_service_bottom }); }