mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-04-11 08:07:33 +02:00
Make DynSock accepted sockets queue optional, with precise lifetime
When DynSock is used to represent a connected socket (e.g. a client) the data I/O pipes are needed but not the m_accepted_sockets Queue, because connected sockets do not create more connected sockets. When DynSock is used to represent a listening socket, the Queue is necessary to create connected sockets upon mocked connection, but the Queue does not need to be a std::shared_ptr as long as it is guaranteed to live as long as the DynSock. Co-Authored by: Hodlinator <172445034+hodlinator@users.noreply.github.com>
This commit is contained in:
@@ -346,11 +346,16 @@ void DynSock::Pipe::WaitForDataOrEof(UniqueLock<Mutex>& lock)
|
||||
});
|
||||
}
|
||||
|
||||
DynSock::DynSock(std::shared_ptr<Pipes> pipes, std::shared_ptr<Queue> accept_sockets)
|
||||
DynSock::DynSock(std::shared_ptr<Pipes> pipes, Queue* accept_sockets)
|
||||
: m_pipes{pipes}, m_accept_sockets{accept_sockets}
|
||||
{
|
||||
}
|
||||
|
||||
DynSock::DynSock(std::shared_ptr<Pipes> pipes)
|
||||
: m_pipes{pipes}, m_accept_sockets{}
|
||||
{
|
||||
}
|
||||
|
||||
DynSock::~DynSock()
|
||||
{
|
||||
m_pipes->send.Eof();
|
||||
@@ -369,6 +374,7 @@ ssize_t DynSock::Send(const void* buf, size_t len, int) const
|
||||
|
||||
std::unique_ptr<Sock> DynSock::Accept(sockaddr* addr, socklen_t* addr_len) const
|
||||
{
|
||||
assert(m_accept_sockets && "Accept() called on non-listening DynSock");
|
||||
ZeroSock::Accept(addr, addr_len);
|
||||
return m_accept_sockets->Pop().value_or(nullptr);
|
||||
}
|
||||
@@ -403,7 +409,7 @@ bool DynSock::WaitMany(std::chrono::milliseconds timeout, EventsPerSock& events_
|
||||
if ((events.requested & Sock::RECV) != 0) {
|
||||
auto dyn_sock = reinterpret_cast<const DynSock*>(sock.get());
|
||||
uint8_t b;
|
||||
if (dyn_sock->m_pipes->recv.GetBytes(&b, 1, MSG_PEEK) == 1 || !dyn_sock->m_accept_sockets->Empty()) {
|
||||
if (dyn_sock->m_pipes->recv.GetBytes(&b, 1, MSG_PEEK) == 1 || (dyn_sock->m_accept_sockets && !dyn_sock->m_accept_sockets->Empty())) {
|
||||
events.occurred |= Sock::RECV;
|
||||
at_least_one_event_occurred = true;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#ifndef BITCOIN_TEST_UTIL_NET_H
|
||||
#define BITCOIN_TEST_UTIL_NET_H
|
||||
|
||||
#include <attributes.h>
|
||||
#include <compat/compat.h>
|
||||
#include <netmessagemaker.h>
|
||||
#include <net.h>
|
||||
@@ -336,7 +337,15 @@ public:
|
||||
* @param[in] pipes Send/recv pipes used by the Send() and Recv() methods.
|
||||
* @param[in] accept_sockets Sockets to return by the Accept() method.
|
||||
*/
|
||||
explicit DynSock(std::shared_ptr<Pipes> pipes, std::shared_ptr<Queue> accept_sockets);
|
||||
explicit DynSock(std::shared_ptr<Pipes> pipes, Queue* accept_sockets LIFETIMEBOUND);
|
||||
|
||||
/**
|
||||
* Create a new mocked sock that represents a connected socket. It has pipes
|
||||
* for data transport but there is no queue because connected sockets do
|
||||
* not introduce new connected sockets.
|
||||
* @param[in] pipes Send/recv pipes used by the Send() and Recv() methods.
|
||||
*/
|
||||
explicit DynSock(std::shared_ptr<Pipes> pipes);
|
||||
|
||||
~DynSock();
|
||||
|
||||
@@ -356,7 +365,7 @@ private:
|
||||
DynSock& operator=(Sock&&) override;
|
||||
|
||||
std::shared_ptr<Pipes> m_pipes;
|
||||
std::shared_ptr<Queue> m_accept_sockets;
|
||||
Queue* const m_accept_sockets;
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
|
||||
Reference in New Issue
Block a user