16,472
社区成员
发帖
与我相关
我的任务
分享
InterProcessChannel::InterProcessChannel( DWORD pid ) {
DWORD max_pid = GetCurrentProcessId(), min_pid = pid;
MaxMin(max_pid, min_pid);
std::wstring pipe_name = PIPE_PREFIX +
I2WString(max_pid) + L"_" + I2WString(min_pid);
DWORD err;
connect_event_ = CreateEvent(NULL, TRUE, FALSE, NULL);
// 先尝试打开已有管道
pipe_ = CreateFile(pipe_name.c_str(), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (pipe_ == INVALID_HANDLE_VALUE) {
err = GetLastError();
if (err != ERROR_FILE_NOT_FOUND)
throw std::runtime_error("CreateFile failed. GetLastError == " +
I2String(err));
// ERROR_NOT_FOUND 说明这个管道还没有创建, 所以需要创建一个
pipe_ = CreateNamedPipe(pipe_name.c_str(),
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
1, MAX_BUFF_SIZE, MAX_BUFF_SIZE, 0, NULL);
if (pipe_ == INVALID_HANDLE_VALUE)
throw std::runtime_error("CreateNamedPipe failed. GetLastError == " +
I2String(GetLastError()));
// 等待对方连接
Request *req = RequestsPool::Get();
req->hEvent = connect_event_;
BOOL conn_f = ConnectNamedPipe(pipe_, req);
if (!conn_f) {
err = GetLastError();
if (err != ERROR_IO_PENDING && err != ERROR_PIPE_CONNECTED)
throw std::runtime_error("ConnectNamedPipe failed. GetLastError == " +
I2String(err));
}
} else {
// 管道已存在, 修改为消息模式
DWORD mode = PIPE_READMODE_MESSAGE;
if (!SetNamedPipeHandleState(pipe_, &mode, NULL, NULL))
throw std::runtime_error("SetNamedPipeHandleState failed. GetLastError == " +
I2String(GetLastError()));
SetEvent(connect_event_);
}
// 为管道创建完成端口
if ((completion_port_ = CreateIoCompletionPort(pipe_, NULL, 0, 0)) == NULL)
throw std::runtime_error("CreateIoCompletionPort failed. GetLastError == " +
I2String(GetLastError()));
// 等待连接建立
if (WaitForSingleObject(connect_event_, INFINITE) != WAIT_OBJECT_0)
throw std::runtime_error("WaitForSingleObject failed. GetLastError == " +
I2String(GetLastError()));
// 第一次读取
Request *req = RequestsPool::Get();
if (ReadFile(pipe_, req->read_buff, MAX_BUFF_SIZE, NULL, req) == FALSE)
if ((err = GetLastError()) != ERROR_IO_PENDING)
throw std::runtime_error("ReadFile failed. GetLastError == " +
I2String(GetLastError()));
// 没有异常, 创建线程开始处理IO结果
CreateThread(NULL, 0, DispatchThread_, this, NULL, NULL);
return ;
}