blob: f1dcc20a35e84e23d100d5086141048a1c0b3af4 [file] [log] [blame]
/*
* Copyright 2016 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "download.h"
#include <string>
#include <vector>
#include <thread>
namespace speedtest {
Download::Download(const Options &options)
: options_(options),
start_time_(0),
end_time_(0),
bytes_transferred_(0) {
}
Download::Result Download::operator()(std::atomic_bool *cancel) {
start_time_ = SystemTimeMicros();
bytes_transferred_ = 0;
if (!cancel) {
end_time_ = SystemTimeMicros();
return GetResult(Status(StatusCode::FAILED_PRECONDITION, "cancel is null"));
}
std::vector<std::thread> threads;
for (int i = 0; i < options_.num_transfers; ++i) {
threads.emplace_back([=]{
http::Request::Ptr download = options_.request_factory(i);
while (!*cancel) {
long downloaded = 0;
download->set_param("i", to_string(i));
download->set_param("size", to_string(options_.download_bytes));
download->set_param("time", to_string(SystemTimeMicros()));
download->set_progress_fn([&](curl_off_t,
curl_off_t dlnow,
curl_off_t,
curl_off_t) -> bool {
if (dlnow > downloaded) {
bytes_transferred_ += dlnow - downloaded;
downloaded = dlnow;
}
return *cancel;
});
download->Get();
download->Reset();
}
});
}
for (std::thread &thread : threads) {
if (thread.joinable()) {
thread.join();
}
}
end_time_ = SystemTimeMicros();
return GetResult(Status::OK);
}
Download::Result Download::GetResult(Status status) const {
Download::Result result;
result.start_time = start_time_;
result.end_time = end_time_;
result.status = status;
result.bytes_transferred = bytes_transferred_;
return result;
}
} // namespace