@D3Nd3R

Как правильно удалять сокет в многопоточном сервере на базе QThreadPool?

Возникла проблема с освобождением памяти после разрыва соединения при использовании QsslSocket::deleteLater(). Я заменил вызов метода на delete socket и все стало ок, но в документации советуют использовать именно deleteLater(). Само соединение обрабатывается в методе run(). Обработчик наследуется от QRunnable. Собственно вопрос: почему не работает QsslSocket::deleteLater().
void RequestProcessor::run()
{

    /*QSslSocket **/socket = new QSslSocket();
    if (!socket) {
        qDebug("not enough memory to create new QSslSocket");
        return;
    }

    if (!socket->setSocketDescriptor(mSocketDescriptor))
    {
        qDebug("couldn't set socket descriptor");
        CloseSocket(socket);
        return;
    }

    socket->setProtocol(QSsl::AnyProtocol);
    socket->setPeerVerifyMode(QSslSocket::VerifyNone);

    startServerEncryption(socket);

    socket->waitForReadyRead();
    this->onReadyRead();

    socket->waitForDisconnected();
    socket->close();
    //socket->deleteLater();

    delete socket;
}
  • Вопрос задан
  • 765 просмотров
Решения вопроса 2
Использование deleteLater() предполагает отложенное удаление через очередь сообщений того потока, который владеет объектом. В вашем случае это поток, который выполняет RequestProcessor::run(). Если после завершения run поток завершится или его очередь сообщений будет остановлена, то само удаление может никогда не произойти.

Явное удаление в данном случае является вполне приемлемым, так как вся работа с сокетом завершена, раз вы дожидаетесь завершения соединения.
Ответ написан
IGHOR
@IGHOR Куратор тега Qt
Qt/C++ DEV/CTO
Чтобы заработал deleteLater надо объекту задать парента, и удалить парент перед выходом из блока.

void RequestProcessor::run()
{
QObject localObject;
/*QSslSocket **/socket = new QSslSocket(&localObject);
if (!socket) {
qDebug("not enough memory to create new QSslSocket");
return;
}

if (!socket->setSocketDescriptor(mSocketDescriptor))
{
qDebug("couldn't set socket descriptor");
CloseSocket(socket);
return;
}

socket->setProtocol(QSsl::AnyProtocol);
socket->setPeerVerifyMode(QSslSocket::VerifyNone);

startServerEncryption(socket);

socket->waitForReadyRead();
this->onReadyRead();

socket->waitForDisconnected();
socket->close();
socket->deleteLater();

// delete socket;
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы