Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Unified Diff: chrome/browser/media_gallery/mtp_device_delegate_impl_linux.cc

Issue 11414221: Media Galleries: On Linux, write data to snapshots in chunks rather than at once. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/media_gallery/mtp_device_delegate_impl_linux.cc
===================================================================
--- chrome/browser/media_gallery/mtp_device_delegate_impl_linux.cc (revision 170236)
+++ chrome/browser/media_gallery/mtp_device_delegate_impl_linux.cc (working copy)
@@ -4,6 +4,10 @@
#include "chrome/browser/media_gallery/mtp_device_delegate_impl_linux.h"
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
#include "base/bind.h"
#include "base/file_path.h"
#include "base/file_util.h"
@@ -352,14 +356,18 @@
public:
// Constructed on |media_task_runner_| thread.
ReadFileWorker(const std::string& handle,
- const std::string& path,
+ const std::string& src_path,
uint32 total_size,
+ const FilePath& dest_path,
SequencedTaskRunner* task_runner,
WaitableEvent* task_completed_event,
WaitableEvent* shutdown_event)
: device_handle_(handle),
- path_(path),
+ src_path_(src_path),
+ bytes_read_(0),
total_bytes_(total_size),
+ dest_path_(dest_path),
+ dest_fd_(-1),
error_occurred_(false),
media_task_runner_(task_runner),
on_task_completed_event_(task_completed_event),
@@ -377,18 +385,25 @@
return;
}
- while (!error_occurred_ && (data_.size() < total_bytes_) &&
- !cancel_tasks_flag_.IsSet()) {
+ dest_fd_ = open(dest_path_.value().c_str(), O_WRONLY);
+ if (dest_fd_ < 0)
+ return;
+ dest_fd_scoper_.reset(&dest_fd_);
+
+ while (!error_occurred_ && (bytes_read_ < total_bytes_)) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
Bind(&ReadFileWorker::DoWorkOnUIThread, this));
on_task_completed_event_->Wait();
- if (on_shutdown_event_->IsSignaled())
+ if (on_shutdown_event_->IsSignaled()) {
cancel_tasks_flag_.Set();
+ break;
+ }
}
}
- // Returns the media file contents received from mtpd.
- const std::string& data() const { return data_; }
+ bool Succeeded() const {
+ return !error_occurred_ && bytes_read_ == total_bytes_;
+ }
// Returns the |media_task_runner_| associated with this worker object.
// This function is exposed for WorkerDeleter struct to access the
@@ -415,7 +430,7 @@
return;
GetMediaTransferProtocolManager()->ReadFileChunkByPath(
- device_handle_, path_, data_.size(), BytesToRead(),
+ device_handle_, src_path_, bytes_read_, BytesToRead(),
Bind(&ReadFileWorker::OnDidWorkOnUIThread, this));
}
@@ -427,16 +442,14 @@
if (cancel_tasks_flag_.IsSet())
return;
- error_occurred_ = error;
- if (!error) {
- if ((BytesToRead() == data.size())) {
- // TODO(kmadhusu): Data could be really huge. Consider passing data by
- // pointer/ref rather than by value here to avoid an extra data copy.
- data_.append(data);
- } else {
- NOTREACHED();
+ error_occurred_ = error || (data.size() != BytesToRead());
+ if (!error_occurred_) {
+ int bytes_written =
+ file_util::WriteFileDescriptor(dest_fd_, data.data(), data.size());
kmadhusu 2012/11/30 01:13:09 You are trying to do a file write operation on a U
+ if (static_cast<int>(data.size()) == bytes_written)
+ bytes_read_ += data.size();
+ else
error_occurred_ = true;
- }
}
on_task_completed_event_->Signal();
}
@@ -444,22 +457,30 @@
uint32 BytesToRead() const {
// Read data in 1 MB chunks.
static const uint32 kReadChunkSize = 1024 * 1024;
- return std::min(kReadChunkSize,
- total_bytes_ - static_cast<uint32>(data_.size()));
+ return std::min(kReadChunkSize, total_bytes_ - bytes_read_);
}
// The device unique identifier to query the device.
const std::string device_handle_;
// The media device file path.
- const std::string path_;
+ const std::string src_path_;
- // The data from mtpd.
- std::string data_;
+ // Number of bytes read from the device.
+ uint32 bytes_read_;
// Number of bytes to read.
const uint32 total_bytes_;
+ // Where to write the data read from the device.
+ const FilePath dest_path_;
+
+ // File descriptor for |dest_path_|.
+ int dest_fd_;
+
+ // Scoper to cleanup |dest_fd_|.
+ file_util::ScopedFD dest_fd_scoper_;
+
// Whether an error occurred during file transfer.
bool error_occurred_;
@@ -860,22 +881,17 @@
scoped_refptr<ReadFileWorker> worker(new ReadFileWorker(
device_handle_,
GetDeviceRelativePath(device_path_, device_file_path.value()),
- file_info->size,
+ file_info->size, local_path,
media_task_runner_, &on_task_completed_event_, &on_shutdown_event_));
worker->Run();
- const std::string& file_data = worker->data();
- int data_size = static_cast<int>(file_data.length());
- if (file_data.empty() ||
- file_util::WriteFile(local_path, file_data.c_str(),
- data_size) != data_size) {
+ if (!worker->Succeeded())
return base::PLATFORM_FILE_ERROR_FAILED;
- }
// Modify the last modified time to null. This prevents the time stamp
// verfication in LocalFileStreamReader.
file_info->last_modified = base::Time();
- return error;
+ return base::PLATFORM_FILE_OK;
}
SequencedTaskRunner* MTPDeviceDelegateImplLinux::GetMediaTaskRunner() {
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698