fix(TCPServer): continues to accept connections after stop() #4892 (#4896)

* fix(TCPServer): continues to accept connections after stop() #4892

* fix(TCPServer): first attempt to silence TSAN #4892

* fix(TCPServer): check stopped status after poll; add TCPServerFactory::stop() and allow factory to return nullptr on connection creation request #4892

* fix(TCPServer): initialize factory stopped flag #4892

* revert(SocketImpl): atomic sock fd
This commit is contained in:
Aleksandar Fabijanic
2025-03-12 16:15:19 -05:00
committed by GitHub
parent 91244ac9d9
commit eb94de03a6
5 changed files with 74 additions and 21 deletions

View File

@@ -295,11 +295,11 @@ public:
/// If count is != 0, sends the given number of bytes, otherwise
/// sends all bytes, starting from the given offset.
///
/// On Linux, macOS and FreeBSD systems, the implementation
/// On Linux, macOS and FreeBSD systems, the implementation
/// uses sendfile() or sendfile64().
/// On Windows, the implementation uses TransmitFile().
///
/// If neither sendfile() nor TransmitFile() is available,
/// If neither sendfile() nor TransmitFile() is available,
/// or the socket is a secure one (secure() returne true),
/// falls back to reading the file block by block and calling sendBytes().
///
@@ -307,7 +307,7 @@ public:
/// as count, unless count is 0.
///
/// Throws NetException (or a subclass) in case of any errors.
/// Also throws a NetException if the socket has been set to
/// Also throws a NetException if the socket has been set to
/// non-blocking.
virtual int available();
@@ -636,7 +636,7 @@ inline bool SocketImpl::getBlocking() const
#if defined(POCO_OS_FAMILY_WINDOWS)
#pragma comment(lib, "mswsock.lib")
#endif
#pragma comment(lib, "mswsock.lib")
#endif
#endif // Net_SocketImpl_INCLUDED

View File

@@ -35,7 +35,13 @@ class Net_API TCPServerConnectionFactory
/// it accepts.
///
/// Subclasses must override the createConnection()
/// method.
/// method, which can refuse connections by returning nullptr.
/// Some examples when an implementation may refuse new connections:
///
/// - number of connections exceeded a limit
/// - a connection from unwanted client attempted
/// - too many connection attempts in a short timespan
/// - etc.
///
/// The TCPServerConnectionFactoryImpl template class
/// can be used to automatically instantiate a
@@ -45,23 +51,55 @@ class Net_API TCPServerConnectionFactory
public:
using Ptr = Poco::SharedPtr<TCPServerConnectionFactory>;
TCPServerConnectionFactory(const TCPServerConnectionFactory&) = delete;
TCPServerConnectionFactory& operator = (const TCPServerConnectionFactory&) = delete;
TCPServerConnectionFactory(TCPServerConnectionFactory&&) = delete;
TCPServerConnectionFactory& operator = (TCPServerConnectionFactory&&) = delete;
virtual ~TCPServerConnectionFactory();
/// Destroys the TCPServerConnectionFactory.
virtual TCPServerConnection* createConnection(const StreamSocket& socket) = 0;
/// Creates an instance of a subclass of TCPServerConnection,
/// using the given StreamSocket.
/// This function is allowed to return nullptr, in which case an accepted
/// socket will be destroyed by the TCPServerDispatcher.
void stop();
/// Stops the factory.
/// Normally, this function is called by TCPServerDispatcher
/// to indicate that the server is shutting down; the expected
/// implementation behavior after this call is to return nullptr
/// on all subsequent connection creation attempts.
bool isStopped() const;
/// Returns true if the factory was stopped, false otherwise.
protected:
TCPServerConnectionFactory();
/// Creates the TCPServerConnectionFactory.
private:
TCPServerConnectionFactory(const TCPServerConnectionFactory&);
TCPServerConnectionFactory& operator = (const TCPServerConnectionFactory&);
std::atomic<bool> _stopped;
};
//
// inlines
//
inline void TCPServerConnectionFactory::stop()
{
_stopped = true;
}
inline bool TCPServerConnectionFactory::isStopped() const
{
return _stopped;
}
template <class S>
class TCPServerConnectionFactoryImpl: public TCPServerConnectionFactory
/// This template provides a basic implementation of
@@ -78,7 +116,10 @@ public:
TCPServerConnection* createConnection(const StreamSocket& socket)
{
return new S(socket);
if (!isStopped())
return new S(socket);
return nullptr;
}
};