| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 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. | |
| 4 | |
| 5 #include "webkit/common/blob/shareable_file_reference.h" | |
| 6 | |
| 7 #include <map> | |
| 8 | |
| 9 #include "base/lazy_instance.h" | |
| 10 #include "base/message_loop/message_loop_proxy.h" | |
| 11 #include "base/task_runner.h" | |
| 12 #include "base/threading/non_thread_safe.h" | |
| 13 | |
| 14 namespace storage { | |
| 15 | |
| 16 namespace { | |
| 17 | |
| 18 // A shareable file map with enforcement of thread checker. | |
| 19 class ShareableFileMap : public base::NonThreadSafe { | |
| 20 public: | |
| 21 typedef std::map<base::FilePath, ShareableFileReference*> FileMap; | |
| 22 typedef FileMap::iterator iterator; | |
| 23 typedef FileMap::key_type key_type; | |
| 24 typedef FileMap::value_type value_type; | |
| 25 | |
| 26 ShareableFileMap() {} | |
| 27 | |
| 28 ~ShareableFileMap() { | |
| 29 DetachFromThread(); | |
| 30 } | |
| 31 | |
| 32 iterator Find(key_type key) { | |
| 33 DCHECK(CalledOnValidThread()); | |
| 34 return file_map_.find(key); | |
| 35 } | |
| 36 | |
| 37 iterator End() { | |
| 38 DCHECK(CalledOnValidThread()); | |
| 39 return file_map_.end(); | |
| 40 } | |
| 41 | |
| 42 std::pair<iterator, bool> Insert(value_type value) { | |
| 43 DCHECK(CalledOnValidThread()); | |
| 44 return file_map_.insert(value); | |
| 45 } | |
| 46 | |
| 47 void Erase(key_type key) { | |
| 48 DCHECK(CalledOnValidThread()); | |
| 49 file_map_.erase(key); | |
| 50 } | |
| 51 | |
| 52 private: | |
| 53 FileMap file_map_; | |
| 54 DISALLOW_COPY_AND_ASSIGN(ShareableFileMap); | |
| 55 }; | |
| 56 | |
| 57 base::LazyInstance<ShareableFileMap> g_file_map = LAZY_INSTANCE_INITIALIZER; | |
| 58 | |
| 59 } // namespace | |
| 60 | |
| 61 // static | |
| 62 scoped_refptr<ShareableFileReference> ShareableFileReference::Get( | |
| 63 const base::FilePath& path) { | |
| 64 ShareableFileMap::iterator found = g_file_map.Get().Find(path); | |
| 65 ShareableFileReference* reference = | |
| 66 (found == g_file_map.Get().End()) ? NULL : found->second; | |
| 67 return scoped_refptr<ShareableFileReference>(reference); | |
| 68 } | |
| 69 | |
| 70 // static | |
| 71 scoped_refptr<ShareableFileReference> ShareableFileReference::GetOrCreate( | |
| 72 const base::FilePath& path, | |
| 73 FinalReleasePolicy policy, | |
| 74 base::TaskRunner* file_task_runner) { | |
| 75 return GetOrCreate( | |
| 76 ScopedFile(path, static_cast<ScopedFile::ScopeOutPolicy>(policy), | |
| 77 file_task_runner)); | |
| 78 } | |
| 79 | |
| 80 // static | |
| 81 scoped_refptr<ShareableFileReference> ShareableFileReference::GetOrCreate( | |
| 82 ScopedFile scoped_file) { | |
| 83 if (scoped_file.path().empty()) | |
| 84 return scoped_refptr<ShareableFileReference>(); | |
| 85 | |
| 86 typedef std::pair<ShareableFileMap::iterator, bool> InsertResult; | |
| 87 // Required for VS2010: http://connect.microsoft.com/VisualStudio/feedback/det
ails/520043/error-converting-from-null-to-a-pointer-type-in-std-pair | |
| 88 storage::ShareableFileReference* null_reference = NULL; | |
| 89 InsertResult result = g_file_map.Get().Insert( | |
| 90 ShareableFileMap::value_type(scoped_file.path(), null_reference)); | |
| 91 if (result.second == false) { | |
| 92 scoped_file.Release(); | |
| 93 return scoped_refptr<ShareableFileReference>(result.first->second); | |
| 94 } | |
| 95 | |
| 96 // Wasn't in the map, create a new reference and store the pointer. | |
| 97 scoped_refptr<ShareableFileReference> reference( | |
| 98 new ShareableFileReference(scoped_file.Pass())); | |
| 99 result.first->second = reference.get(); | |
| 100 return reference; | |
| 101 } | |
| 102 | |
| 103 void ShareableFileReference::AddFinalReleaseCallback( | |
| 104 const FinalReleaseCallback& callback) { | |
| 105 DCHECK(g_file_map.Get().CalledOnValidThread()); | |
| 106 scoped_file_.AddScopeOutCallback(callback, NULL); | |
| 107 } | |
| 108 | |
| 109 ShareableFileReference::ShareableFileReference(ScopedFile scoped_file) | |
| 110 : scoped_file_(scoped_file.Pass()) { | |
| 111 DCHECK(g_file_map.Get().Find(path())->second == NULL); | |
| 112 } | |
| 113 | |
| 114 ShareableFileReference::~ShareableFileReference() { | |
| 115 DCHECK(g_file_map.Get().Find(path())->second == this); | |
| 116 g_file_map.Get().Erase(path()); | |
| 117 } | |
| 118 | |
| 119 } // namespace storage | |
| OLD | NEW |