Fixing crash when DRIVER_INFO_6::pszMfgName is NULL
[chromium-blink-merge.git] / net / disk_cache / tracing_cache_backend.cc
blob4966133f00db9073a40db40b8ff6f7fdbabdeef4
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
3 // found in the LICENSE file.
5 #include "net/disk_cache/tracing_cache_backend.h"
7 #include "net/base/net_errors.h"
9 namespace disk_cache {
11 // Proxies entry objects created by the real underlying backend. Backend users
12 // will only see the proxy entries. It is necessary for recording the backend
13 // operations since often non-trivial work is invoked directly on entries.
14 class EntryProxy : public Entry, public base::RefCountedThreadSafe<EntryProxy> {
15 public:
16 EntryProxy(Entry *entry, TracingCacheBackend* backend);
17 virtual void Doom() OVERRIDE;
18 virtual void Close() OVERRIDE;
19 virtual std::string GetKey() const OVERRIDE;
20 virtual base::Time GetLastUsed() const OVERRIDE;
21 virtual base::Time GetLastModified() const OVERRIDE;
22 virtual int32 GetDataSize(int index) const OVERRIDE;
23 virtual int ReadData(int index, int offset, IOBuffer* buf, int buf_len,
24 const CompletionCallback& callback) OVERRIDE;
25 virtual int WriteData(int index, int offset, IOBuffer* buf, int buf_len,
26 const CompletionCallback& callback,
27 bool truncate) OVERRIDE;
28 virtual int ReadSparseData(int64 offset, IOBuffer* buf, int buf_len,
29 const CompletionCallback& callback) OVERRIDE;
30 virtual int WriteSparseData(int64 offset, IOBuffer* buf, int buf_len,
31 const CompletionCallback& callback) OVERRIDE;
32 virtual int GetAvailableRange(int64 offset, int len, int64* start,
33 const CompletionCallback& callback) OVERRIDE;
34 virtual bool CouldBeSparse() const OVERRIDE;
35 virtual void CancelSparseIO() OVERRIDE;
36 virtual int ReadyForSparseIO(const CompletionCallback& callback) OVERRIDE;
38 private:
39 friend class base::RefCountedThreadSafe<EntryProxy>;
40 typedef TracingCacheBackend::Operation Operation;
41 virtual ~EntryProxy();
43 struct RwOpExtra {
44 int index;
45 int offset;
46 int buf_len;
47 bool truncate;
50 void RecordEvent(base::TimeTicks start_time, Operation op, RwOpExtra extra,
51 int result_to_record);
52 void EntryOpComplete(base::TimeTicks start_time, Operation op,
53 RwOpExtra extra, const CompletionCallback& cb,
54 int result);
55 Entry* entry_;
56 base::WeakPtr<TracingCacheBackend> backend_;
58 DISALLOW_COPY_AND_ASSIGN(EntryProxy);
61 EntryProxy::EntryProxy(Entry *entry, TracingCacheBackend* backend)
62 : entry_(entry),
63 backend_(backend->AsWeakPtr()) {
66 void EntryProxy::Doom() {
67 // TODO(pasko): Record the event.
68 entry_->Doom();
71 void EntryProxy::Close() {
72 // TODO(pasko): Record the event.
73 entry_->Close();
74 Release();
77 std::string EntryProxy::GetKey() const {
78 return entry_->GetKey();
81 base::Time EntryProxy::GetLastUsed() const {
82 return entry_->GetLastUsed();
85 base::Time EntryProxy::GetLastModified() const {
86 return entry_->GetLastModified();
89 int32 EntryProxy::GetDataSize(int index) const {
90 return entry_->GetDataSize(index);
93 int EntryProxy::ReadData(int index, int offset, IOBuffer* buf, int buf_len,
94 const CompletionCallback& callback) {
95 base::TimeTicks start_time = base::TimeTicks::Now();
96 RwOpExtra extra;
97 extra.index = index;
98 extra.offset = offset;
99 extra.buf_len = buf_len;
100 extra.truncate = false;
101 int rv = entry_->ReadData(
102 index, offset, buf, buf_len,
103 base::Bind(&EntryProxy::EntryOpComplete, this, start_time,
104 TracingCacheBackend::OP_READ, extra, callback));
105 if (rv != net::ERR_IO_PENDING) {
106 RecordEvent(start_time, TracingCacheBackend::OP_READ, extra, rv);
108 return rv;
111 int EntryProxy::WriteData(int index, int offset, IOBuffer* buf, int buf_len,
112 const CompletionCallback& callback,
113 bool truncate) {
114 base::TimeTicks start_time = base::TimeTicks::Now();
115 RwOpExtra extra;
116 extra.index = index;
117 extra.offset = offset;
118 extra.buf_len = buf_len;
119 extra.truncate = truncate;
120 int rv = entry_->WriteData(index, offset, buf, buf_len,
121 base::Bind(&EntryProxy::EntryOpComplete, this, start_time,
122 TracingCacheBackend::OP_WRITE, extra, callback),
123 truncate);
124 if (rv != net::ERR_IO_PENDING) {
125 RecordEvent(start_time, TracingCacheBackend::OP_WRITE, extra, rv);
127 return rv;
130 int EntryProxy::ReadSparseData(int64 offset, IOBuffer* buf, int buf_len,
131 const CompletionCallback& callback) {
132 // TODO(pasko): Record the event.
133 return entry_->ReadSparseData(offset, buf, buf_len, callback);
136 int EntryProxy::WriteSparseData(int64 offset, IOBuffer* buf, int buf_len,
137 const CompletionCallback& callback) {
138 // TODO(pasko): Record the event.
139 return entry_->WriteSparseData(offset, buf, buf_len, callback);
142 int EntryProxy::GetAvailableRange(int64 offset, int len, int64* start,
143 const CompletionCallback& callback) {
144 return entry_->GetAvailableRange(offset, len, start, callback);
147 bool EntryProxy::CouldBeSparse() const {
148 return entry_->CouldBeSparse();
151 void EntryProxy::CancelSparseIO() {
152 return entry_->CancelSparseIO();
155 int EntryProxy::ReadyForSparseIO(const CompletionCallback& callback) {
156 return entry_->ReadyForSparseIO(callback);
159 void EntryProxy::RecordEvent(base::TimeTicks start_time, Operation op,
160 RwOpExtra extra, int result_to_record) {
161 // TODO(pasko): Implement.
164 void EntryProxy::EntryOpComplete(base::TimeTicks start_time, Operation op,
165 RwOpExtra extra, const CompletionCallback& cb,
166 int result) {
167 RecordEvent(start_time, op, extra, result);
168 if (!cb.is_null()) {
169 cb.Run(result);
173 EntryProxy::~EntryProxy() {
174 if (backend_.get()) {
175 backend_->OnDeleteEntry(entry_);
179 TracingCacheBackend::TracingCacheBackend(scoped_ptr<Backend> backend)
180 : backend_(backend.Pass()) {
183 TracingCacheBackend::~TracingCacheBackend() {
186 net::CacheType TracingCacheBackend::GetCacheType() const {
187 return backend_->GetCacheType();
190 int32 TracingCacheBackend::GetEntryCount() const {
191 return backend_->GetEntryCount();
194 void TracingCacheBackend::RecordEvent(base::TimeTicks start_time, Operation op,
195 std::string key, Entry* entry, int rv) {
196 // TODO(pasko): Implement.
199 EntryProxy* TracingCacheBackend::FindOrCreateEntryProxy(Entry* entry) {
200 EntryProxy* entry_proxy;
201 EntryToProxyMap::iterator it = open_entries_.find(entry);
202 if (it != open_entries_.end()) {
203 entry_proxy = it->second;
204 entry_proxy->AddRef();
205 return entry_proxy;
207 entry_proxy = new EntryProxy(entry, this);
208 entry_proxy->AddRef();
209 open_entries_[entry] = entry_proxy;
210 return entry_proxy;
213 void TracingCacheBackend::OnDeleteEntry(Entry* entry) {
214 EntryToProxyMap::iterator it = open_entries_.find(entry);
215 if (it != open_entries_.end()) {
216 open_entries_.erase(it);
220 void TracingCacheBackend::BackendOpComplete(base::TimeTicks start_time,
221 Operation op,
222 std::string key,
223 Entry** entry,
224 const CompletionCallback& callback,
225 int result) {
226 RecordEvent(start_time, op, key, *entry, result);
227 if (*entry) {
228 *entry = FindOrCreateEntryProxy(*entry);
230 if (!callback.is_null()) {
231 callback.Run(result);
235 net::CompletionCallback TracingCacheBackend::BindCompletion(
236 Operation op, base::TimeTicks start_time, const std::string& key,
237 Entry **entry, const net::CompletionCallback& cb) {
238 return base::Bind(&TracingCacheBackend::BackendOpComplete,
239 AsWeakPtr(), start_time, op, key, entry, cb);
242 int TracingCacheBackend::OpenEntry(const std::string& key, Entry** entry,
243 const CompletionCallback& callback) {
244 DCHECK(*entry == NULL);
245 base::TimeTicks start_time = base::TimeTicks::Now();
246 int rv = backend_->OpenEntry(key, entry,
247 BindCompletion(OP_OPEN, start_time, key, entry,
248 callback));
249 if (rv != net::ERR_IO_PENDING) {
250 RecordEvent(start_time, OP_OPEN, key, *entry, rv);
251 if (*entry) {
252 *entry = FindOrCreateEntryProxy(*entry);
255 return rv;
258 int TracingCacheBackend::CreateEntry(const std::string& key, Entry** entry,
259 const CompletionCallback& callback) {
260 base::TimeTicks start_time = base::TimeTicks::Now();
261 int rv = backend_->CreateEntry(key, entry,
262 BindCompletion(OP_CREATE, start_time, key,
263 entry, callback));
264 if (rv != net::ERR_IO_PENDING) {
265 RecordEvent(start_time, OP_CREATE, key, *entry, rv);
266 if (*entry) {
267 *entry = FindOrCreateEntryProxy(*entry);
270 return rv;
273 int TracingCacheBackend::DoomEntry(const std::string& key,
274 const CompletionCallback& callback) {
275 base::TimeTicks start_time = base::TimeTicks::Now();
276 int rv = backend_->DoomEntry(key, BindCompletion(OP_DOOM_ENTRY,
277 start_time, key, NULL,
278 callback));
279 if (rv != net::ERR_IO_PENDING) {
280 RecordEvent(start_time, OP_DOOM_ENTRY, key, NULL, rv);
282 return rv;
285 int TracingCacheBackend::DoomAllEntries(const CompletionCallback& callback) {
286 return backend_->DoomAllEntries(callback);
289 int TracingCacheBackend::DoomEntriesBetween(base::Time initial_time,
290 base::Time end_time,
291 const CompletionCallback& cb) {
292 return backend_->DoomEntriesBetween(initial_time, end_time, cb);
295 int TracingCacheBackend::DoomEntriesSince(base::Time initial_time,
296 const CompletionCallback& callback) {
297 return backend_->DoomEntriesSince(initial_time, callback);
300 int TracingCacheBackend::OpenNextEntry(void** iter, Entry** next_entry,
301 const CompletionCallback& callback) {
302 return backend_->OpenNextEntry(iter, next_entry, callback);
305 void TracingCacheBackend::EndEnumeration(void** iter) {
306 return backend_->EndEnumeration(iter);
309 void TracingCacheBackend::GetStats(StatsItems* stats) {
310 return backend_->GetStats(stats);
313 void TracingCacheBackend::OnExternalCacheHit(const std::string& key) {
314 return backend_->OnExternalCacheHit(key);
317 } // namespace disk_cache