Older/ToolKit/Poller/PipeWrap.cpp

97 lines
2.5 KiB
C++
Raw Permalink Normal View History

2024-09-28 23:55:00 +08:00
/*
* Copyright (c) 2016 The ZLToolKit project authors. All Rights Reserved.
*
* This file is part of ZLToolKit(https://github.com/ZLMediaKit/ZLToolKit).
*
* Use of this source code is governed by MIT license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#include <stdexcept>
#include "PipeWrap.h"
#include "Util/util.h"
#include "Util/uv_errno.h"
#include "Network/sockutil.h"
using namespace std;
#define checkFD(fd) \
if (fd == -1) { \
clearFD(); \
throw runtime_error(StrPrinter << "Create windows pipe failed: " << get_uv_errmsg());\
}
#define closeFD(fd) \
if (fd != -1) { \
close(fd);\
fd = -1;\
}
namespace toolkit {
PipeWrap::PipeWrap() {
reOpen();
}
void PipeWrap::reOpen() {
clearFD();
#if defined(_WIN32)
const char *localip = SockUtil::support_ipv6() ? "::1" : "127.0.0.1";
auto listener_fd = SockUtil::listen(0, localip);
checkFD(listener_fd)
SockUtil::setNoBlocked(listener_fd,false);
auto localPort = SockUtil::get_local_port(listener_fd);
_pipe_fd[1] = SockUtil::connect(localip, localPort,false);
checkFD(_pipe_fd[1])
_pipe_fd[0] = (int)accept(listener_fd, nullptr, nullptr);
checkFD(_pipe_fd[0])
SockUtil::setNoDelay(_pipe_fd[0]);
SockUtil::setNoDelay(_pipe_fd[1]);
close(listener_fd);
#else
if (pipe(_pipe_fd) == -1) {
throw runtime_error(StrPrinter << "Create posix pipe failed: " << get_uv_errmsg());
}
#endif // defined(_WIN32)
SockUtil::setNoBlocked(_pipe_fd[0], true);
SockUtil::setNoBlocked(_pipe_fd[1], false);
SockUtil::setCloExec(_pipe_fd[0]);
SockUtil::setCloExec(_pipe_fd[1]);
}
void PipeWrap::clearFD() {
closeFD(_pipe_fd[0]);
closeFD(_pipe_fd[1]);
}
PipeWrap::~PipeWrap() {
clearFD();
}
int PipeWrap::write(const void *buf, int n) {
int ret;
do {
#if defined(_WIN32)
ret = send(_pipe_fd[1], (char *)buf, n, 0);
#else
ret = ::write(_pipe_fd[1], buf, n);
#endif // defined(_WIN32)
} while (-1 == ret && UV_EINTR == get_uv_error(true));
return ret;
}
int PipeWrap::read(void *buf, int n) {
int ret;
do {
#if defined(_WIN32)
ret = recv(_pipe_fd[0], (char *)buf, n, 0);
#else
ret = ::read(_pipe_fd[0], buf, n);
#endif // defined(_WIN32)
} while (-1 == ret && UV_EINTR == get_uv_error(true));
return ret;
}
} /* namespace toolkit*/