1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/file_system_provider/throttled_file_system.h"
10 #include "base/files/file.h"
11 #include "chrome/browser/chromeos/file_system_provider/queue.h"
14 namespace file_system_provider
{
16 ThrottledFileSystem::ThrottledFileSystem(
17 scoped_ptr
<ProvidedFileSystemInterface
> file_system
)
18 : file_system_(file_system
.Pass()), weak_ptr_factory_(this) {
19 const int opened_files_limit
=
20 file_system_
->GetFileSystemInfo().opened_files_limit();
21 open_queue_
.reset(opened_files_limit
22 ? new Queue(static_cast<size_t>(opened_files_limit
))
23 : new Queue(std::numeric_limits
<size_t>::max()));
26 ThrottledFileSystem::~ThrottledFileSystem() {
29 AbortCallback
ThrottledFileSystem::RequestUnmount(
30 const storage::AsyncFileUtil::StatusCallback
& callback
) {
31 return file_system_
->RequestUnmount(callback
);
34 AbortCallback
ThrottledFileSystem::GetMetadata(
35 const base::FilePath
& entry_path
,
36 MetadataFieldMask fields
,
37 const GetMetadataCallback
& callback
) {
38 return file_system_
->GetMetadata(entry_path
, fields
, callback
);
41 AbortCallback
ThrottledFileSystem::GetActions(
42 const base::FilePath
& entry_path
,
43 const GetActionsCallback
& callback
) {
44 return file_system_
->GetActions(entry_path
, callback
);
47 AbortCallback
ThrottledFileSystem::ExecuteAction(
48 const base::FilePath
& entry_path
,
49 const std::string
& action_id
,
50 const storage::AsyncFileUtil::StatusCallback
& callback
) {
51 return file_system_
->ExecuteAction(entry_path
, action_id
, callback
);
54 AbortCallback
ThrottledFileSystem::ReadDirectory(
55 const base::FilePath
& directory_path
,
56 const storage::AsyncFileUtil::ReadDirectoryCallback
& callback
) {
57 return file_system_
->ReadDirectory(directory_path
, callback
);
60 AbortCallback
ThrottledFileSystem::ReadFile(
62 net::IOBuffer
* buffer
,
65 const ReadChunkReceivedCallback
& callback
) {
66 return file_system_
->ReadFile(file_handle
, buffer
, offset
, length
, callback
);
69 AbortCallback
ThrottledFileSystem::OpenFile(const base::FilePath
& file_path
,
71 const OpenFileCallback
& callback
) {
72 const size_t task_token
= open_queue_
->NewToken();
76 &ProvidedFileSystemInterface::OpenFile
,
77 base::Unretained(file_system_
.get()), // Outlives the queue.
79 base::Bind(&ThrottledFileSystem::OnOpenFileCompleted
,
80 weak_ptr_factory_
.GetWeakPtr(), task_token
, callback
)));
81 return base::Bind(&ThrottledFileSystem::Abort
, weak_ptr_factory_
.GetWeakPtr(),
85 AbortCallback
ThrottledFileSystem::CloseFile(
87 const storage::AsyncFileUtil::StatusCallback
& callback
) {
88 return file_system_
->CloseFile(
90 base::Bind(&ThrottledFileSystem::OnCloseFileCompleted
,
91 weak_ptr_factory_
.GetWeakPtr(), file_handle
, callback
));
94 AbortCallback
ThrottledFileSystem::CreateDirectory(
95 const base::FilePath
& directory_path
,
97 const storage::AsyncFileUtil::StatusCallback
& callback
) {
98 return file_system_
->CreateDirectory(directory_path
, recursive
, callback
);
101 AbortCallback
ThrottledFileSystem::DeleteEntry(
102 const base::FilePath
& entry_path
,
104 const storage::AsyncFileUtil::StatusCallback
& callback
) {
105 return file_system_
->DeleteEntry(entry_path
, recursive
, callback
);
108 AbortCallback
ThrottledFileSystem::CreateFile(
109 const base::FilePath
& file_path
,
110 const storage::AsyncFileUtil::StatusCallback
& callback
) {
111 return file_system_
->CreateFile(file_path
, callback
);
114 AbortCallback
ThrottledFileSystem::CopyEntry(
115 const base::FilePath
& source_path
,
116 const base::FilePath
& target_path
,
117 const storage::AsyncFileUtil::StatusCallback
& callback
) {
118 return file_system_
->CopyEntry(source_path
, target_path
, callback
);
121 AbortCallback
ThrottledFileSystem::WriteFile(
123 net::IOBuffer
* buffer
,
126 const storage::AsyncFileUtil::StatusCallback
& callback
) {
127 return file_system_
->WriteFile(file_handle
, buffer
, offset
, length
, callback
);
130 AbortCallback
ThrottledFileSystem::MoveEntry(
131 const base::FilePath
& source_path
,
132 const base::FilePath
& target_path
,
133 const storage::AsyncFileUtil::StatusCallback
& callback
) {
134 return file_system_
->MoveEntry(source_path
, target_path
, callback
);
137 AbortCallback
ThrottledFileSystem::Truncate(
138 const base::FilePath
& file_path
,
140 const storage::AsyncFileUtil::StatusCallback
& callback
) {
141 return file_system_
->Truncate(file_path
, length
, callback
);
144 AbortCallback
ThrottledFileSystem::AddWatcher(
146 const base::FilePath
& entry_path
,
149 const storage::AsyncFileUtil::StatusCallback
& callback
,
150 const storage::WatcherManager::NotificationCallback
&
151 notification_callback
) {
152 return file_system_
->AddWatcher(origin
, entry_path
, recursive
, persistent
,
153 callback
, notification_callback
);
156 void ThrottledFileSystem::RemoveWatcher(
158 const base::FilePath
& entry_path
,
160 const storage::AsyncFileUtil::StatusCallback
& callback
) {
161 file_system_
->RemoveWatcher(origin
, entry_path
, recursive
, callback
);
164 const ProvidedFileSystemInfo
& ThrottledFileSystem::GetFileSystemInfo() const {
165 return file_system_
->GetFileSystemInfo();
168 RequestManager
* ThrottledFileSystem::GetRequestManager() {
169 return file_system_
->GetRequestManager();
172 Watchers
* ThrottledFileSystem::GetWatchers() {
173 return file_system_
->GetWatchers();
176 const OpenedFiles
& ThrottledFileSystem::GetOpenedFiles() const {
177 return file_system_
->GetOpenedFiles();
180 void ThrottledFileSystem::AddObserver(ProvidedFileSystemObserver
* observer
) {
181 file_system_
->AddObserver(observer
);
184 void ThrottledFileSystem::RemoveObserver(ProvidedFileSystemObserver
* observer
) {
185 file_system_
->RemoveObserver(observer
);
188 void ThrottledFileSystem::Notify(
189 const base::FilePath
& entry_path
,
191 storage::WatcherManager::ChangeType change_type
,
192 scoped_ptr
<ProvidedFileSystemObserver::Changes
> changes
,
193 const std::string
& tag
,
194 const storage::AsyncFileUtil::StatusCallback
& callback
) {
195 return file_system_
->Notify(entry_path
, recursive
, change_type
,
196 changes
.Pass(), tag
, callback
);
199 void ThrottledFileSystem::Configure(
200 const storage::AsyncFileUtil::StatusCallback
& callback
) {
201 return file_system_
->Configure(callback
);
204 base::WeakPtr
<ProvidedFileSystemInterface
> ThrottledFileSystem::GetWeakPtr() {
205 return weak_ptr_factory_
.GetWeakPtr();
208 void ThrottledFileSystem::Abort(int queue_token
) {
209 open_queue_
->Abort(queue_token
);
212 void ThrottledFileSystem::OnOpenFileCompleted(int queue_token
,
213 const OpenFileCallback
& callback
,
215 base::File::Error result
) {
216 // If the file is opened successfully then hold the queue token until the file
218 if (result
== base::File::FILE_OK
)
219 opened_files_
[file_handle
] = queue_token
;
221 open_queue_
->Complete(queue_token
);
223 callback
.Run(file_handle
, result
);
226 void ThrottledFileSystem::OnCloseFileCompleted(
228 const storage::AsyncFileUtil::StatusCallback
& callback
,
229 base::File::Error result
) {
230 // Closing is always final. Even if an error happened, the file is considered
231 // closed on the C++ side. Release the task from the queue, so other files
232 // which are enqueued can be opened.
233 const auto it
= opened_files_
.find(file_handle
);
234 DCHECK(it
!= opened_files_
.end());
236 const int queue_token
= it
->second
;
237 open_queue_
->Complete(queue_token
);
238 opened_files_
.erase(file_handle
);
240 callback
.Run(result
);
243 } // namespace file_system_provider
244 } // namespace chromeos