#include "Pipe.h"
#include "util.h"
namespace panda { namespace unievent {
const HandleType Pipe::TYPE("pipe");
const HandleType& Pipe::type () const {
return TYPE;
}
backend::HandleImpl* Pipe::new_impl () {
return loop()->impl()->new_pipe(this, _ipc);
}
excepted<void, ErrorCode> Pipe::open (fd_t file, int mode, Ownership ownership) {
if (ownership == Ownership::SHARE) file = file_dup(file);
auto error = impl()->open(file);
if (error) make_excepted(error);
if (mode != Mode::not_connected) {
if (!(mode & Mode::readable)) read_stop(); // do not run read_start() if pipe is not a reader
error = set_connect_result(true);
if (!(mode & Mode::writable)) clear_out_connected(); // do not allow to call write() if pipe is not a writer
}
return make_excepted(error);
}
excepted<void, ErrorCode> Pipe::bind (string_view name) {
return make_excepted(impl()->bind(name));
}
StreamSP Pipe::create_connection () {
return new Pipe(loop(), _ipc);
}
PipeConnectRequestSP Pipe::connect (const PipeConnectRequestSP& req) {
req->set(this);
queue.push(req);
return req;
}
void PipeConnectRequest::exec () {
ConnectRequest::exec();
if (handle->filters().size()) {
last_filter = handle->filters().front();
last_filter->pipe_connect(this);
}
else finalize_connect();
}
void PipeConnectRequest::finalize_connect () {
panda_log_debug("PipeConnectRequest::finalize_connect " << this);
auto err = handle->impl()->connect(name, impl());
if (err) return delay([=]{ cancel(err); });
}
void Pipe::pending_instances (int count) {
impl()->pending_instances(count);
}
int Pipe::pending_count () const {
return impl()->pending_count();
}
static excepted<net::SockAddr, ErrorCode> name2addr (const excepted<string, ErrorCode>& res) {
if (!res) return make_unexpected(res.error());
#ifdef _WIN32
return {};
#else
return net::SockAddr::Unix(res.value());
#endif
}
excepted<net::SockAddr, ErrorCode> Pipe::sockaddr() const {
return name2addr(sockname());
}
excepted<net::SockAddr, ErrorCode> Pipe::peeraddr() const {
return name2addr(peername());
}
excepted<void, ErrorCode> Pipe::chmod (int mode) {
return make_excepted(impl()->chmod(mode));
}
excepted<std::pair<PipeSP, PipeSP>, ErrorCode> Pipe::pair (const LoopSP& loop) {
return pair(new Pipe(loop), new Pipe(loop));
}
excepted<std::pair<PipeSP, PipeSP>, ErrorCode> Pipe::pair (const PipeSP& h1, const PipeSP& h2) {
std::pair<PipeSP, PipeSP> p = {h1, h2};
auto spres = panda::unievent::pipe();
if (!spres) return make_unexpected<ErrorCode>(spres.error());
auto fds = spres.value();
auto res = p.first->open(fds.first, Mode::readable);
if (res) res = p.second->open(fds.second, Mode::writable);
if (res) return p;
p.first->reset();
p.second->reset();
return make_unexpected(res.error());
}
}}