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

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 // base::SysInfo::AmountOfPhysicalMemoryMB()
ericu 2013/04/18 02:01:58 What does this comment mean? Is this a TODO?
michaeln 2013/04/19 21:55:51 it is a todo, related to that bug you're cc'd on,
36 static const int64 kMaxMemoryUsage = 500 * 1024 * 1024; // Half a gig.
ericu 2013/04/18 02:01:58 How'd you pick this number? I see it used to be t
32 37
33 } // namespace 38 } // namespace
34 39
35 BlobStorageController::BlobStorageController() 40 //-----------------------------------------------------------------------
41 // BlobDataHandle
42 //-----------------------------------------------------------------------
43
44 BlobDataHandle::BlobDataHandle(BlobData* blob_data, BlobStorageContext* context,
45 base::SequencedTaskRunner* task_runner)
46 : blob_data_(blob_data),
47 context_(new base::WeakPtr<BlobStorageContext>(context->AsWeakPtr())),
48 io_task_runner_(task_runner) {
49 // Ensures the uuid remains registered and the underlying data is not deleted.
50 context_->get()->IncrementBlobRefCount(blob_data->uuid());
51 }
52
53 BlobDataHandle::~BlobDataHandle() {
ericu 2013/04/18 02:01:58 There's no need to call the PostTask either if !co
michaeln 2013/04/19 21:55:51 i gotta look more closely, are weakptrs threadsafe
ericu 2013/04/22 17:25:14 Ah, I was assuming that they were; I could be comp
michaeln 2013/04/23 21:11:11 weakptrs may be deleted on the 'wrong thread', but
54 if (io_task_runner_->RunsTasksOnCurrentThread()) {
55 if (context_->get())
56 context_->get()->DecrementBlobRefCount(blob_data_->uuid());
57 return;
58 }
59 io_task_runner_->PostTask(
60 FROM_HERE,
61 base::Bind(&DeleteHelper, base::Passed(&context_), blob_data_));
michaeln 2013/04/18 20:45:15 blob_data_ is not being handled correctly here sin
62 }
63
64 BlobData* BlobDataHandle::data() const {
65 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
66 return blob_data_.get();
67 }
68
69 // static
70 void BlobDataHandle::DeleteHelper(
71 scoped_ptr<base::WeakPtr<BlobStorageContext> > context,
72 scoped_refptr<BlobData> blob_data) {
73 if (context->get())
74 context->get()->DecrementBlobRefCount(blob_data->uuid());
75 }
76
77 //-----------------------------------------------------------------------
78 // BlobStorageHost
79 //-----------------------------------------------------------------------
80
81 // TODO(michaeln): I need to tighten this up, some assertions and better
82 // map usage (aka use ->find more). Do something reasonable given bad inputs
83 // like addref'ing an id that does not exist.
84
85 BlobStorageHost::BlobStorageHost(BlobStorageContext* context)
86 : context_(context->AsWeakPtr()) {
87 }
88
89 BlobStorageHost::~BlobStorageHost() {
90 if (!context_)
91 return;
92 for (BlobReferenceMap::iterator iter = blobs_inuse_map_.begin();
93 iter != blobs_inuse_map_.end(); ++iter) {
94 for (int i = 0; i < iter->second; ++i)
95 context_->DecrementBlobRefCount(iter->first);
96 }
97
98 for (std::set<GURL>::iterator iter = public_blob_urls_.begin();
99 iter != public_blob_urls_.end(); ++iter) {
100 context_->RevokePublicBlobURL(*iter);
101 }
ericu 2013/04/18 02:01:58 Stylistically, I'd probably revoke the public URL
michaeln 2013/04/19 21:55:51 Done.
102 }
103
104 void BlobStorageHost::StartBuildingBlob(const std::string& uuid) {
105 if (!context_)
106 return;
107 DCHECK(blobs_inuse_map_.find(uuid) == blobs_inuse_map_.end());
108 blobs_inuse_map_[uuid] = 1;
109 context_->StartBuildingBlob(uuid);
110 }
111
112 void BlobStorageHost::AppendBlobDataItem(
113 const std::string& uuid, const BlobData::Item& data_item) {
114 if (!context_)
115 return;
116 DCHECK_EQ(blobs_inuse_map_[uuid], 1);
ericu 2013/04/18 02:01:58 How about a TODO for something harsher here [and p
michaeln 2013/04/19 21:55:51 i'll just make these changes now and put the retur
117 context_->AppendBlobDataItem(uuid, data_item);
118 }
119
120 void BlobStorageHost::CancelBuildingBlob(const std::string& uuid) {
121 if (!context_)
122 return;
123 DCHECK_EQ(blobs_inuse_map_[uuid], 1);
124 blobs_inuse_map_.erase(uuid);
125 context_->CancelBuildingBlob(uuid);
126 }
127
128 void BlobStorageHost::FinishBuildingBlob(
129 const std::string& uuid, const std::string& content_type) {
130 if (!context_)
131 return;
132 DCHECK_EQ(blobs_inuse_map_[uuid], 1);
133 context_->FinishBuildingBlob(uuid, content_type);
134 }
135
136 void BlobStorageHost::AddFinishedBlob(const BlobData* blob_data) {
ericu 2013/04/18 02:01:58 This function stands out as different. Where is i
michaeln 2013/04/19 21:55:51 this one is different, it's not in direct support
137 if (!context_)
138 return;
139 DCHECK(blobs_inuse_map_.find(blob_data->uuid()) == blobs_inuse_map_.end());
140 blobs_inuse_map_[blob_data->uuid()] = 1;
141 context_->AddFinishedBlob(blob_data);
142 }
143
144 void BlobStorageHost::IncrementBlobRefCount(const std::string& uuid) {
145 if (!context_)
146 return;
147 blobs_inuse_map_[uuid] += 1;
148 context_->IncrementBlobRefCount(uuid);
149 }
150
151 void BlobStorageHost::DecrementBlobRefCount(const std::string& uuid) {
152 if (!context_)
153 return;
154 DCHECK_GT(blobs_inuse_map_[uuid], 0);
155 blobs_inuse_map_[uuid] -= 1;
156 if (blobs_inuse_map_[uuid] == 0)
157 blobs_inuse_map_.erase(uuid);
158 context_->DecrementBlobRefCount(uuid);
159 }
160
161 void BlobStorageHost::RegisterPublicBlobURL(
162 const GURL& blob_url, const std::string& uuid) {
163 if (!context_)
164 return;
165 DCHECK_GT(blobs_inuse_map_[uuid], 0);
166 public_blob_urls_.insert(blob_url);
167 context_->RegisterPublicBlobURL(blob_url, uuid);
168 }
169
170 void BlobStorageHost::RevokePublicBlobURL(const GURL& blob_url) {
171 if (!context_)
172 return;
173 public_blob_urls_.erase(blob_url);
174 context_->RevokePublicBlobURL(blob_url);
175 }
176
177 //-----------------------------------------------------------------------
178 // BlobStorageContext
179 //-----------------------------------------------------------------------
180
181 BlobStorageContext::BlobStorageContext()
36 : memory_usage_(0) { 182 : memory_usage_(0) {
37 } 183 }
38 184
39 BlobStorageController::~BlobStorageController() { 185 BlobStorageContext::~BlobStorageContext() {
40 } 186 }
41 187
42 void BlobStorageController::StartBuildingBlob(const GURL& url) { 188 scoped_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromUUID(
43 DCHECK(url.SchemeIs("blob")); 189 const std::string& uuid) {
44 DCHECK(!BlobUrlHasRef(url)); 190 scoped_ptr<BlobDataHandle> result;
45 BlobData* blob_data = new BlobData; 191 BlobMap::iterator found = blob_map_.find(uuid);
46 unfinalized_blob_map_[url.spec()] = blob_data; 192 if (found == blob_map_.end())
47 IncrementBlobDataUsage(blob_data); 193 return result.Pass();
194 result.reset(new BlobDataHandle(found->second.second, this,
195 base::MessageLoopProxy::current()));
196 return result.Pass();
48 } 197 }
49 198
50 void BlobStorageController::AppendBlobDataItem( 199 scoped_ptr<BlobDataHandle> BlobStorageContext::GetBlobDataFromPublicURL(
51 const GURL& url, const BlobData::Item& item) { 200 const GURL& url) {
52 DCHECK(url.SchemeIs("blob")); 201 BlobURLMap::iterator found = public_blob_urls_.find(
53 DCHECK(!BlobUrlHasRef(url)); 202 BlobUrlHasRef(url) ? ClearBlobUrlRef(url) : url);
54 BlobMap::iterator found = unfinalized_blob_map_.find(url.spec()); 203 if (found == public_blob_urls_.end())
204 return scoped_ptr<BlobDataHandle>();
205 return GetBlobDataFromUUID(found->second);
206 }
207
208 void BlobStorageContext::StartBuildingBlob(const std::string& uuid) {
209 DCHECK(unfinalized_blob_map_.find(uuid) == unfinalized_blob_map_.end());
ericu 2013/04/18 02:01:58 This one definitely needs something stronger than
ericu 2013/04/24 23:54:43 Still there.
michaeln 2013/04/25 01:21:37 See the Host class where renderer inputs are exami
210 unfinalized_blob_map_[uuid] = std::make_pair(1 , new BlobData(uuid));
211 }
212
213 void BlobStorageContext::AppendBlobDataItem(
214 const std::string& uuid, const BlobData::Item& item) {
215 BlobMap::iterator found = unfinalized_blob_map_.find(uuid);
55 if (found == unfinalized_blob_map_.end()) 216 if (found == unfinalized_blob_map_.end())
56 return; 217 return;
57 BlobData* target_blob_data = found->second; 218 BlobData* target_blob_data = found->second.second;
58 DCHECK(target_blob_data); 219 DCHECK(target_blob_data);
59 220
60 memory_usage_ -= target_blob_data->GetMemoryUsage(); 221 memory_usage_ -= target_blob_data->GetMemoryUsage();
61 222
62 // The blob data is stored in the "canonical" way. That is, it only contains a 223 // The blob data is stored in the "canonical" way. That is, it only contains a
63 // list of Data and File items. 224 // list of Data and File items.
64 // 1) The Data item is denoted by the raw data and the range. 225 // 1) The Data item is denoted by the raw data and the range.
ericu 2013/04/18 02:01:58 I see no range for the TYPE_BYTES.
michaeln 2013/04/19 21:55:51 i'll look more closely at these comments? the code
michaeln 2013/04/25 00:08:00 Changed the comment to read... // The blob data
65 // 2) The File item is denoted by the file path, the range and the expected 226 // 2) The File item is denoted by the file path, the range and the expected
66 // modification time. 227 // modification time.
67 // 3) The FileSystem File item is denoted by the FileSystem URL, the range 228 // 3) The FileSystem File item is denoted by the FileSystem URL, the range
68 // and the expected modification time. 229 // and the expected modification time.
69 // All the Blob items in the passing blob data are resolved and expanded into 230 // All the Blob items in the passing blob data are resolved and expanded into
ericu 2013/04/18 02:01:58 What is "the passing blob data"?
70 // a set of Data and File items. 231 // a set of Data, File, and FileSystemFile items.
71 232
72 DCHECK(item.length() > 0); 233 DCHECK(item.length() > 0);
73 switch (item.type()) { 234 switch (item.type()) {
74 case BlobData::Item::TYPE_BYTES: 235 case BlobData::Item::TYPE_BYTES:
75 DCHECK(!item.offset()); 236 DCHECK(!item.offset());
76 target_blob_data->AppendData(item.bytes(), item.length()); 237 target_blob_data->AppendData(item.bytes(), item.length());
77 break; 238 break;
78 case BlobData::Item::TYPE_FILE: 239 case BlobData::Item::TYPE_FILE:
79 AppendFileItem(target_blob_data, 240 AppendFileItem(target_blob_data,
80 item.path(), 241 item.path(),
81 item.offset(), 242 item.offset(),
82 item.length(), 243 item.length(),
83 item.expected_modification_time()); 244 item.expected_modification_time());
84 break; 245 break;
85 case BlobData::Item::TYPE_FILE_FILESYSTEM: 246 case BlobData::Item::TYPE_FILE_FILESYSTEM:
86 AppendFileSystemFileItem(target_blob_data, 247 AppendFileSystemFileItem(target_blob_data,
87 item.url(), 248 item.filesystem_url(),
88 item.offset(), 249 item.offset(),
89 item.length(), 250 item.length(),
90 item.expected_modification_time()); 251 item.expected_modification_time());
91 break; 252 break;
92 case BlobData::Item::TYPE_BLOB: { 253 case BlobData::Item::TYPE_BLOB: {
ericu 2013/04/18 02:01:58 If we always convert BlobData::Items to lowest for
michaeln 2013/04/23 21:15:10 we'll get here by way of script... var compoundBl
ericu 2013/04/24 23:54:43 Thx.
93 BlobData* src_blob_data = GetBlobDataFromUrl(item.url()); 254 scoped_ptr<BlobDataHandle> src = GetBlobDataFromUUID(item.blob_uuid());
94 DCHECK(src_blob_data); 255 DCHECK(src.get());
95 if (src_blob_data) 256 if (src.get())
96 AppendStorageItems(target_blob_data, 257 AppendStorageItems(target_blob_data,
97 src_blob_data, 258 src->data(),
98 item.offset(), 259 item.offset(),
99 item.length()); 260 item.length());
100 break; 261 break;
101 } 262 }
102 default: 263 default:
103 NOTREACHED(); 264 NOTREACHED();
104 break; 265 break;
105 } 266 }
106 267
107 memory_usage_ += target_blob_data->GetMemoryUsage(); 268 memory_usage_ += target_blob_data->GetMemoryUsage();
108 269
109 // If we're using too much memory, drop this blob. 270 // If we're using too much memory, drop this blob.
110 // TODO(michaeln): Blob memory storage does not yet spill over to disk, 271 // 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. 272 // until it does, we'll prevent memory usage over a max amount.
ericu 2013/04/18 02:01:58 We don't really prevent it--we just prevent it fro
michaeln 2013/04/19 21:55:51 good point, i can test above instead of after the
michaeln 2013/04/25 01:05:01 Done.
112 if (memory_usage_ > kMaxMemoryUsage) 273 if (memory_usage_ > kMaxMemoryUsage) {
113 RemoveBlob(url); 274 DCHECK_EQ(1, found->second.first);
275 memory_usage_ -= target_blob_data->GetMemoryUsage();
276 unfinalized_blob_map_.erase(found);
277 }
114 } 278 }
115 279
116 void BlobStorageController::FinishBuildingBlob( 280 void BlobStorageContext::FinishBuildingBlob(
117 const GURL& url, const std::string& content_type) { 281 const std::string& uuid, const std::string& content_type) {
118 DCHECK(url.SchemeIs("blob")); 282 BlobMap::iterator found = unfinalized_blob_map_.find(uuid);
119 DCHECK(!BlobUrlHasRef(url)); 283 if (found == unfinalized_blob_map_.end()) {
120 BlobMap::iterator found = unfinalized_blob_map_.find(url.spec()); 284 DCHECK(false);
121 if (found == unfinalized_blob_map_.end())
122 return; 285 return;
123 found->second->set_content_type(content_type); 286 }
124 blob_map_[url.spec()] = found->second; 287 found->second.second->set_content_type(content_type);
288 blob_map_[uuid] = std::make_pair(1, found->second.second);
125 unfinalized_blob_map_.erase(found); 289 unfinalized_blob_map_.erase(found);
126 } 290 }
127 291
128 void BlobStorageController::AddFinishedBlob(const GURL& url, 292 void BlobStorageContext::CancelBuildingBlob(const std::string& uuid) {
129 const BlobData* data) { 293 DCHECK(unfinalized_blob_map_.find(uuid) != unfinalized_blob_map_.end());
ericu 2013/04/18 02:01:58 Also too dangerous for just DCHECK.
130 StartBuildingBlob(url); 294 DecrementBlobRefCountHelper(&unfinalized_blob_map_, uuid);
295 DCHECK(unfinalized_blob_map_.find(uuid) == unfinalized_blob_map_.end());
296 }
297
298 void BlobStorageContext::AddFinishedBlob(const BlobData* data) {
299 StartBuildingBlob(data->uuid());
131 for (std::vector<BlobData::Item>::const_iterator iter = 300 for (std::vector<BlobData::Item>::const_iterator iter =
132 data->items().begin(); 301 data->items().begin();
133 iter != data->items().end(); ++iter) { 302 iter != data->items().end(); ++iter) {
134 AppendBlobDataItem(url, *iter); 303 AppendBlobDataItem(data->uuid(), *iter);
135 } 304 }
136 FinishBuildingBlob(url, data->content_type()); 305 FinishBuildingBlob(data->uuid(), data->content_type());
137 } 306 }
138 307
139 void BlobStorageController::CloneBlob( 308 void BlobStorageContext::IncrementBlobRefCount(const std::string& uuid) {
140 const GURL& url, const GURL& src_url) { 309 BlobMap::iterator found = blob_map_.find(uuid);
141 DCHECK(url.SchemeIs("blob")); 310 if (found == blob_map_.end()) {
142 DCHECK(!BlobUrlHasRef(url)); 311 DCHECK(false);
143
144 BlobData* blob_data = GetBlobDataFromUrl(src_url);
145 DCHECK(blob_data);
146 if (!blob_data)
147 return; 312 return;
148 313 }
149 blob_map_[url.spec()] = blob_data; 314 ++(found->second.first);
150 IncrementBlobDataUsage(blob_data);
151 } 315 }
152 316
153 void BlobStorageController::RemoveBlob(const GURL& url) { 317 void BlobStorageContext::DecrementBlobRefCount(const std::string& uuid) {
154 DCHECK(url.SchemeIs("blob")); 318 if (!DecrementBlobRefCountHelper(&unfinalized_blob_map_, uuid))
155 DCHECK(!BlobUrlHasRef(url)); 319 DecrementBlobRefCountHelper(&blob_map_, uuid);
156
157 if (!RemoveFromMapHelper(&unfinalized_blob_map_, url))
158 RemoveFromMapHelper(&blob_map_, url);
159 } 320 }
160 321
161 bool BlobStorageController::RemoveFromMapHelper( 322 bool BlobStorageContext::DecrementBlobRefCountHelper(
162 BlobMap* map, const GURL& url) { 323 BlobMap* map, const std::string& uuid) {
163 BlobMap::iterator found = map->find(url.spec()); 324 BlobMap::iterator found = map->find(uuid);
164 if (found == map->end()) 325 if (found == map->end())
165 return false; 326 return false;
166 if (DecrementBlobDataUsage(found->second)) 327 if (--(found->second.first) == 0) {
167 memory_usage_ -= found->second->GetMemoryUsage(); 328 DCHECK_EQ(found->second.second->uuid(), uuid);
ericu 2013/04/18 02:01:58 This DCHECK_EQ could be hoisted to line 327.
michaeln 2013/04/19 21:55:51 Done.
168 map->erase(found); 329 memory_usage_ -= found->second.second->GetMemoryUsage();
330 map->erase(found);
331 }
169 return true; 332 return true;
170 } 333 }
171 334
172 335 void BlobStorageContext::RegisterPublicBlobURL(
173 BlobData* BlobStorageController::GetBlobDataFromUrl(const GURL& url) { 336 const GURL& blob_url, const std::string& uuid) {
174 BlobMap::iterator found = blob_map_.find( 337 DCHECK(!BlobUrlHasRef(blob_url));
175 BlobUrlHasRef(url) ? ClearBlobUrlRef(url).spec() : url.spec()); 338 IncrementBlobRefCount(uuid);
176 return (found != blob_map_.end()) ? found->second : NULL; 339 public_blob_urls_[blob_url] = uuid;
ericu 2013/04/18 02:01:58 What if this URL is already in the map?
michaeln 2013/04/19 21:55:51 yup... another of those 'what you talkin about wil
177 } 340 }
178 341
179 void BlobStorageController::AppendStorageItems( 342 void BlobStorageContext::RevokePublicBlobURL(const GURL& blob_url) {
343 DCHECK(!BlobUrlHasRef(blob_url));
344 DecrementBlobRefCount(public_blob_urls_[blob_url]);
345 public_blob_urls_.erase(blob_url);
346 }
347
348 void BlobStorageContext::AppendStorageItems(
180 BlobData* target_blob_data, BlobData* src_blob_data, 349 BlobData* target_blob_data, BlobData* src_blob_data,
181 uint64 offset, uint64 length) { 350 uint64 offset, uint64 length) {
182 DCHECK(target_blob_data && src_blob_data && 351 DCHECK(target_blob_data && src_blob_data &&
183 length != static_cast<uint64>(-1)); 352 length != static_cast<uint64>(-1));
184 353
185 std::vector<BlobData::Item>::const_iterator iter = 354 std::vector<BlobData::Item>::const_iterator iter =
186 src_blob_data->items().begin(); 355 src_blob_data->items().begin();
187 if (offset) { 356 if (offset) {
188 for (; iter != src_blob_data->items().end(); ++iter) { 357 for (; iter != src_blob_data->items().end(); ++iter) {
189 if (offset >= iter->length()) 358 if (offset >= iter->length())
(...skipping 12 matching lines...) Expand all
202 static_cast<uint32>(new_length)); 371 static_cast<uint32>(new_length));
203 } else if (iter->type() == BlobData::Item::TYPE_FILE) { 372 } else if (iter->type() == BlobData::Item::TYPE_FILE) {
204 AppendFileItem(target_blob_data, 373 AppendFileItem(target_blob_data,
205 iter->path(), 374 iter->path(),
206 iter->offset() + offset, 375 iter->offset() + offset,
207 new_length, 376 new_length,
208 iter->expected_modification_time()); 377 iter->expected_modification_time());
209 } else { 378 } else {
210 DCHECK(iter->type() == BlobData::Item::TYPE_FILE_FILESYSTEM); 379 DCHECK(iter->type() == BlobData::Item::TYPE_FILE_FILESYSTEM);
211 AppendFileSystemFileItem(target_blob_data, 380 AppendFileSystemFileItem(target_blob_data,
212 iter->url(), 381 iter->filesystem_url(),
213 iter->offset() + offset, 382 iter->offset() + offset,
214 new_length, 383 new_length,
215 iter->expected_modification_time()); 384 iter->expected_modification_time());
216 } 385 }
217 length -= new_length; 386 length -= new_length;
218 offset = 0; 387 offset = 0;
219 } 388 }
220 } 389 }
221 390
222 void BlobStorageController::AppendFileItem( 391 void BlobStorageContext::AppendFileItem(
223 BlobData* target_blob_data, 392 BlobData* target_blob_data,
224 const base::FilePath& file_path, uint64 offset, uint64 length, 393 const base::FilePath& file_path, uint64 offset, uint64 length,
225 const base::Time& expected_modification_time) { 394 const base::Time& expected_modification_time) {
226 target_blob_data->AppendFile(file_path, offset, length, 395 target_blob_data->AppendFile(file_path, offset, length,
227 expected_modification_time); 396 expected_modification_time);
228 397
229 // It may be a temporary file that should be deleted when no longer needed. 398 // It may be a temporary file that should be deleted when no longer needed.
230 scoped_refptr<ShareableFileReference> shareable_file = 399 scoped_refptr<ShareableFileReference> shareable_file =
231 ShareableFileReference::Get(file_path); 400 ShareableFileReference::Get(file_path);
232 if (shareable_file) 401 if (shareable_file)
233 target_blob_data->AttachShareableFileReference(shareable_file); 402 target_blob_data->AttachShareableFileReference(shareable_file);
234 } 403 }
235 404
236 void BlobStorageController::AppendFileSystemFileItem( 405 void BlobStorageContext::AppendFileSystemFileItem(
237 BlobData* target_blob_data, 406 BlobData* target_blob_data,
238 const GURL& url, uint64 offset, uint64 length, 407 const GURL& filesystem_url, uint64 offset, uint64 length,
239 const base::Time& expected_modification_time) { 408 const base::Time& expected_modification_time) {
240 target_blob_data->AppendFileSystemFile(url, offset, length, 409 target_blob_data->AppendFileSystemFile(filesystem_url, offset, length,
241 expected_modification_time); 410 expected_modification_time);
242 } 411 }
243 412
244 void BlobStorageController::IncrementBlobDataUsage(BlobData* blob_data) {
245 blob_data_usage_count_[blob_data] += 1;
246 }
247
248 bool BlobStorageController::DecrementBlobDataUsage(BlobData* blob_data) {
249 BlobDataUsageMap::iterator found = blob_data_usage_count_.find(blob_data);
250 DCHECK(found != blob_data_usage_count_.end());
251 if (--(found->second))
252 return false; // Still in use
253 blob_data_usage_count_.erase(found);
254 return true;
255 }
256
257 } // namespace webkit_blob 413 } // namespace webkit_blob
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698