Skip to content

Commit

Permalink
http: Make sure we don't hang checking existance.
Browse files Browse the repository at this point in the history
It's not great to delay loading when the server is down - we'll do a
proper check when we display the games.

This also fixes shutdown being slow.
  • Loading branch information
unknownbrackets committed Jul 4, 2016
1 parent c793efd commit 3b843b9
Show file tree
Hide file tree
Showing 12 changed files with 90 additions and 14 deletions.
2 changes: 1 addition & 1 deletion Core/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1141,7 +1141,7 @@ void Config::CleanRecent() {
std::vector<std::string> cleanedRecent;
for (size_t i = 0; i < recentIsos.size(); i++) {
FileLoader *loader = ConstructFileLoader(recentIsos[i]);
if (loader->Exists()) {
if (loader->ExistsFast()) {
// Make sure we don't have any redundant items.
auto duplicate = std::find(cleanedRecent.begin(), cleanedRecent.end(), recentIsos[i]);
if (duplicate == cleanedRecent.end()) {
Expand Down
22 changes: 20 additions & 2 deletions Core/FileLoaders/CachingFileLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,16 @@

// Takes ownership of backend.
CachingFileLoader::CachingFileLoader(FileLoader *backend)
: filesize_(0), filepos_(0), backend_(backend), exists_(-1), isDirectory_(-1), aheadThread_(false) {
filesize_ = backend->FileSize();
: filesize_(0), filepos_(0), backend_(backend), exists_(-1), isDirectory_(-1), aheadThread_(false), prepared_(false) {
}

void CachingFileLoader::Prepare() {
if (prepared_) {
return;
}
prepared_ = true;

filesize_ = backend_->FileSize();
if (filesize_ > 0) {
InitCache();
}
Expand All @@ -46,6 +54,14 @@ bool CachingFileLoader::Exists() {
return exists_ == 1;
}

bool CachingFileLoader::ExistsFast() {
if (exists_ == -1) {
lock_guard guard(backendMutex_);
return backend_->ExistsFast();
}
return exists_ == 1;
}

bool CachingFileLoader::IsDirectory() {
if (isDirectory_ == -1) {
lock_guard guard(backendMutex_);
Expand All @@ -55,6 +71,7 @@ bool CachingFileLoader::IsDirectory() {
}

s64 CachingFileLoader::FileSize() {
Prepare();
return filesize_;
}

Expand All @@ -68,6 +85,7 @@ void CachingFileLoader::Seek(s64 absolutePos) {
}

size_t CachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) {
Prepare();
if (absolutePos >= filesize_) {
bytes = 0;
} else if (absolutePos + (s64)bytes >= filesize_) {
Expand Down
3 changes: 3 additions & 0 deletions Core/FileLoaders/CachingFileLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class CachingFileLoader : public FileLoader {
virtual ~CachingFileLoader() override;

virtual bool Exists() override;
virtual bool ExistsFast() override;
virtual bool IsDirectory() override;
virtual s64 FileSize() override;
virtual std::string Path() const override;
Expand All @@ -45,6 +46,7 @@ class CachingFileLoader : public FileLoader {
virtual size_t ReadAt(s64 absolutePos, size_t bytes, void *data) override;

private:
void Prepare();
void InitCache();
void ShutdownCache();
size_t ReadFromCache(s64 pos, size_t bytes, void *data);
Expand Down Expand Up @@ -84,4 +86,5 @@ class CachingFileLoader : public FileLoader {
recursive_mutex blocksMutex_;
mutable recursive_mutex backendMutex_;
bool aheadThread_;
bool prepared_;
};
28 changes: 20 additions & 8 deletions Core/FileLoaders/DiskCachingFileLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,16 @@ recursive_mutex DiskCachingFileLoader::cachesMutex_;

// Takes ownership of backend.
DiskCachingFileLoader::DiskCachingFileLoader(FileLoader *backend)
: filesize_(0), filepos_(0), backend_(backend), cache_(nullptr) {
filesize_ = backend->FileSize();
: prepared_(false), filesize_(0), filepos_(0), backend_(backend), cache_(nullptr) {
}

void DiskCachingFileLoader::Prepare() {
if (prepared_) {
return;
}
prepared_ = true;

filesize_ = backend_->FileSize();
if (filesize_ > 0) {
InitCache();
}
Expand All @@ -54,19 +62,22 @@ DiskCachingFileLoader::~DiskCachingFileLoader() {
}

bool DiskCachingFileLoader::Exists() {
if (cache_ && cache_->HasData()) {
// It may require a slow operation to check - if we have data, let's say yes.
// This helps initial load, since we check each recent file for existence.
return true;
}
Prepare();
return backend_->Exists();
}

bool DiskCachingFileLoader::ExistsFast() {
// It may require a slow operation to check - if we have data, let's say yes.
// This helps initial load, since we check each recent file for existence.
return true;
}

bool DiskCachingFileLoader::IsDirectory() {
return backend_->IsDirectory() ? 1 : 0;
return backend_->IsDirectory();
}

s64 DiskCachingFileLoader::FileSize() {
Prepare();
return filesize_;
}

Expand All @@ -79,6 +90,7 @@ void DiskCachingFileLoader::Seek(s64 absolutePos) {
}

size_t DiskCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) {
Prepare();
size_t readSize;

if (absolutePos >= filesize_) {
Expand Down
3 changes: 3 additions & 0 deletions Core/FileLoaders/DiskCachingFileLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class DiskCachingFileLoader : public FileLoader {
virtual ~DiskCachingFileLoader() override;

virtual bool Exists() override;
virtual bool ExistsFast() override;
virtual bool IsDirectory() override;
virtual s64 FileSize() override;
virtual std::string Path() const override;
Expand All @@ -50,9 +51,11 @@ class DiskCachingFileLoader : public FileLoader {
static std::vector<std::string> GetCachedPathsInUse();

private:
void Prepare();
void InitCache();
void ShutdownCache();

bool prepared_;
s64 filesize_;
s64 filepos_;
FileLoader *backend_;
Expand Down
21 changes: 18 additions & 3 deletions Core/FileLoaders/HTTPFileLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,15 @@
#include "Core/FileLoaders/HTTPFileLoader.h"

HTTPFileLoader::HTTPFileLoader(const std::string &filename)
: filesize_(0), filepos_(0), url_(filename), filename_(filename), connected_(false) {
: filesize_(0), filepos_(0), url_(filename), filename_(filename), connected_(false), prepared_(false) {
}

void HTTPFileLoader::Prepare() {
if (prepared_) {
return;
}
prepared_ = true;

if (!client_.Resolve(url_.Host().c_str(), url_.Port())) {
// TODO: Should probably set some flag?
return;
Expand All @@ -39,7 +47,7 @@ HTTPFileLoader::HTTPFileLoader(const std::string &filename)
int code = client_.ReadResponseHeaders(&readbuf, responseHeaders);
if (code != 200) {
// Leave size at 0, invalid.
ERROR_LOG(LOADER, "HTTP request failed, got %03d for %s", code, filename.c_str());
ERROR_LOG(LOADER, "HTTP request failed, got %03d for %s", code, filename_.c_str());
Disconnect();
return;
}
Expand Down Expand Up @@ -78,7 +86,7 @@ HTTPFileLoader::HTTPFileLoader(const std::string &filename)
WARN_LOG(LOADER, "HTTP server did not advertise support for range requests.");
}
if (filesize_ == 0) {
ERROR_LOG(LOADER, "Could not determine file size for %s", filename.c_str());
ERROR_LOG(LOADER, "Could not determine file size for %s", filename_.c_str());
}

// If we didn't end up with a filesize_ (e.g. chunked response), give up. File invalid.
Expand All @@ -89,15 +97,21 @@ HTTPFileLoader::~HTTPFileLoader() {
}

bool HTTPFileLoader::Exists() {
Prepare();
return url_.Valid() && filesize_ > 0;
}

bool HTTPFileLoader::ExistsFast() {
return url_.Valid();
}

bool HTTPFileLoader::IsDirectory() {
// Only files.
return false;
}

s64 HTTPFileLoader::FileSize() {
Prepare();
return filesize_;
}

Expand All @@ -110,6 +124,7 @@ void HTTPFileLoader::Seek(s64 absolutePos) {
}

size_t HTTPFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data) {
Prepare();
s64 absoluteEnd = std::min(absolutePos + (s64)bytes, filesize_);
if (absolutePos >= filesize_ || bytes == 0) {
// Read outside of the file or no read at all, just fail immediately.
Expand Down
4 changes: 4 additions & 0 deletions Core/FileLoaders/HTTPFileLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class HTTPFileLoader : public FileLoader {
virtual ~HTTPFileLoader() override;

virtual bool Exists() override;
virtual bool ExistsFast() override;
virtual bool IsDirectory() override;
virtual s64 FileSize() override;
virtual std::string Path() const override;
Expand All @@ -46,6 +47,8 @@ class HTTPFileLoader : public FileLoader {
virtual size_t ReadAt(s64 absolutePos, size_t bytes, void *data) override;

private:
void Prepare();

void Connect() {
if (!connected_) {
connected_ = client_.Connect();
Expand All @@ -66,4 +69,5 @@ class HTTPFileLoader : public FileLoader {
http::Client client_;
std::string filename_;
bool connected_;
bool prepared_;
};
8 changes: 8 additions & 0 deletions Core/FileLoaders/RamCachingFileLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ bool RamCachingFileLoader::Exists() {
return exists_ == 1;
}

bool RamCachingFileLoader::ExistsFast() {
if (exists_ == -1) {
lock_guard guard(backendMutex_);
return backend_->ExistsFast();
}
return exists_ == 1;
}

bool RamCachingFileLoader::IsDirectory() {
if (isDirectory_ == -1) {
lock_guard guard(backendMutex_);
Expand Down
1 change: 1 addition & 0 deletions Core/FileLoaders/RamCachingFileLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class RamCachingFileLoader : public FileLoader {
~RamCachingFileLoader() override;

bool Exists() override;
bool ExistsFast() override;
bool IsDirectory() override;
s64 FileSize() override;
std::string Path() const override;
Expand Down
8 changes: 8 additions & 0 deletions Core/FileLoaders/RetryingFileLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ bool RetryingFileLoader::Exists() {
return true;
}

bool RetryingFileLoader::ExistsFast() {
if (!backend_->ExistsFast()) {
// Retry once, immediately.
return backend_->ExistsFast();
}
return true;
}

bool RetryingFileLoader::IsDirectory() {
// Can't tell if it's an error either way.
return backend_->IsDirectory();
Expand Down
1 change: 1 addition & 0 deletions Core/FileLoaders/RetryingFileLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class RetryingFileLoader : public FileLoader {
virtual ~RetryingFileLoader() override;

virtual bool Exists() override;
virtual bool ExistsFast() override;
virtual bool IsDirectory() override;
virtual s64 FileSize() override;
virtual std::string Path() const override;
Expand Down
3 changes: 3 additions & 0 deletions Core/Loaders.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ class FileLoader {
virtual ~FileLoader() {}

virtual bool Exists() = 0;
virtual bool ExistsFast() {
return Exists();
}
virtual bool IsDirectory() = 0;
virtual s64 FileSize() = 0;
virtual std::string Path() const = 0;
Expand Down

0 comments on commit 3b843b9

Please sign in to comment.