lib/net: Simplify handling of socket multiplexer jobs
This commit is contained in:
parent
d2c106db53
commit
d7de571fdc
|
@ -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"
|
||||||
|
|
|
@ -140,17 +140,17 @@ 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()));
|
||||||
}
|
}
|
||||||
|
|
||||||
TCPSocket::EJobResult
|
TCPSocket::EJobResult
|
||||||
|
@ -772,9 +772,9 @@ 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
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
m_socket, m_readable, m_writable);
|
{ return serviceConnecting(j, r, w, e); },
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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},
|
||||||
|
m_socket(ARCH->copySocket(socket)),
|
||||||
|
m_readable(readable),
|
||||||
|
m_writable(writable)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~TSocketMultiplexerMethodJob() override
|
||||||
|
{
|
||||||
|
ARCH->closeSocket(m_socket);
|
||||||
|
}
|
||||||
|
|
||||||
// IJob overrides
|
// IJob overrides
|
||||||
virtual MultiplexerJobStatus run(bool readable, bool writable, bool error) override;
|
virtual MultiplexerJobStatus run(bool readable, bool writable, bool error) override
|
||||||
virtual ArchSocket getSocket() const override;
|
{
|
||||||
virtual bool isReadable() const override;
|
if (func_) {
|
||||||
virtual bool isWritable() const override;
|
return func_(this, readable, writable, error);
|
||||||
|
}
|
||||||
|
return {false, {}};
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ArchSocket getSocket() const override { return m_socket; }
|
||||||
|
virtual bool isReadable() const override { return m_readable; }
|
||||||
|
virtual bool isWritable() const override { return m_writable; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T* m_object;
|
RunFunction func_;
|
||||||
Method m_method;
|
|
||||||
ArchSocket m_socket;
|
ArchSocket m_socket;
|
||||||
bool m_readable;
|
bool m_readable;
|
||||||
bool m_writable;
|
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_readable(readable),
|
|
||||||
m_writable(writable)
|
|
||||||
{
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline
|
|
||||||
TSocketMultiplexerMethodJob<T>::~TSocketMultiplexerMethodJob()
|
|
||||||
{
|
|
||||||
ARCH->closeSocket(m_socket);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline MultiplexerJobStatus TSocketMultiplexerMethodJob<T>::run(bool read, bool write, bool error)
|
|
||||||
{
|
|
||||||
if (m_object != NULL) {
|
|
||||||
return (m_object->*m_method)(this, read, write, error);
|
|
||||||
}
|
|
||||||
return {false, {}};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline
|
|
||||||
ArchSocket
|
|
||||||
TSocketMultiplexerMethodJob<T>::getSocket() const
|
|
||||||
{
|
|
||||||
return m_socket;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline
|
|
||||||
bool
|
|
||||||
TSocketMultiplexerMethodJob<T>::isReadable() const
|
|
||||||
{
|
|
||||||
return m_readable;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
inline
|
|
||||||
bool
|
|
||||||
TSocketMultiplexerMethodJob<T>::isWritable() const
|
|
||||||
{
|
|
||||||
return m_writable;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue