In fact, these functions call the do_one function, which is used to obtain the complete port status. All timers and network events are scheduled through do_one, do_one function prototype:
size_t do_one(bool block, boost::system::error_code& ec)
Its first parameter indicates whether it is blocked, in the do_one code:
BOOL ok = ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred, &completion_key, &overlapped, block ? timeout : 0);
If it is false, the wait time is 0 (that is, it is not blocked ).
The implementation of run, run_one, poll, and poll_one is also quite simple, as follows:
// Run the event loop until stopped or no more work.size_t run(boost::system::error_code& ec){ if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) { stop(); ec = boost::system::error_code(); return 0; } call_stack<win_iocp_io_service>::context ctx(this); size_t n = 0; while (do_one(true, ec)) if (n != (std::numeric_limits<size_t>::max)()) ++n; return n;}// Run until stopped or one operation is performed.size_t run_one(boost::system::error_code& ec){ if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) { stop(); ec = boost::system::error_code(); return 0; } call_stack<win_iocp_io_service>::context ctx(this); return do_one(true, ec);}// Poll for operations without blocking.size_t poll(boost::system::error_code& ec){ if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) { stop(); ec = boost::system::error_code(); return 0; } call_stack<win_iocp_io_service>::context ctx(this); size_t n = 0; while (do_one(false, ec)) if (n != (std::numeric_limits<size_t>::max)()) ++n; return n;}// Poll for one operation without blocking.size_t poll_one(boost::system::error_code& ec){ if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0) { stop(); ec = boost::system::error_code(); return 0; } call_stack<win_iocp_io_service>::context ctx(this); return do_one(false, ec);}
We can see that run is always executing do_one cyclically, and is blocked (the parameter is true), while run_one is also blocked, but only do_one is executed once; poll and run are almost identical, but it executes do_one in non-blocking mode (the parameter is false), and poll_one executes do_one in non-blocking mode.
Link: http://my.oschina.net/jackwgm/blog/6314