#pragma once
#include "Stream.h"
#include "backend/PipeImpl.h"
namespace
panda {
namespace
unievent {
struct
IPipeListener : IStreamListener {};
struct
IPipeSelfListener : IStreamSelfListener {};
struct
Pipe :
virtual
Stream {
using
Mode = backend::PipeImpl::Mode;
static
const
HandleType TYPE;
Pipe (Loop* loop = Loop::default_loop(),
bool
ipc =
false
) : _ipc(ipc) {
panda_log_ctor();
_init(loop, loop->impl()->new_pipe(
this
, ipc));
}
Pipe (
bool
ipc) : Pipe(Loop::default_loop(), ipc) {}
~Pipe () { panda_log_dtor(); }
const
HandleType& type ()
const
override;
bool
ipc ()
const
{
return
_ipc; }
virtual
excepted<
void
, ErrorCode> open (fd_t,
int
mode, Ownership = Ownership::TRANSFER);
virtual
excepted<
void
, ErrorCode> bind (string_view name);
virtual
PipeConnectRequestSP connect (
const
PipeConnectRequestSP& req);
PipeConnectRequestSP connect (
const
string& name, connect_fn callback =
nullptr
);
virtual
void
pending_instances (
int
count);
virtual
int
pending_count ()
const
;
excepted<string, ErrorCode> sockname ()
const
{
return
handle_fd_excepted(impl()->sockname()); }
excepted<string, ErrorCode> peername ()
const
{
return
handle_fd_excepted(impl()->peername()); }
excepted<net::SockAddr, ErrorCode> sockaddr ()
const
override;
excepted<net::SockAddr, ErrorCode> peeraddr ()
const
override;
virtual
excepted<
void
, ErrorCode> chmod (
int
mode);
static
excepted<std::pair<PipeSP,PipeSP>, ErrorCode> pair (
const
LoopSP& = Loop::default_loop());
static
excepted<std::pair<PipeSP,PipeSP>, ErrorCode> pair (
const
PipeSP&,
const
PipeSP&);
protected
:
StreamSP create_connection () override;
private
:
friend
PipeConnectRequest;
bool
_ipc;
backend::PipeImpl* impl ()
const
{
return
static_cast
<backend::PipeImpl*>(BackendHandle::impl()); }
HandleImpl* new_impl () override;
};
struct
PipeConnectRequest : ConnectRequest, AllocatedObject<PipeConnectRequest> {
string name;
PipeConnectRequest (
const
string& name, Stream::connect_fn callback =
nullptr
)
: ConnectRequest(callback), name(name) {}
private
:
friend
Pipe;
friend
StreamFilter;
Pipe* handle;
void
set (Pipe* h) {
handle = h;
ConnectRequest::set(h);
}
void
exec () override;
void
finalize_connect ();
};
inline
PipeConnectRequestSP Pipe::connect (
const
string& name, connect_fn callback) {
PipeConnectRequestSP connect_request =
new
PipeConnectRequest(name, callback);
return
connect(connect_request);
}
}}