6#include <zypp-core/zyppng/base/EventDispatcher>
10#include <sys/socket.h>
121 auto wbOld = std::move( std::get<ConnectedState>(
_state)._writeBuffer );
134 z_func()->IODevice::close();
148 if ( !
state._connectNotifier ) {
153 if ( !
state._connectTimeout ) {
157 state._connectNotifier.reset();
158 state._connectTimeout.reset();
161 state._connectTimeout->setSingleShot(
true );
162 state._connectTimeout->start( 30000 );
253 return std::visit( [
this](
auto &
s ){
254 using T = std::decay_t<
decltype (
s)>;
255 if constexpr ( std::is_same_v<T, ConnectedState> || std::is_same_v<T, ClosingState> ) {
256 const auto nwrite =
s._writeBuffer.frontSize();
263 const auto nBuf =
s._writeBuffer.front();
271#if EAGAIN != EWOULDBLOCK
287 if (
s._writeBuffer.size() == 0 )
343 std::visit( [
this, &
ev ] (
const auto &
currState ) {
344 using T = std::decay_t<
decltype(
currState)>;
345 if constexpr ( std::is_same<ConnectingState, T>() ) {
358 if ( err == 0 || err ==
EISCONN ) {
369 }
else if constexpr ( std::is_same<ConnectedState, T>() ) {
386 }
else if constexpr ( std::is_same<ClosingState, T>() ) {
395 if (
currState._writeBuffer.size() == 0 ) {
400 }
else if constexpr ( std::is_same<ListeningState, T>() ) {
406 DBG <<
"Unexpected state on socket activation" << std::endl;
413 return std::visit([](
const auto &
s )
constexpr {
return s.type(); },
_state );
421 sptr->d_func()->_socket =
fd;
424 if ( !
sptr->setBlocking(
false ) ) {
425 DBG <<
"Failed to unblock socket." << std::endl;
429 if(
sptr->d_func()->transition(
state ) )
443 if ( channel != 0 ) {
444 constexpr std::string_view msg(
"Socket does not support multiple read channels");
445 ERR << msg << std::endl;
446 throw std::logic_error( msg.data() );
448 return d_func()->rawBytesAvailable();
464 if ( !
addr || !
d->initSocket() )
467 int res = ::bind(
d->_socket,
addr->nativeSockAddr(),
addr->size() );
468 if (
res >= 0)
return true;
510 if ( !
d->initSocket() )
539 if (
d->_socket == -1 )
546#if EAGAIN != EWOULDBLOCK
569 DBG <<
"Error querying socket domain: " <<
strerr_cxx() << std::endl;
575 optlen =
sizeof(protocol);
578 DBG <<
"Error querying socket protocol: " <<
strerr_cxx() << std::endl;
587 DBG <<
"Error querying socket type: " <<
strerr_cxx() << std::endl;
599 if ( !
d->initSocket() )
624 if ( !
d->initSocket() )
627 d->_targetAddr = std::move(
addr);
645 auto sock =
d->_socket;
660 d->transition( ClosedState );
671 std::visit([&
d](
const auto &
s ){
672 using Type = std::decay_t<
decltype (
s)>;
673 if constexpr ( std::is_same_v<Type, SocketPrivate::ConnectedState > ) {
675 if (
s._writeBuffer.size() ) {
688 if (
d->state() != SocketState::ConnectedState )
691 auto &
s = std::get<SocketPrivate::ConnectedState>(
d->_state );
694 if (
s._writeBuffer.size() ) {
695 s._writeBuffer.append( data,
count );
697 d->writePendingData();
704#if EAGAIN != EWOULDBLOCK
730 d->_sigBytesWritten.emit(
written );
733 if (
s._writeBuffer.size() == 0 )
734 d->_sigAllBytesWritten.emit();
769 std::visit([&](
const auto &
s ){
770 using T = std::decay_t<
decltype (
s)>;
771 if constexpr ( std::is_same_v<T, SocketPrivate::ConnectedState> || std::is_same_v<T, SocketPrivate::ClosingState> ) {
772 if (
s._writeBuffer.size() > 0 ) {
780 if (
s._writeBuffer.size() == 0 ){
806 return bytesAvailable() > 0;
811 if ( channel != 0 ) {
812 constexpr std::string_view msg(
"Socket does not support multiple read channels");
813 ERR << msg << std::endl;
814 throw std::logic_error( msg.data() );
818 if (
d->state() != SocketState::ConnectedState )
825 d->setError( ConnectionClosedByRemote,
"The remote host closed the connection",
false );
827 }
else if ( read < 0 ) {
829#if EAGAIN != EWOULDBLOCK
846 if ( channel != 0 ) {
847 constexpr std::string_view msg(
"Changing the readChannel on a Socket is not supported");
848 ERR << msg << std::endl;
849 throw std::logic_error( msg.data() );
856 return std::visit([&](
const auto &
s ) -> int64_t {
857 using T = std::decay_t<
decltype (
s)>;
858 if constexpr ( std::is_same_v<T, SocketPrivate::ConnectedState> || std::is_same_v<T, SocketPrivate::ClosingState> ) {
859 return s._writeBuffer.size();
872 return d_func()->_incomingConnection;
877 return d_func()->_connected;
882 return d_func()->_disconnected;
887 return d_func()->_sigError;
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
static bool waitForFdEvent(const int fd, int events, int &revents, int &timeout)
Signal< void()> _readyRead
Signal< void()> _sigAllBytesWritten
Signal< void(int64_t)> _sigBytesWritten
std::vector< IOBuffer > _readChannels
Signal< void(uint)> _channelReadyRead
SignalProxy< void(const SocketNotifier &sock, int evTypes) sigActivated)()
static Ptr create(int socket, int evTypes, bool enable=true)
Socket::SocketState state() const
static Socket::Ptr wrapSocket(int fd, int domain, int type, int protocol, Socket::SocketState state)
std::variant< InitialState, ConnectingState, ConnectedState, ListeningState, ClosingState, ClosedState > _state
bool transition(Socket::SocketState newState)
int64_t rawBytesAvailable() const
bool readRawBytesToBuffer()
bool handleConnectError(int error)
Signal< void()> _disconnected
void onSocketActivated(int ev)
std::shared_ptr< SockAddr > _targetAddr
Signal< void()> _connected
void setError(Socket::SocketError error, std::string &&err, bool emit=true)
void onSocketActivatedSlot(const SocketNotifier &, int ev)
Signal< void()> _incomingConnection
Signal< void(Socket::SocketError)> _sigError
Socket::SocketError _error
SocketError lastError() const
SignalProxy< void()> sigConnected()
bool connect(std::shared_ptr< SockAddr > addr)
static Ptr fromSocket(int fd, SocketState state)
@ UnsupportedSocketOptions
@ InsufficientPermissions
@ ConnectionClosedByRemote
void readChannelChanged(uint channel) override
bool waitForReadyRead(uint channel, int timeout=-1) override
int64_t bytesPending() const
static Ptr create(int domain, int type, int protocol)
SignalProxy< void()> sigDisconnected()
SignalProxy< void()> sigIncomingConnection()
bool waitForAllBytesWritten(int timeout=-1)
bool listen(int backlog=50)
SignalProxy< void(Socket::SocketError)> sigError()
bool setBlocking(const bool set=true)
int64_t writeData(const char *data, int64_t count) override
bool waitForConnected(int timeout=-1)
std::shared_ptr< Socket > Ptr
bool bind(const std::shared_ptr< SockAddr > &addr)
int64_t readData(uint channel, char *buffer, int64_t bufsize) override
int64_t rawBytesAvailable(uint channel=0) const override
SocketState state() const
static std::shared_ptr< Timer > create()
Creates a new Timer object, the timer is not started at this point.
SignalProxy< void(Timer &t) sigExpired)()
This signal is always emitted when the timer expires.
auto eintrSafeCall(Fun &&function, Args &&... args)
int64_t bytesAvailableOnFD(int fd)
std::string strerr_cxx(const int err=-1)
ClosingState(IOBuffer &&writeBuffer)
#define ZYPP_IMPL_PRIVATE(Class)