Russian Qt Forum

Qt => Работа с сетью => Тема начата: billygates от Февраль 25, 2010, 13:33



Название: [РЕШЕНО] QNetworkAccessManager: неверная работа с тредами валит приложение
Отправлено: billygates от Февраль 25, 2010, 13:33
Есть следующее (псевдо-код):

Код
C
class RequestMaker: public QObject
{
  Q_OBJECT
  private:
    QNetworkAccessManager mgr_;
  public:
    RequestMaker(QObject* parent) : QObject(parent), mgr_(this)
    {
       connect(&mgr_, SIGNAL(finished(QNetworkReply*)), this, SLOT(networkReplyReceived(QNetworkReply*)));
    }
    void sendRequest(...)
    {
        // compose request
        mgr_.post(...);
    }
  public signals:
     void responseReceived(Response*);
  private slots:
     void networkReplyReceived(QNetworkReply* reply)
     {
         // convert reply to a special struct
         Response* resp = ResponseMaker::make(reply);
         emit responseReceived(resp);
         reply->deleteLater();
     }
};
 

Данный класс используется в MainWindow: public QMainWindow, устанавливая слот на responseReceived(). Выполняет sendRequest() и в слоте responseReceived() делает widget.update(). После чего seg. fault.

Подозреваю, что слот выполняет в другом треде, и из-за этого такое поведение. Как заставить нормально отрабатывать данный сценарий с данным кодом? Может в каком-то месте надо сделать moveToThread() ?

Спасибо.


Название: Re: QNetworkAccessManager: неверная работа с тредами валит приложение
Отправлено: voronElf от Февраль 25, 2010, 14:07
Цитировать
Подозреваю, что слот выполняет в другом треде
тред тот же самый, если конечно ты сам за рамками этого кода с тредами не играешься. QNetworkAccessManager у меня отрабатывает нормально безо всяких moveToThread().

Я бы в первую очередь обратил внимание на то, что на основе reply создается resp, а reply сразу грохается. в resp нету укателей на данные из reply (уже удаленного на момент обращения) ?


Название: Re: QNetworkAccessManager: неверная работа с тредами валит приложение
Отправлено: billygates от Февраль 25, 2010, 14:21
тред тот же самый, если конечно ты сам за рамками этого кода с тредами не играешься. QNetworkAccessManager у меня отрабатывает нормально безо всяких moveToThread().

С тредами не играю: исключительно последовательные вызовы. gdb показывает, что создается несколько нитей:
Код:
- sendRequest()
[New Thread 0xb77ddb70 (LWP 13839)]
здесь же вызывается networkReplyReceived(QNetworkReply*)
[New Thread 0xb6fdcb70 (LWP 13840)]
еще одно сообщение (via qDebug) от networkReplyReceived(QNetworkReply*)

Я бы в первую очередь обратил внимание на то, что на основе reply создается resp, а reply сразу грохается. в resp нету укателей на данные из reply (уже удаленного на момент обращения) ?

Response не содержит указателей. Абсолютно статичные данные --  специально так проектировался.
Падает именно в той точке, где выполняется метод визуального виджета. По симптомам -- очень похоже на случай, когда из другого треда пытаются воздействовать на виджет, находящийся в другом потоке.


Название: Re: QNetworkAccessManager: неверная работа с тредами валит приложение
Отправлено: billygates от Февраль 25, 2010, 16:00
Сам дурак. Вопрос снят. Всем спасибо!

Указатель на виджет был obsolete (до этого он был перемещен в другое пространство имен, а старый остался), соответственно он нигде не инициализировался, отсюда и seg. fault.