在asio_1.12.1 win_iocp_socket_service_base.ipp中,我在这种模式下发现了许多类似的代码:
start_async_action(...){//for example: start_send_op、 start_connect_op
...
iocp_service_work_started();
...
int result = ::WSA_IO_OPERATION(...); //such as WSASend、WSARecv
DWORD last_error = ::WSAGetLastError();
if (result != 0 /*or !result */ && last_error != WSA_IO_PENDING)
iocp_service_.on_completion(...); //means IO completed immediately
else
iocp_service_.on_pending(op);
注意:它是iocp_service_.on_completion(...)
,与op->on_complete(...)
中的do_one
在多次跟踪程序后,始终调用on_pending
,但从未看到调用on_completion
。如何使场景调用此功能?
我认为当IO操作立即完成时,它将调用on_completion
,这可能会导致GetQueueCompletionStatus
被绕开,因此on_completion
进入了回调,消息是由PostQueueCompletionStatus
发布的。
Ps:我在libuv中找到了代码,通过WSA操作标志绕过GetQueueComletionStatus
,但在asio中不习惯调用on_completion
:
result = WSARecv(handle->socket,
(WSABUF*)&buf,
1,
&bytes,
&flags, /*flag for with or without IOCP */
&req->u.io.overlapped,
NULL);
if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
/* Process the req without IOCP. */
handle->flags |= UV_HANDLE_READ_PENDING;
req->u.io.overlapped.InternalHigh = bytes;
handle->reqs_pending++;
uv_insert_pending_req(loop, (uv_req_t*)req); }