lib/net: Simplify handling of socket multiplexer jobs

This commit is contained in:
Povilas Kanapickas 2021-11-01 06:16:34 +02:00
parent d2c106db53
commit d7de571fdc
5 changed files with 60 additions and 89 deletions

View File

@ -20,7 +20,7 @@
#include "SecureSocket.h" #include "SecureSocket.h"
#include "net/NetworkAddress.h" #include "net/NetworkAddress.h"
#include "net/SocketMultiplexer.h" #include "net/SocketMultiplexer.h"
#include "net/TSocketMultiplexerMethodJob.h" #include "arch/Arch.h"
#include "arch/XArch.h" #include "arch/XArch.h"
#include "common/DataDirectories.h" #include "common/DataDirectories.h"
#include "base/String.h" #include "base/String.h"

View File

@ -140,16 +140,16 @@ std::unique_ptr<ISocketMultiplexerJob> SecureSocket::newJob()
void void
SecureSocket::secureConnect() SecureSocket::secureConnect()
{ {
setJob(std::make_unique<TSocketMultiplexerMethodJob<SecureSocket>>( setJob(std::make_unique<TSocketMultiplexerMethodJob>([this](auto j, auto r, auto w, auto e)
this, &SecureSocket::serviceConnect, { return serviceConnect(j, r, w, e); },
getSocket(), isReadable(), isWritable())); getSocket(), isReadable(), isWritable()));
} }
void void
SecureSocket::secureAccept() SecureSocket::secureAccept()
{ {
setJob(std::make_unique<TSocketMultiplexerMethodJob<SecureSocket>>( setJob(std::make_unique<TSocketMultiplexerMethodJob>([this](auto j, auto r, auto w, auto e)
this, &SecureSocket::serviceAccept, { return serviceAccept(j, r, w, e); },
getSocket(), isReadable(), isWritable())); getSocket(), isReadable(), isWritable()));
} }
@ -772,8 +772,8 @@ MultiplexerJobStatus SecureSocket::serviceConnect(ISocketMultiplexerJob* job,
// Retry case // Retry case
return { return {
true, true,
std::make_unique<TSocketMultiplexerMethodJob<SecureSocket>>( std::make_unique<TSocketMultiplexerMethodJob>([this](auto j, auto r, auto w, auto e)
this, &SecureSocket::serviceConnect, { return serviceConnect(j, r, w, e); },
getSocket(), isReadable(), isWritable()) getSocket(), isReadable(), isWritable())
}; };
} }
@ -802,9 +802,12 @@ MultiplexerJobStatus SecureSocket::serviceAccept(ISocketMultiplexerJob* job,
} }
// Retry case // Retry case
return {true, std::make_unique<TSocketMultiplexerMethodJob<SecureSocket>>( return {
this, &SecureSocket::serviceAccept, true,
getSocket(), isReadable(), isWritable())}; std::make_unique<TSocketMultiplexerMethodJob>([this](auto j, auto r, auto w, auto e)
{ return serviceAccept(j, r, w, e); },
getSocket(), isReadable(), isWritable())
};
} }
void void

View File

@ -70,8 +70,10 @@ TCPListenSocket::bind(const NetworkAddress& addr)
ARCH->bindSocket(m_socket, addr.getAddress()); ARCH->bindSocket(m_socket, addr.getAddress());
ARCH->listenOnSocket(m_socket); ARCH->listenOnSocket(m_socket);
auto new_job = std::make_unique<TSocketMultiplexerMethodJob<TCPListenSocket>>( auto new_job = std::make_unique<TSocketMultiplexerMethodJob>(
this, &TCPListenSocket::serviceListening, m_socket, true, false); [this](auto j, auto r, auto w, auto e)
{ return serviceListening(j, r, w, e); },
m_socket, true, false);
m_socketMultiplexer->addSocket(this, std::move(new_job)); m_socketMultiplexer->addSocket(this, std::move(new_job));
} }
@ -136,8 +138,10 @@ TCPListenSocket::accept()
void void
TCPListenSocket::setListeningJob() TCPListenSocket::setListeningJob()
{ {
auto new_job = std::make_unique<TSocketMultiplexerMethodJob<TCPListenSocket>>( auto new_job = std::make_unique<TSocketMultiplexerMethodJob>(
this, &TCPListenSocket::serviceListening, m_socket, true, false); [this](auto j, auto r, auto w, auto e)
{ return serviceListening(j, r, w, e); },
m_socket, true, false);
m_socketMultiplexer->addSocket(this, std::move(new_job)); m_socketMultiplexer->addSocket(this, std::move(new_job));
} }

View File

@ -426,18 +426,20 @@ std::unique_ptr<ISocketMultiplexerJob> TCPSocket::newJob()
if (!(m_readable || m_writable)) { if (!(m_readable || m_writable)) {
return {}; return {};
} }
return std::make_unique<TSocketMultiplexerMethodJob<TCPSocket>>( return std::make_unique<TSocketMultiplexerMethodJob>(
this, &TCPSocket::serviceConnecting, [this](auto j, auto r, auto w, auto e)
{ return serviceConnecting(j, r, w, e); },
m_socket, m_readable, m_writable); m_socket, m_readable, m_writable);
} }
else { else {
if (!(m_readable || (m_writable && (m_outputBuffer.getSize() > 0)))) { auto writable = m_writable && (m_outputBuffer.getSize() > 0);
if (!(m_readable || writable)) {
return {}; return {};
} }
return std::make_unique<TSocketMultiplexerMethodJob<TCPSocket>>( return std::make_unique<TSocketMultiplexerMethodJob>(
this, &TCPSocket::serviceConnected, [this](auto j, auto r, auto w, auto e)
m_socket, m_readable, { return serviceConnected(j, r, w, e); },
m_writable && (m_outputBuffer.getSize() > 0)); m_socket, m_readable, writable);
} }
} }

View File

@ -25,81 +25,43 @@
/*! /*!
A socket multiplexer job class that invokes a member function. A socket multiplexer job class that invokes a member function.
*/ */
template <class T>
class TSocketMultiplexerMethodJob : public ISocketMultiplexerJob { class TSocketMultiplexerMethodJob : public ISocketMultiplexerJob {
public: public:
using Method = MultiplexerJobStatus (T::*)(ISocketMultiplexerJob*, bool, bool, bool); using RunFunction = std::function<MultiplexerJobStatus(ISocketMultiplexerJob*, bool, bool, bool)>;
//! run() invokes \c object->method(arg) //! run() invokes \c object->method(arg)
TSocketMultiplexerMethodJob(T* object, Method method, TSocketMultiplexerMethodJob(const RunFunction& func,
ArchSocket socket, bool readable, bool writeable); ArchSocket socket, bool readable, bool writable) :
virtual ~TSocketMultiplexerMethodJob(); func_{func},
// IJob overrides
virtual MultiplexerJobStatus run(bool readable, bool writable, bool error) override;
virtual ArchSocket getSocket() const override;
virtual bool isReadable() const override;
virtual bool isWritable() const override;
private:
T* m_object;
Method m_method;
ArchSocket m_socket;
bool m_readable;
bool m_writable;
void* m_arg;
};
template <class T>
inline
TSocketMultiplexerMethodJob<T>::TSocketMultiplexerMethodJob(T* object,
Method method, ArchSocket socket,
bool readable, bool writable) :
m_object(object),
m_method(method),
m_socket(ARCH->copySocket(socket)), m_socket(ARCH->copySocket(socket)),
m_readable(readable), m_readable(readable),
m_writable(writable) m_writable(writable)
{ {
// do nothing }
}
template <class T> ~TSocketMultiplexerMethodJob() override
inline {
TSocketMultiplexerMethodJob<T>::~TSocketMultiplexerMethodJob()
{
ARCH->closeSocket(m_socket); ARCH->closeSocket(m_socket);
} }
template <class T> // IJob overrides
inline MultiplexerJobStatus TSocketMultiplexerMethodJob<T>::run(bool read, bool write, bool error) virtual MultiplexerJobStatus run(bool readable, bool writable, bool error) override
{ {
if (m_object != NULL) { if (func_) {
return (m_object->*m_method)(this, read, write, error); return func_(this, readable, writable, error);
} }
return {false, {}}; return {false, {}};
} }
template <class T> virtual ArchSocket getSocket() const override { return m_socket; }
inline virtual bool isReadable() const override { return m_readable; }
ArchSocket virtual bool isWritable() const override { return m_writable; }
TSocketMultiplexerMethodJob<T>::getSocket() const
{ private:
return m_socket; RunFunction func_;
} ArchSocket m_socket;
bool m_readable;
bool m_writable;
};
template <class T>
inline
bool
TSocketMultiplexerMethodJob<T>::isReadable() const
{
return m_readable;
}
template <class T>
inline
bool
TSocketMultiplexerMethodJob<T>::isWritable() const
{
return m_writable;
}