OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/shareable_file_reference.h" | 5 #include "webkit/blob/shareable_file_reference.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 | 8 |
9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
10 #include "base/files/file_util_proxy.h" | 10 #include "base/files/file_util_proxy.h" |
11 #include "base/lazy_instance.h" | 11 #include "base/lazy_instance.h" |
12 #include "base/task_runner.h" | 12 #include "base/task_runner.h" |
13 #include "base/threading/thread_checker.h" | 13 #include "base/threading/thread_checker.h" |
14 | 14 |
15 namespace webkit_blob { | 15 namespace webkit_blob { |
16 | 16 |
17 namespace { | 17 namespace { |
18 | 18 |
19 // A shareable file map with enforcement of thread checker. | 19 // A shareable file map with enforcement of thread checker. |
20 // This map may get deleted on a different thread in AtExitManager at the | 20 // This map may get deleted on a different thread in AtExitManager at the |
21 // very end on the main thread (at the point all other threads must be | 21 // very end on the main thread (at the point all other threads must be |
22 // terminated), so we use ThreadChecker rather than NonThreadSafe and do not | 22 // terminated), so we use ThreadChecker rather than NonThreadSafe and do not |
23 // check thread in the dtor. | 23 // check thread in the dtor. |
24 class ShareableFileMap { | 24 class ShareableFileMap { |
25 public: | 25 public: |
26 typedef std::map<FilePath, ShareableFileReference*> FileMap; | 26 typedef std::map<base::FilePath, ShareableFileReference*> FileMap; |
27 typedef FileMap::iterator iterator; | 27 typedef FileMap::iterator iterator; |
28 typedef FileMap::key_type key_type; | 28 typedef FileMap::key_type key_type; |
29 typedef FileMap::value_type value_type; | 29 typedef FileMap::value_type value_type; |
30 | 30 |
31 ShareableFileMap() {} | 31 ShareableFileMap() {} |
32 | 32 |
33 iterator Find(key_type key) { | 33 iterator Find(key_type key) { |
34 DCHECK(CalledOnValidThread()); | 34 DCHECK(CalledOnValidThread()); |
35 return file_map_.find(key); | 35 return file_map_.find(key); |
36 } | 36 } |
(...skipping 22 matching lines...) Expand all Loading... |
59 base::ThreadChecker thread_checker_; | 59 base::ThreadChecker thread_checker_; |
60 DISALLOW_COPY_AND_ASSIGN(ShareableFileMap); | 60 DISALLOW_COPY_AND_ASSIGN(ShareableFileMap); |
61 }; | 61 }; |
62 | 62 |
63 base::LazyInstance<ShareableFileMap> g_file_map = LAZY_INSTANCE_INITIALIZER; | 63 base::LazyInstance<ShareableFileMap> g_file_map = LAZY_INSTANCE_INITIALIZER; |
64 | 64 |
65 } // namespace | 65 } // namespace |
66 | 66 |
67 // static | 67 // static |
68 scoped_refptr<ShareableFileReference> ShareableFileReference::Get( | 68 scoped_refptr<ShareableFileReference> ShareableFileReference::Get( |
69 const FilePath& path) { | 69 const base::FilePath& path) { |
70 ShareableFileMap::iterator found = g_file_map.Get().Find(path); | 70 ShareableFileMap::iterator found = g_file_map.Get().Find(path); |
71 ShareableFileReference* reference = | 71 ShareableFileReference* reference = |
72 (found == g_file_map.Get().End()) ? NULL : found->second; | 72 (found == g_file_map.Get().End()) ? NULL : found->second; |
73 return scoped_refptr<ShareableFileReference>(reference); | 73 return scoped_refptr<ShareableFileReference>(reference); |
74 } | 74 } |
75 | 75 |
76 // static | 76 // static |
77 scoped_refptr<ShareableFileReference> ShareableFileReference::GetOrCreate( | 77 scoped_refptr<ShareableFileReference> ShareableFileReference::GetOrCreate( |
78 const FilePath& path, FinalReleasePolicy policy, | 78 const base::FilePath& path, FinalReleasePolicy policy, |
79 base::TaskRunner* file_task_runner) { | 79 base::TaskRunner* file_task_runner) { |
80 DCHECK(file_task_runner); | 80 DCHECK(file_task_runner); |
81 typedef std::pair<ShareableFileMap::iterator, bool> InsertResult; | 81 typedef std::pair<ShareableFileMap::iterator, bool> InsertResult; |
82 | 82 |
83 // Required for VS2010: http://connect.microsoft.com/VisualStudio/feedback/det
ails/520043/error-converting-from-null-to-a-pointer-type-in-std-pair | 83 // Required for VS2010: http://connect.microsoft.com/VisualStudio/feedback/det
ails/520043/error-converting-from-null-to-a-pointer-type-in-std-pair |
84 webkit_blob::ShareableFileReference* null_reference = NULL; | 84 webkit_blob::ShareableFileReference* null_reference = NULL; |
85 InsertResult result = g_file_map.Get().Insert( | 85 InsertResult result = g_file_map.Get().Insert( |
86 ShareableFileMap::value_type(path, null_reference)); | 86 ShareableFileMap::value_type(path, null_reference)); |
87 if (result.second == false) | 87 if (result.second == false) |
88 return scoped_refptr<ShareableFileReference>(result.first->second); | 88 return scoped_refptr<ShareableFileReference>(result.first->second); |
89 | 89 |
90 // Wasn't in the map, create a new reference and store the pointer. | 90 // Wasn't in the map, create a new reference and store the pointer. |
91 scoped_refptr<ShareableFileReference> reference( | 91 scoped_refptr<ShareableFileReference> reference( |
92 new ShareableFileReference(path, policy, file_task_runner)); | 92 new ShareableFileReference(path, policy, file_task_runner)); |
93 result.first->second = reference.get(); | 93 result.first->second = reference.get(); |
94 return reference; | 94 return reference; |
95 } | 95 } |
96 | 96 |
97 void ShareableFileReference::AddFinalReleaseCallback( | 97 void ShareableFileReference::AddFinalReleaseCallback( |
98 const FinalReleaseCallback& callback) { | 98 const FinalReleaseCallback& callback) { |
99 DCHECK(g_file_map.Get().CalledOnValidThread()); | 99 DCHECK(g_file_map.Get().CalledOnValidThread()); |
100 final_release_callbacks_.push_back(callback); | 100 final_release_callbacks_.push_back(callback); |
101 } | 101 } |
102 | 102 |
103 ShareableFileReference::ShareableFileReference( | 103 ShareableFileReference::ShareableFileReference( |
104 const FilePath& path, FinalReleasePolicy policy, | 104 const base::FilePath& path, FinalReleasePolicy policy, |
105 base::TaskRunner* file_task_runner) | 105 base::TaskRunner* file_task_runner) |
106 : path_(path), | 106 : path_(path), |
107 final_release_policy_(policy), | 107 final_release_policy_(policy), |
108 file_task_runner_(file_task_runner) { | 108 file_task_runner_(file_task_runner) { |
109 DCHECK(g_file_map.Get().Find(path_)->second == NULL); | 109 DCHECK(g_file_map.Get().Find(path_)->second == NULL); |
110 } | 110 } |
111 | 111 |
112 ShareableFileReference::~ShareableFileReference() { | 112 ShareableFileReference::~ShareableFileReference() { |
113 DCHECK(g_file_map.Get().Find(path_)->second == this); | 113 DCHECK(g_file_map.Get().Find(path_)->second == this); |
114 g_file_map.Get().Erase(path_); | 114 g_file_map.Get().Erase(path_); |
115 | 115 |
116 for (size_t i = 0; i < final_release_callbacks_.size(); i++) | 116 for (size_t i = 0; i < final_release_callbacks_.size(); i++) |
117 final_release_callbacks_[i].Run(path_); | 117 final_release_callbacks_[i].Run(path_); |
118 | 118 |
119 if (final_release_policy_ == DELETE_ON_FINAL_RELEASE) { | 119 if (final_release_policy_ == DELETE_ON_FINAL_RELEASE) { |
120 base::FileUtilProxy::Delete(file_task_runner_, path_, false /* recursive */, | 120 base::FileUtilProxy::Delete(file_task_runner_, path_, false /* recursive */, |
121 base::FileUtilProxy::StatusCallback()); | 121 base::FileUtilProxy::StatusCallback()); |
122 } | 122 } |
123 } | 123 } |
124 | 124 |
125 } // namespace webkit_blob | 125 } // namespace webkit_blob |
OLD | NEW |