Закрытие проблемы Boost Asio Acceptor

Я сталкиваюсь с проблемой, пытающейся закрыть asio ip :: tcp :: acceptor. Ниже приведен код, который я использую (свободно на основе пример асинхронного сервера) чтобы запустить и запустить tcp listener / server:

Чтобы запустить сервис:

bool TCPServer::listen()
{
try
{
if(std::atoi(_port.c_str()) <= 0)
{
LOG_ERROR("Configured port is invalid. Application will not work. Please check config file.");
return false;
}

int noOfThreads = 5;

using namespace boost::asio::ip;

tcp::endpoint endpoint(address::from_string(_host), std::atoi(_port.c_str()));
_acceptor.reset(new tcp::acceptor(_ioService, endpoint));

startAccept();

for(std::size_t i = 0; i < static_cast<unsigned>(noOfThreads); ++i)
{
_threads.push_back(std::thread(std::bind(static_cast<size_t (boost::asio::io_service::*)()>
(&boost::asio::io_service::run), &_ioService)));
}

return true;
}
catch(std::exception& e)
{
LOG_ERROR("Received exception while trying to listen at the specified address. Please verify the address"<< " is accurate. Exception:" << e.what());
return false;
}
}

Ниже приведена функция startAccept (), вызываемая в приведенном выше коде. Он запускает объект класса «TCPConnection» и помещает его в очередь asio .:

void TCPServer::startAccept()
{
TCPConnection::Ptr newConn(new TCPConnection(_acceptor->get_io_service(), _processDataFn));

_acceptor->async_accept(newConn->socket(), std::bind(&TCPServer::handleAccept, this, newConn, std::placeholders::_1));
}

И далее — функция handleAccept (), асинхронно вызываемая asio, как указано в функции startAccept ():

void TCPServer::handleAccept(TCPConnection::Ptr newConn_, const boost::system::error_code& error_)
{
if (!error_)
{
newConn_->start();
}
else
{
LOG_ERROR("Encountered error while trying to accept connection. Error Code:" << error_);
}
startAccept();
}

Код выше, кажется, работает нормально и слушает нормально. Проблема, с которой я сталкиваюсь, касается закрытия сервера. Я использую следующий код, чтобы закрыть сервер.

TCPServer::~TCPServer()
{
try
{
if(!_ioService.stopped())
{
_ioService.stop();
}

if(_acceptor)
{
boost::system::error_code ec;
_acceptor->cancel(ec);
_acceptor->close(ec);
}

for(std::size_t i = 0; i < _threads.size(); ++i)
{
if(_threads[i].joinable())
{
_threads[i].join();
}
}

//_acceptor.reset(); // Hacky and causes memory leak.

}
catch(std::exception& e_)
{
LOG_ERROR("Received exception while shutting down listener. Exception:" << e_.what());
}
}

Беда в том, что в приведенном выше коде, если закомментированная строка не закомментирована, поток, из которого вызывается эта функция, не возвращается. Если закомментированная строка не закомментирована, это приводит к утечке памяти (пропущенные элементы являются переменными-членами acceptor). Обратите внимание, что это простое приложение с графическим интерфейсом (я использую wxWidgets). Вышеупомянутая функция listen () и деструктор вызываются из потоков GUI при различных событиях (я не уверен, что это актуально. Но на всякий случай …). Я боролся с этим часами. Любая помощь приветствуется.

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]