void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle, uv_req_t* req) { DWORD bytes, avail; uv_buf_t buf; uv_ipc_frame_uv_stream ipc_frame; assert(handle->type == UV_NAMED_PIPE); handle->flags &= ~UV_HANDLE_READ_PENDING; eof_timer_stop(handle); if (!REQ_SUCCESS(req)) { /* An error occurred doing the 0-read. */ if (handle->flags & UV_HANDLE_READING) { uv_pipe_read_error_or_eof(loop, handle, GET_REQ_ERROR(req), uv_null_buf_); } } else { /* Do non-blocking reads until the buffer is empty */ while (handle->flags & UV_HANDLE_READING) { if (!PeekNamedPipe(handle->handle, NULL, 0, NULL, &avail, NULL)) { uv_pipe_read_error_or_eof(loop, handle, GetLastError(), uv_null_buf_); break; } if (avail == 0) { /* There is nothing to read after all. */ break; } if (handle->ipc) { /* Use the IPC framing protocol to read the incoming data. */ if (handle->remaining_ipc_rawdata_bytes == 0) { /* We're reading a new frame. First, read the header. */ assert(avail >= sizeof(ipc_frame.header)); if (!ReadFile(handle->handle, &ipc_frame.header, sizeof(ipc_frame.header), &bytes, NULL)) { uv_pipe_read_error_or_eof(loop, handle, GetLastError(), uv_null_buf_); break; } assert(bytes == sizeof(ipc_frame.header)); assert(ipc_frame.header.flags <= (UV_IPC_TCP_SERVER | UV_IPC_RAW_DATA | UV_IPC_TCP_CONNECTION)); if (ipc_frame.header.flags & UV_IPC_TCP_SERVER) { assert(avail - sizeof(ipc_frame.header) >= sizeof(ipc_frame.socket_info)); /* Read the TCP socket info. */ if (!ReadFile(handle->handle, &ipc_frame.socket_info, sizeof(ipc_frame) - sizeof(ipc_frame.header), &bytes, NULL)) { uv_pipe_read_error_or_eof(loop, handle, GetLastError(), uv_null_buf_); break; } assert(bytes == sizeof(ipc_frame) - sizeof(ipc_frame.header)); /* Store the pending socket info. */ assert(!handle->pending_ipc_info.socket_info); handle->pending_ipc_info.socket_info = (WSAPROTOCOL_INFOW*)malloc(sizeof(*(handle->pending_ipc_info.socket_info))); if (!handle->pending_ipc_info.socket_info) { uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); } *(handle->pending_ipc_info.socket_info) = ipc_frame.socket_info; handle->pending_ipc_info.tcp_connection = ipc_frame.header.flags & UV_IPC_TCP_CONNECTION; } if (ipc_frame.header.flags & UV_IPC_RAW_DATA) { handle->remaining_ipc_rawdata_bytes = ipc_frame.header.raw_data_length; continue; } } else { avail = min(avail, (DWORD)handle->remaining_ipc_rawdata_bytes); } } buf = handle->alloc_cb((uv_handle_t*) handle, avail); assert(buf.len > 0); if (ReadFile(handle->handle, buf.base, buf.len, &bytes, NULL)) { /* Successful read */ if (handle->ipc) { assert(handle->remaining_ipc_rawdata_bytes >= bytes); handle->remaining_ipc_rawdata_bytes = handle->remaining_ipc_rawdata_bytes - bytes; if (handle->read2_cb) { handle->read2_cb(handle, bytes, buf, handle->pending_ipc_info.socket_info ? UV_TCP : UV_UNKNOWN_HANDLE); } else if (handle->read_cb) { handle->read_cb((uv_stream_t*)handle, bytes, buf); } if (handle->pending_ipc_info.socket_info) { free(handle->pending_ipc_info.socket_info); handle->pending_ipc_info.socket_info = NULL; } } else { handle->read_cb((uv_stream_t*)handle, bytes, buf); } /* Read again only if bytes == buf.len */ if (bytes <= buf.len) { break; } } else { uv_pipe_read_error_or_eof(loop, handle, GetLastError(), uv_null_buf_); break; } } /* Post another 0-read if still reading and not closing. */ if ((handle->flags & UV_HANDLE_READING) && !(handle->flags & UV_HANDLE_READ_PENDING)) { uv_pipe_queue_read(loop, handle); } } DECREASE_PENDING_REQ_COUNT(handle); }
void uv_process_pipe_read_req(uv_pipe_t* handle, uv_req_t* req) { DWORD bytes, avail; uv_buf_t buf; assert(handle->type == UV_NAMED_PIPE); handle->flags &= ~UV_HANDLE_READ_PENDING; eof_timer_stop(handle); if (!REQ_SUCCESS(req)) { /* An error occurred doing the 0-read. */ if (handle->flags & UV_HANDLE_READING) { uv_pipe_read_error_or_eof(handle, GET_REQ_ERROR(req), uv_null_buf_); } } else { /* Do non-blocking reads until the buffer is empty */ while (handle->flags & UV_HANDLE_READING) { if (!PeekNamedPipe(handle->handle, NULL, 0, NULL, &avail, NULL)) { uv_pipe_read_error_or_eof(handle, GetLastError(), uv_null_buf_); break; } if (avail == 0) { /* There is nothing to read after all. */ break; } buf = handle->alloc_cb((uv_handle_t*) handle, avail); assert(buf.len > 0); if (ReadFile(handle->handle, buf.base, buf.len, &bytes, NULL)) { /* Successful read */ handle->read_cb((uv_stream_t*)handle, bytes, buf); /* Read again only if bytes == buf.len */ if (bytes <= buf.len) { break; } } else { uv_pipe_read_error_or_eof(handle, GetLastError(), uv_null_buf_); break; } } /* Post another 0-read if still reading and not closing. */ if ((handle->flags & UV_HANDLE_READING) && !(handle->flags & UV_HANDLE_READ_PENDING)) { uv_pipe_queue_read(handle); } } DECREASE_PENDING_REQ_COUNT(handle); }