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

Side by Side Diff: webkit/blob/blob_storage_context.cc

Issue 14139026: New blobstoragecontext for use in the main browser process, not plugged in yet. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 7 years, 8 months 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "webkit/blob/blob_storage_controller.h" 5 #include "webkit/blob/blob_storage_context.h"
6 6
7 #include "base/bind.h"
8 #include "base/location.h"
7 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/message_loop_proxy.h"
11 #include "base/sys_info.h"
8 #include "googleurl/src/gurl.h" 12 #include "googleurl/src/gurl.h"
9 #include "webkit/blob/blob_data.h" 13 #include "webkit/blob/blob_data.h"
10 14
11 namespace webkit_blob { 15 namespace webkit_blob {
12 16
13 namespace { 17 namespace {
14 18
15 // We can't use GURL directly for these hash fragment manipulations 19 // We can't use GURL directly for these hash fragment manipulations
16 // since it doesn't have specific knowlege of the BlobURL format. GURL 20 // since it doesn't have specific knowlege of the BlobURL format. GURL
17 // treats BlobURLs as if they were PathURLs which don't support hash 21 // treats BlobURLs as if they were PathURLs which don't support hash
18 // fragments. 22 // fragments.
19 23
20 bool BlobUrlHasRef(const GURL& url) { 24 bool BlobUrlHasRef(const GURL& url) {
21 return url.spec().find('#') != std::string::npos; 25 return url.spec().find('#') != std::string::npos;
22 } 26 }
23 27
24 GURL ClearBlobUrlRef(const GURL& url) { 28 GURL ClearBlobUrlRef(const GURL& url) {
25 size_t hash_pos = url.spec().find('#'); 29 size_t hash_pos = url.spec().find('#');
26 if (hash_pos == std::string::npos) 30 if (hash_pos == std::string::npos)
27 return url; 31 return url;
28 return GURL(url.spec().substr(0, hash_pos)); 32 return GURL(url.spec().substr(0, hash_pos));
29 } 33 }
30 34
31 static const int64 kMaxMemoryUsage = 1024 * 1024 * 1024; // 1G 35 // TODO(michaeln): use base::SysInfo::AmountOfPhysicalMemoryMB() in some
36 // way to come up with a better limit.
37 static const int64 kMaxMemoryUsage = 500 * 1024 * 1024; // Half a gig.
32 38
33 } // namespace 39 } // namespace
34 40
35 BlobStorageController::BlobStorageController() 41 //-----------------------------------------------------------------------
42 // BlobDataHandle
43 //-----------------------------------------------------------------------
44
45 BlobDataHandle::BlobDataHandle(BlobData* blob_data, BlobStorageContext* context,
46 base::SequencedTaskRunner* task_runner)
47 : blob_data_(blob_data),
48 context_(context->AsWeakPtr()),
49 io_task_runner_(task_runner) {
50 // Ensures the uuid remains registered and the underlying data is not deleted.
51 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
52 context_->IncrementBlobRefCount(blob_data->uuid());
53 blob_data_->AddRef();
54 }
55
56 BlobDataHandle::~BlobDataHandle() {
57 if (io_task_runner_->RunsTasksOnCurrentThread()) {
58 // Note: Do not test context_ on the wrong thread.
59 if (context_.get())
60 context_->DecrementBlobRefCount(blob_data_->uuid());
61 blob_data_->Release();
ericu 2013/04/24 23:54:43 Wouldn't this be a bit cleaner with a scoped_refpt
michaeln 2013/04/25 01:21:37 It would not be cleaner because there is no api to
ericu 2013/04/26 22:17:37 Arg. OK, that's clearly not better. Nevermind.
62 return;
63 }
64
65 io_task_runner_->PostTask(
66 FROM_HERE,
67 base::Bind(&DeleteHelper, context_, base::Unretained(blob_data_)));
68 }
69
70 BlobData* BlobDataHandle::data() const {
71 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
72 return blob_data_;
73 }
74
75 // static
76 void BlobDataHandle::DeleteHelper(
77 base::WeakPtr<BlobStorageContext> context,
78 BlobData* blob_data) {
79 if (context.get())
80 context->DecrementBlobRefCount(blob_data->uuid());
81 blob_data->Release();
82 }
83
84 //-----------------------------------------------------------------------
85 // BlobStorageHost
86 //-----------------------------------------------------------------------
87
88 BlobStorageHost::BlobStorageHost(BlobStorageContext* context)
89 : context_(context->AsWeakPtr()) {
90 }
91
92 BlobStorageHost::~BlobStorageHost() {
93 if (!context_)
94 return;
95 for (std::set<GURL>::iterator iter = public_blob_urls_.begin();
96 iter != public_blob_urls_.end(); ++iter) {
97 context_->RevokePublicBlobURL(*iter);
98 }
99 for (BlobReferenceMap::iterator iter = blobs_inuse_map_.begin();
100 iter != blobs_inuse_map_.end(); ++iter) {
101 for (int i = 0; i < iter->second; ++i)
102 context_->DecrementBlobRefCount(iter->first);
103 }
104 }
105
106 bool BlobStorageHost::StartBuildingBlob(const std::string& uuid) {
107 if (!context_ || context_->IsInUse(uuid))
108 return false;
109 context_->StartBuildingBlob(uuid);
110 blobs_inuse_map_[uuid] = 1;
111 return true;
112 }
113
114 bool BlobStorageHost::AppendBlobDataItem(
115 const std::string& uuid, const BlobData::Item& data_item) {
116 if (!context_ || !HasUseCountOfOne(uuid))
117 return false;
118 context_->AppendBlobDataItem(uuid, data_item);
119 return true;
120 }
121
122 bool BlobStorageHost::CancelBuildingBlob(const std::string& uuid) {
123 if (!context_ || !HasUseCountOfOne(uuid))
124 return false;
125 blobs_inuse_map_.erase(uuid);
126 context_->CancelBuildingBlob(uuid);
127 return true;
128 }
129
130 bool BlobStorageHost::FinishBuildingBlob(
131 const std::string& uuid, const std::string& content_type) {
132 if (!context_ || !HasUseCountOfOne(uuid))
133 return false;
134 context_->FinishBuildingBlob(uuid, content_type);
135 return true;
136 }
137
138 bool BlobStorageHost::IncrementBlobRefCount(const std::string& uuid) {
139 if (!context_ || !context_->IsInUse(uuid))
140 return false;
141 context_->IncrementBlobRefCount(uuid);
142 blobs_inuse_map_[uuid] += 1;
143 return true;
144 }
145
146 bool BlobStorageHost::DecrementBlobRefCount(const std::string& uuid) {
147 if (!context_ || !IsInUse(uuid))
148 return false;
149 context_->DecrementBlobRefCount(uuid);
150 blobs_inuse_map_[uuid] -= 1;
151 if (blobs_inuse_map_[uuid] == 0)
152 blobs_inuse_map_.erase(uuid);
153 return true;
154 }
155
156 bool BlobStorageHost::RegisterPublicBlobURL(
157 const GURL& blob_url, const std::string& uuid) {
158 if (!context_ || !IsInUse(uuid) || context_->IsUrlRegistered(blob_url))
159 return false;
160 context_->RegisterPublicBlobURL(blob_url, uuid);
161 public_blob_urls_.insert(blob_url);
162 return true;
163 }
164
165 bool BlobStorageHost::RevokePublicBlobURL(const GURL& blob_url) {
166 if (!context_ || !IsUrlRegistered(blob_url))
167 return false;
168 context_->RevokePublicBlobURL(blob_url);
169 public_blob_urls_.erase(blob_url);
170 return true;
171 }
172
173 bool BlobStorageHost::IsInUse(const std::string& uuid) {
174 return blobs_inuse_map_.find(uuid) != blobs_inuse_map_.end();
175 }
176
177 bool BlobStorageHost::HasUseCountOfOne(const std::string& uuid) {
178 return IsInUse(uuid) && (blobs_inuse_map_[uuid] == 1);
ericu 2013/04/24 23:54:43 Given how often this is called, you might want to
michaeln 2013/04/25 01:21:37 will do when splitting files
ericu 2013/04/26 22:17:37 OK; if that's not going to be in the next upload,
michaeln 2013/04/29 18:32:48 this is done elsewhere, see later comment about wh
179 }
180
181 bool BlobStorageHost::IsUrlRegistered(const GURL& blob_url) {
182 return public_blob_urls_.find(blob_url) != public_blob_urls_.end();
183 }
184
185 //-----------------------------------------------------------------------
186 // BlobStorageContext
187 //-----------------------------------------------------------------------
188
189 BlobStorageContext::BlobStorageContext()
36 : memory_usage_(0) { 190 : memory_usage_(0) {
37 } 191 }
38 192
39 BlobStorageController::~BlobStorageController() { 193 BlobStorageContext::~BlobStorageContext() {
40 } 194 }
41 195
42 void BlobStorageController::StartBuildingBlob(const GURL& url) { 196 scoped_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromUUID(
43 DCHECK(url.SchemeIs("blob")); 197 const std::string& uuid) {
44 DCHECK(!BlobUrlHasRef(url)); 198 scoped_ptr<BlobDataHandle> result;
45 BlobData* blob_data = new BlobData; 199 BlobMap::iterator found = blob_map_.find(uuid);
46 unfinalized_blob_map_[url.spec()] = blob_data; 200 if (found == blob_map_.end())
47 IncrementBlobDataUsage(blob_data); 201 return result.Pass();
48 } 202 if (found->second.flags & EXCEEDED_MEMORY)
49 203 return result.Pass();
50 void BlobStorageController::AppendBlobDataItem( 204 DCHECK(!(found->second.flags & BEING_BUILT));
51 const GURL& url, const BlobData::Item& item) { 205 result.reset(new BlobDataHandle(found->second.data, this,
52 DCHECK(url.SchemeIs("blob")); 206 base::MessageLoopProxy::current()));
53 DCHECK(!BlobUrlHasRef(url)); 207 return result.Pass();
54 BlobMap::iterator found = unfinalized_blob_map_.find(url.spec()); 208 }
55 if (found == unfinalized_blob_map_.end()) 209
56 return; 210 scoped_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromPublicURL(
57 BlobData* target_blob_data = found->second; 211 const GURL& url) {
212 BlobURLMap::iterator found = public_blob_urls_.find(
213 BlobUrlHasRef(url) ? ClearBlobUrlRef(url) : url);
214 if (found == public_blob_urls_.end())
215 return scoped_ptr<BlobDataHandle>();
216 return GetBlobDataFromUUID(found->second);
217 }
218
219 scoped_ptr<BlobDataHandle> BlobStorageContext::AddFinishedBlob(
220 const BlobData* data) {
221 StartBuildingBlob(data->uuid());
222 for (std::vector<BlobData::Item>::const_iterator iter =
223 data->items().begin();
224 iter != data->items().end(); ++iter) {
225 AppendBlobDataItem(data->uuid(), *iter);
226 }
227 FinishBuildingBlob(data->uuid(), data->content_type());
228 scoped_ptr<BlobDataHandle> handle = GetBlobDataFromUUID(data->uuid());
229 DecrementBlobRefCount(data->uuid());
230 return handle.Pass();
231 }
232
233 void BlobStorageContext::StartBuildingBlob(const std::string& uuid) {
234 DCHECK(!IsInUse(uuid));
235 blob_map_[uuid] = BlobMapEntry(1, BEING_BUILT, new BlobData(uuid));
236 }
237
238 void BlobStorageContext::AppendBlobDataItem(
239 const std::string& uuid, const BlobData::Item& item) {
240 BlobMap::iterator found = blob_map_.find(uuid);
241 if (found == blob_map_.end())
242 return;
243 if (found->second.flags & EXCEEDED_MEMORY)
ericu 2013/04/24 23:54:43 Check for BEING_BUILT too?
michaeln 2013/04/25 01:21:37 i'll add a DCHECK here, and an IsBeingBuilt() for
michaeln 2013/04/25 21:22:46 I've massaged the rel and dbg runtime checks a lit
244 return;
245 BlobData* target_blob_data = found->second.data;
58 DCHECK(target_blob_data); 246 DCHECK(target_blob_data);
59 247
60 memory_usage_ -= target_blob_data->GetMemoryUsage(); 248 memory_usage_ -= target_blob_data->GetMemoryUsage();
61 249
62 // The blob data is stored in the "canonical" way. That is, it only contains a 250 // The blob data is stored in the "canonical" way. That is, it only contains a
63 // list of Data and File items. 251 // list of Data and File items.
64 // 1) The Data item is denoted by the raw data and the range. 252 // 1) The Data item is denoted by the raw data and the range.
65 // 2) The File item is denoted by the file path, the range and the expected 253 // 2) The File item is denoted by the file path, the range and the expected
66 // modification time. 254 // modification time.
67 // 3) The FileSystem File item is denoted by the FileSystem URL, the range 255 // 3) The FileSystem File item is denoted by the FileSystem URL, the range
68 // and the expected modification time. 256 // and the expected modification time.
69 // All the Blob items in the passing blob data are resolved and expanded into 257 // All the Blob items in the passing blob data are resolved and expanded into
70 // a set of Data and File items. 258 // a set of Data, File, and FileSystemFile items.
71 259
72 DCHECK(item.length() > 0); 260 DCHECK(item.length() > 0);
73 switch (item.type()) { 261 switch (item.type()) {
74 case BlobData::Item::TYPE_BYTES: 262 case BlobData::Item::TYPE_BYTES:
75 DCHECK(!item.offset()); 263 DCHECK(!item.offset());
76 target_blob_data->AppendData(item.bytes(), item.length()); 264 target_blob_data->AppendData(item.bytes(), item.length());
77 break; 265 break;
78 case BlobData::Item::TYPE_FILE: 266 case BlobData::Item::TYPE_FILE:
79 AppendFileItem(target_blob_data, 267 AppendFileItem(target_blob_data,
80 item.path(), 268 item.path(),
81 item.offset(), 269 item.offset(),
82 item.length(), 270 item.length(),
83 item.expected_modification_time()); 271 item.expected_modification_time());
84 break; 272 break;
85 case BlobData::Item::TYPE_FILE_FILESYSTEM: 273 case BlobData::Item::TYPE_FILE_FILESYSTEM:
86 AppendFileSystemFileItem(target_blob_data, 274 AppendFileSystemFileItem(target_blob_data,
87 item.url(), 275 item.filesystem_url(),
88 item.offset(), 276 item.offset(),
89 item.length(), 277 item.length(),
90 item.expected_modification_time()); 278 item.expected_modification_time());
91 break; 279 break;
92 case BlobData::Item::TYPE_BLOB: { 280 case BlobData::Item::TYPE_BLOB: {
93 BlobData* src_blob_data = GetBlobDataFromUrl(item.url()); 281 scoped_ptr<BlobDataHandle> src = GetBlobDataFromUUID(item.blob_uuid());
94 DCHECK(src_blob_data); 282 DCHECK(src.get());
95 if (src_blob_data) 283 if (src.get())
96 AppendStorageItems(target_blob_data, 284 AppendStorageItems(target_blob_data,
97 src_blob_data, 285 src->data(),
98 item.offset(), 286 item.offset(),
99 item.length()); 287 item.length());
100 break; 288 break;
101 } 289 }
102 default: 290 default:
103 NOTREACHED(); 291 NOTREACHED();
104 break; 292 break;
105 } 293 }
106 294
107 memory_usage_ += target_blob_data->GetMemoryUsage(); 295 memory_usage_ += target_blob_data->GetMemoryUsage();
108 296
109 // If we're using too much memory, drop this blob. 297 // If we're using too much memory, drop this blob.
110 // TODO(michaeln): Blob memory storage does not yet spill over to disk, 298 // TODO(michaeln): Blob memory storage does not yet spill over to disk,
111 // until it does, we'll prevent memory usage over a max amount. 299 // as a stop gap, we'll prevent memory usage over a max amount.
112 if (memory_usage_ > kMaxMemoryUsage) 300 if (memory_usage_ > kMaxMemoryUsage) {
113 RemoveBlob(url); 301 // TODO(michaeln): Hoist this test up to before we go over.
302 memory_usage_ -= target_blob_data->GetMemoryUsage();
303 found->second.flags |= EXCEEDED_MEMORY;
304 found->second.data = new BlobData(uuid);
305 }
114 } 306 }
115 307
116 void BlobStorageController::FinishBuildingBlob( 308 void BlobStorageContext::FinishBuildingBlob(
117 const GURL& url, const std::string& content_type) { 309 const std::string& uuid, const std::string& content_type) {
118 DCHECK(url.SchemeIs("blob")); 310 BlobMap::iterator found = blob_map_.find(uuid);
119 DCHECK(!BlobUrlHasRef(url)); 311 if (found == blob_map_.end())
120 BlobMap::iterator found = unfinalized_blob_map_.find(url.spec());
121 if (found == unfinalized_blob_map_.end())
122 return; 312 return;
123 found->second->set_content_type(content_type); 313 found->second.data->set_content_type(content_type);
124 blob_map_[url.spec()] = found->second; 314 found->second.flags &= ~BEING_BUILT;
ericu 2013/04/24 23:54:43 DCHECK before clearing it?
125 unfinalized_blob_map_.erase(found);
126 } 315 }
127 316
128 void BlobStorageController::AddFinishedBlob(const GURL& url, 317 void BlobStorageContext::CancelBuildingBlob(const std::string& uuid) {
129 const BlobData* data) { 318 DecrementBlobRefCount(uuid);
130 StartBuildingBlob(url);
131 for (std::vector<BlobData::Item>::const_iterator iter =
132 data->items().begin();
133 iter != data->items().end(); ++iter) {
134 AppendBlobDataItem(url, *iter);
135 }
136 FinishBuildingBlob(url, data->content_type());
137 } 319 }
138 320
139 void BlobStorageController::CloneBlob( 321 void BlobStorageContext::IncrementBlobRefCount(const std::string& uuid) {
140 const GURL& url, const GURL& src_url) { 322 BlobMap::iterator found = blob_map_.find(uuid);
141 DCHECK(url.SchemeIs("blob")); 323 if (found == blob_map_.end()) {
142 DCHECK(!BlobUrlHasRef(url)); 324 DCHECK(false);
143
144 BlobData* blob_data = GetBlobDataFromUrl(src_url);
145 DCHECK(blob_data);
146 if (!blob_data)
147 return; 325 return;
148 326 }
149 blob_map_[url.spec()] = blob_data; 327 ++(found->second.refcount);
150 IncrementBlobDataUsage(blob_data);
151 } 328 }
152 329
153 void BlobStorageController::RemoveBlob(const GURL& url) { 330 void BlobStorageContext::DecrementBlobRefCount(const std::string& uuid) {
154 DCHECK(url.SchemeIs("blob")); 331 BlobMap::iterator found = blob_map_.find(uuid);
155 DCHECK(!BlobUrlHasRef(url)); 332 if (found == blob_map_.end())
156 333 return;
157 if (!RemoveFromMapHelper(&unfinalized_blob_map_, url)) 334 DCHECK_EQ(found->second.data->uuid(), uuid);
158 RemoveFromMapHelper(&blob_map_, url); 335 if (--(found->second.refcount) == 0) {
336 memory_usage_ -= found->second.data->GetMemoryUsage();
337 blob_map_.erase(found);
338 }
159 } 339 }
160 340
161 bool BlobStorageController::RemoveFromMapHelper( 341 void BlobStorageContext::RegisterPublicBlobURL(
162 BlobMap* map, const GURL& url) { 342 const GURL& blob_url, const std::string& uuid) {
163 BlobMap::iterator found = map->find(url.spec()); 343 DCHECK(!BlobUrlHasRef(blob_url));
164 if (found == map->end()) 344 DCHECK(IsInUse(uuid));
165 return false; 345 DCHECK(!IsUrlRegistered(blob_url));
166 if (DecrementBlobDataUsage(found->second)) 346 IncrementBlobRefCount(uuid);
167 memory_usage_ -= found->second->GetMemoryUsage(); 347 public_blob_urls_[blob_url] = uuid;
168 map->erase(found);
169 return true;
170 } 348 }
171 349
172 350 void BlobStorageContext::RevokePublicBlobURL(const GURL& blob_url) {
173 BlobData* BlobStorageController::GetBlobDataFromUrl(const GURL& url) { 351 DCHECK(!BlobUrlHasRef(blob_url));
174 BlobMap::iterator found = blob_map_.find( 352 if (!IsUrlRegistered(blob_url))
175 BlobUrlHasRef(url) ? ClearBlobUrlRef(url).spec() : url.spec()); 353 return;
176 return (found != blob_map_.end()) ? found->second : NULL; 354 DecrementBlobRefCount(public_blob_urls_[blob_url]);
355 public_blob_urls_.erase(blob_url);
177 } 356 }
178 357
179 void BlobStorageController::AppendStorageItems( 358 void BlobStorageContext::AppendStorageItems(
180 BlobData* target_blob_data, BlobData* src_blob_data, 359 BlobData* target_blob_data, BlobData* src_blob_data,
181 uint64 offset, uint64 length) { 360 uint64 offset, uint64 length) {
182 DCHECK(target_blob_data && src_blob_data && 361 DCHECK(target_blob_data && src_blob_data &&
183 length != static_cast<uint64>(-1)); 362 length != static_cast<uint64>(-1));
184 363
185 std::vector<BlobData::Item>::const_iterator iter = 364 std::vector<BlobData::Item>::const_iterator iter =
186 src_blob_data->items().begin(); 365 src_blob_data->items().begin();
187 if (offset) { 366 if (offset) {
188 for (; iter != src_blob_data->items().end(); ++iter) { 367 for (; iter != src_blob_data->items().end(); ++iter) {
189 if (offset >= iter->length()) 368 if (offset >= iter->length())
(...skipping 12 matching lines...) Expand all
202 static_cast<uint32>(new_length)); 381 static_cast<uint32>(new_length));
203 } else if (iter->type() == BlobData::Item::TYPE_FILE) { 382 } else if (iter->type() == BlobData::Item::TYPE_FILE) {
204 AppendFileItem(target_blob_data, 383 AppendFileItem(target_blob_data,
205 iter->path(), 384 iter->path(),
206 iter->offset() + offset, 385 iter->offset() + offset,
207 new_length, 386 new_length,
208 iter->expected_modification_time()); 387 iter->expected_modification_time());
209 } else { 388 } else {
210 DCHECK(iter->type() == BlobData::Item::TYPE_FILE_FILESYSTEM); 389 DCHECK(iter->type() == BlobData::Item::TYPE_FILE_FILESYSTEM);
211 AppendFileSystemFileItem(target_blob_data, 390 AppendFileSystemFileItem(target_blob_data,
212 iter->url(), 391 iter->filesystem_url(),
213 iter->offset() + offset, 392 iter->offset() + offset,
214 new_length, 393 new_length,
215 iter->expected_modification_time()); 394 iter->expected_modification_time());
216 } 395 }
217 length -= new_length; 396 length -= new_length;
218 offset = 0; 397 offset = 0;
219 } 398 }
220 } 399 }
221 400
222 void BlobStorageController::AppendFileItem( 401 void BlobStorageContext::AppendFileItem(
223 BlobData* target_blob_data, 402 BlobData* target_blob_data,
224 const base::FilePath& file_path, uint64 offset, uint64 length, 403 const base::FilePath& file_path, uint64 offset, uint64 length,
225 const base::Time& expected_modification_time) { 404 const base::Time& expected_modification_time) {
226 target_blob_data->AppendFile(file_path, offset, length, 405 target_blob_data->AppendFile(file_path, offset, length,
227 expected_modification_time); 406 expected_modification_time);
228 407
229 // It may be a temporary file that should be deleted when no longer needed. 408 // It may be a temporary file that should be deleted when no longer needed.
230 scoped_refptr<ShareableFileReference> shareable_file = 409 scoped_refptr<ShareableFileReference> shareable_file =
231 ShareableFileReference::Get(file_path); 410 ShareableFileReference::Get(file_path);
232 if (shareable_file) 411 if (shareable_file)
233 target_blob_data->AttachShareableFileReference(shareable_file); 412 target_blob_data->AttachShareableFileReference(shareable_file);
234 } 413 }
235 414
236 void BlobStorageController::AppendFileSystemFileItem( 415 void BlobStorageContext::AppendFileSystemFileItem(
237 BlobData* target_blob_data, 416 BlobData* target_blob_data,
238 const GURL& url, uint64 offset, uint64 length, 417 const GURL& filesystem_url, uint64 offset, uint64 length,
239 const base::Time& expected_modification_time) { 418 const base::Time& expected_modification_time) {
240 target_blob_data->AppendFileSystemFile(url, offset, length, 419 target_blob_data->AppendFileSystemFile(filesystem_url, offset, length,
241 expected_modification_time); 420 expected_modification_time);
242 } 421 }
243 422
244 void BlobStorageController::IncrementBlobDataUsage(BlobData* blob_data) { 423 bool BlobStorageContext::IsInUse(const std::string& uuid) {
245 blob_data_usage_count_[blob_data] += 1; 424 return blob_map_.find(uuid) != blob_map_.end();
246 } 425 }
247 426
248 bool BlobStorageController::DecrementBlobDataUsage(BlobData* blob_data) { 427 bool BlobStorageContext::HasUseCountOfOne(const std::string& uuid) {
249 BlobDataUsageMap::iterator found = blob_data_usage_count_.find(blob_data); 428 return IsInUse(uuid) && (blob_map_[uuid].refcount == 1);
250 DCHECK(found != blob_data_usage_count_.end()); 429 }
251 if (--(found->second)) 430
252 return false; // Still in use 431 bool BlobStorageContext::IsUrlRegistered(const GURL& blob_url) {
253 blob_data_usage_count_.erase(found); 432 return public_blob_urls_.find(blob_url) != public_blob_urls_.end();
254 return true;
255 } 433 }
256 434
257 } // namespace webkit_blob 435 } // namespace webkit_blob
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698