Skip to content

Commit

Permalink
Qt/curl: fix segfault in curl
Browse files Browse the repository at this point in the history
The QThread lived longer than the m_curl object.
This lead to a crash when closing RPCS3 while the download is still in progress.
  • Loading branch information
Megamouse committed Jan 12, 2021
1 parent e05f1c3 commit 8433b70
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 5 deletions.
27 changes: 23 additions & 4 deletions rpcs3/rpcs3qt/downloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ downloader::downloader(QWidget* parent)
m_curl = new curl_handle(this);
}

downloader::~downloader()
{
m_curl_abort = true;
if (m_thread && m_thread->isRunning())
{
m_thread->wait();
}
}

void downloader::start(const std::string& url, bool follow_location, bool show_progress_dialog, const QString& progress_dialog_title, bool keep_progress_dialog_open, int exptected_size)
{
connect(this, &downloader::signal_buffer_update, this, &downloader::handle_buffer_update);
Expand All @@ -36,7 +45,17 @@ void downloader::start(const std::string& url, bool follow_location, bool show_p
curl_easy_setopt(m_curl->get_curl(), CURLOPT_WRITEDATA, this);
curl_easy_setopt(m_curl->get_curl(), CURLOPT_FOLLOWLOCATION, follow_location ? 1 : 0);

const auto thread = QThread::create([this]
if (m_thread)
{
m_curl_abort = true;
if (m_thread->isRunning())
{
m_thread->wait();
}
m_thread->deleteLater();
}

m_thread = QThread::create([this]
{
const auto result = curl_easy_perform(m_curl->get_curl());
m_curl_success = result == CURLE_OK;
Expand All @@ -49,7 +68,7 @@ void downloader::start(const std::string& url, bool follow_location, bool show_p
}
});

connect(thread, &QThread::finished, this, [this]()
connect(m_thread, &QThread::finished, this, [this]()
{
if (m_curl_abort)
{
Expand Down Expand Up @@ -95,8 +114,8 @@ void downloader::start(const std::string& url, bool follow_location, bool show_p
}
}

thread->setObjectName("Compat Update");
thread->start();
m_thread->setObjectName("Download Thread");
m_thread->start();
}

void downloader::update_progress_dialog(const QString& title)
Expand Down
5 changes: 4 additions & 1 deletion rpcs3/rpcs3qt/downloader.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ class downloader : public QObject
Q_OBJECT

public:
downloader(QWidget* parent = nullptr);
explicit downloader(QWidget* parent = nullptr);
~downloader();

void start(const std::string& url, bool follow_location, bool show_progress_dialog, const QString& progress_dialog_title = "", bool keep_progress_dialog_open = false, int expected_size = -1);
usz update_buffer(char* data, usz size);
Expand Down Expand Up @@ -43,4 +44,6 @@ private Q_SLOTS:
progress_dialog* m_progress_dialog = nullptr;
atomic_t<bool> m_keep_progress_dialog_open = false;
QString m_progress_dialog_title;

QThread* m_thread = nullptr;
};

0 comments on commit 8433b70

Please sign in to comment.