TCPServerDispatcher: fix thread accounting leak (#1801)

* TCPServerDispatcher::run: catch errors in connection creation and handling to prevent threads from exiting without accounting for them
This commit is contained in:
Matt Tucker 2017-07-10 13:37:11 -07:00 committed by Aleksandar Fabijanic
parent 6c13f5d14c
commit 4da941f869

View File

@ -18,6 +18,7 @@
#include "Poco/Net/TCPServerConnectionFactory.h" #include "Poco/Net/TCPServerConnectionFactory.h"
#include "Poco/Notification.h" #include "Poco/Notification.h"
#include "Poco/AutoPtr.h" #include "Poco/AutoPtr.h"
#include "Poco/ErrorHandler.h"
#include <memory> #include <memory>
@ -104,24 +105,38 @@ void TCPServerDispatcher::run()
for (;;) for (;;)
{ {
AutoPtr<Notification> pNf = _queue.waitDequeueNotification(idleTime); try {
if (pNf) AutoPtr<Notification> pNf = _queue.waitDequeueNotification(idleTime);
{ if (pNf)
TCPConnectionNotification* pCNf = dynamic_cast<TCPConnectionNotification*>(pNf.get());
if (pCNf)
{ {
#if __cplusplus < 201103L TCPConnectionNotification* pCNf = dynamic_cast<TCPConnectionNotification*>(pNf.get());
std::auto_ptr<TCPServerConnection> pConnection(_pConnectionFactory->createConnection(pCNf->socket())); if (pCNf)
#else {
std::unique_ptr<TCPServerConnection> pConnection(_pConnectionFactory->createConnection(pCNf->socket())); #if __cplusplus < 201103L
#endif std::auto_ptr<TCPServerConnection> pConnection(_pConnectionFactory->createConnection(pCNf->socket()));
poco_check_ptr(pConnection.get()); #else
beginConnection(); std::unique_ptr<TCPServerConnection> pConnection(_pConnectionFactory->createConnection(pCNf->socket()));
pConnection->start(); #endif
endConnection(); poco_check_ptr(pConnection.get());
beginConnection();
pConnection->start();
endConnection();
}
} }
} }
catch (Poco::Exception &exc)
{
ErrorHandler::handle(exc);
}
catch (std::exception &exc)
{
ErrorHandler::handle(exc);
}
catch (...)
{
ErrorHandler::handle();
}
FastMutex::ScopedLock lock(_mutex); FastMutex::ScopedLock lock(_mutex);
if (_stopped || (_currentThreads > 1 && _queue.empty())) if (_stopped || (_currentThreads > 1 && _queue.empty()))
{ {