Keep a reference to download objects for their lifetime. Should fix cancelling crashes.

This commit is contained in:
Henrik Rydgard 2013-06-26 19:24:49 +02:00
parent c9e1089261
commit 1777d9e835
2 changed files with 18 additions and 4 deletions

View File

@ -1,4 +1,5 @@
#include "net/http_client.h"
#include "base/timeutil.h"
#ifndef _WIN32
#include <arpa/inet.h>
@ -286,20 +287,27 @@ int Client::POST(const char *resource, const std::string &data, Buffer *output)
Download::Download(const std::string &url, const std::string &outfile)
: url_(url), outfile_(outfile), progress_(0.0f), failed_(false), resultCode_(0), cancelled_(false) {
std::thread th(std::bind(&Download::Do, this));
th.detach();
}
Download::~Download() {
}
void Download::Start(std::shared_ptr<Download> self)
{
std::thread th(std::bind(&Download::Do, this, self));
th.detach();
}
void Download::SetFailed(int code) {
failed_ = true;
progress_ = 1.0f;
}
void Download::Do() {
void Download::Do(std::shared_ptr<Download> self) {
// as long as this is in scope, we won't get destructed.
// yeah this is ugly, I need to think about how life time should be managed for these...
std::shared_ptr<Download> self_ = self;
resultCode_ = 0;
Url fileUrl(url_);
@ -349,6 +357,7 @@ void Download::Do() {
} else {
ELOG("Error downloading %s to %s: %i", url_.c_str(), outfile_.c_str(), resultCode);
}
resultCode_ = resultCode;
net::Shutdown();
progress_ = 1.0f;
@ -357,6 +366,7 @@ void Download::Do() {
std::shared_ptr<Download> Downloader::StartDownload(const std::string &url, const std::string &outfile) {
std::shared_ptr<Download> dl(new Download(url, outfile));
downloads_.push_back(dl);
dl->Start(dl);
return dl;
}

View File

@ -73,6 +73,10 @@ public:
Download(const std::string &url, const std::string &outfile);
~Download();
// Keeps around an instance of the shared_ptr, so that it doesn't get destructed
// until done.
void Start(std::shared_ptr<Download> self);
// Returns 1.0 when done. That one value can be compared exactly - or just use Done().
float Progress() const { return progress_; }
bool Done() const { return progress_ == 1.0f; }
@ -92,7 +96,7 @@ public:
}
private:
void Do(); // Actually does the download. Runs on thread.
void Do(std::shared_ptr<Download> self); // Actually does the download. Runs on thread.
void SetFailed(int code);
float progress_;
Buffer buffer_;