15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/http/disk_cache_based_quic_server_info.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/bind.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/callback.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/logging.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/base/completion_callback.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/base/io_buffer.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/base/net_errors.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/http/http_cache.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/http/http_network_session.h"
15e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "net/quic/quic_server_id.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace net {
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Some APIs inside disk_cache take a handle that the caller must keep alive
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// until the API has finished its asynchronous execution.
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Unfortunately, DiskCacheBasedQuicServerInfo may be deleted before the
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// operation completes causing a use-after-free.
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This data shim struct is meant to provide a location for the disk_cache
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// APIs to write into even if the originating DiskCacheBasedQuicServerInfo
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// object has been deleted.  The lifetime for instances of this struct
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// should be bound to the CompletionCallback that is passed to the disk_cache
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// API.  We do this by binding an instance of this struct to an unused
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// parameter for OnIOComplete() using base::Owned().
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This is a hack. A better fix is to make it so that the disk_cache APIs
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// take a Callback to a mutator for setting the output value rather than
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// writing into a raw handle. Then the caller can just pass in a Callback
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// bound to WeakPtr for itself. This callback would correctly "no-op" itself
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// when the DiskCacheBasedQuicServerInfo object is deleted.
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(ajwong): Change disk_cache's API to return results via Callback.
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct DiskCacheBasedQuicServerInfo::CacheOperationDataShim {
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CacheOperationDataShim() : backend(NULL), entry(NULL) {}
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  disk_cache::Backend* backend;
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  disk_cache::Entry* entry;
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DiskCacheBasedQuicServerInfo::DiskCacheBasedQuicServerInfo(
47e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    const QuicServerId& server_id,
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    HttpCache* http_cache)
49e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    : QuicServerInfo(server_id),
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      data_shim_(new CacheOperationDataShim()),
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      state_(GET_BACKEND),
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ready_(false),
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      found_entry_(false),
54e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      server_id_(server_id),
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      http_cache_(http_cache),
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      backend_(NULL),
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      entry_(NULL),
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      weak_factory_(this) {
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      io_callback_ =
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          base::Bind(&DiskCacheBasedQuicServerInfo::OnIOComplete,
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     weak_factory_.GetWeakPtr(),
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     base::Owned(data_shim_));  // Ownership assigned.
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DiskCacheBasedQuicServerInfo::Start() {
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(CalledOnValidThread());
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK_EQ(GET_BACKEND, state_);
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DoLoop(OK);
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int DiskCacheBasedQuicServerInfo::WaitForDataReady(
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const CompletionCallback& callback) {
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(CalledOnValidThread());
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_NE(GET_BACKEND, state_);
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (ready_)
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return OK;
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!callback.is_null()) {
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // Prevent a new callback for WaitForDataReady overwriting an existing
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // pending callback (|user_callback_|).
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!user_callback_.is_null())
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return ERR_INVALID_ARGUMENT;
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    user_callback_ = callback;
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return ERR_IO_PENDING;
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool DiskCacheBasedQuicServerInfo::IsDataReady() {
9123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return ready_;
9223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
9323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
9423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)bool DiskCacheBasedQuicServerInfo::IsReadyToPersist() {
9523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // The data can be persisted if it has been loaded from the disk cache
9623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // and there are no pending writes.
9723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  return ready_ && new_data_.empty();
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DiskCacheBasedQuicServerInfo::Persist() {
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(CalledOnValidThread());
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_NE(GET_BACKEND, state_);
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(new_data_.empty());
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CHECK(ready_);
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(user_callback_.is_null());
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  new_data_ = Serialize();
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!backend_)
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  state_ = CREATE_OR_OPEN;
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DoLoop(OK);
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)DiskCacheBasedQuicServerInfo::~DiskCacheBasedQuicServerInfo() {
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(user_callback_.is_null());
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (entry_)
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    entry_->Close();
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string DiskCacheBasedQuicServerInfo::key() const {
123e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  return "quicserverinfo:" + server_id_.ToString();
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DiskCacheBasedQuicServerInfo::OnIOComplete(CacheOperationDataShim* unused,
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                int rv) {
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_NE(NONE, state_);
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  rv = DoLoop(rv);
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (rv != ERR_IO_PENDING && !user_callback_.is_null()) {
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CompletionCallback callback = user_callback_;
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    user_callback_.Reset();
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(rv);
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int DiskCacheBasedQuicServerInfo::DoLoop(int rv) {
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  do {
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    switch (state_) {
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case GET_BACKEND:
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        rv = DoGetBackend();
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case GET_BACKEND_COMPLETE:
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        rv = DoGetBackendComplete(rv);
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case OPEN:
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        rv = DoOpen();
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case OPEN_COMPLETE:
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        rv = DoOpenComplete(rv);
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case READ:
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        rv = DoRead();
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case READ_COMPLETE:
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        rv = DoReadComplete(rv);
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case WAIT_FOR_DATA_READY_DONE:
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        rv = DoWaitForDataReadyDone();
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case CREATE_OR_OPEN:
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        rv = DoCreateOrOpen();
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case CREATE_OR_OPEN_COMPLETE:
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        rv = DoCreateOrOpenComplete(rv);
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case WRITE:
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        rv = DoWrite();
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case WRITE_COMPLETE:
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        rv = DoWriteComplete(rv);
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case SET_DONE:
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        rv = DoSetDone();
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      default:
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        rv = OK;
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        NOTREACHED();
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } while (rv != ERR_IO_PENDING && state_ != NONE);
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return rv;
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int DiskCacheBasedQuicServerInfo::DoGetBackendComplete(int rv) {
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (rv == OK) {
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    backend_ = data_shim_->backend;
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    state_ = OPEN;
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    state_ = WAIT_FOR_DATA_READY_DONE;
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return OK;
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int DiskCacheBasedQuicServerInfo::DoOpenComplete(int rv) {
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (rv == OK) {
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    entry_ = data_shim_->entry;
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    state_ = READ;
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    found_entry_ = true;
2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    state_ = WAIT_FOR_DATA_READY_DONE;
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return OK;
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int DiskCacheBasedQuicServerInfo::DoReadComplete(int rv) {
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (rv > 0)
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    data_.assign(read_buffer_->data(), rv);
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  state_ = WAIT_FOR_DATA_READY_DONE;
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return OK;
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int DiskCacheBasedQuicServerInfo::DoWriteComplete(int rv) {
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Keep the entry open for future writes.
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  new_data_.clear();
2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  state_ = NONE;
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return OK;
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int DiskCacheBasedQuicServerInfo::DoCreateOrOpenComplete(int rv) {
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (rv != OK) {
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    state_ = SET_DONE;
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!entry_)
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      entry_ = data_shim_->entry;
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    state_ = WRITE;
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return OK;
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int DiskCacheBasedQuicServerInfo::DoGetBackend() {
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  state_ = GET_BACKEND_COMPLETE;
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return http_cache_->GetBackend(&data_shim_->backend, io_callback_);
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int DiskCacheBasedQuicServerInfo::DoOpen() {
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  state_ = OPEN_COMPLETE;
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return backend_->OpenEntry(key(), &data_shim_->entry, io_callback_);
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int DiskCacheBasedQuicServerInfo::DoRead() {
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int32 size = entry_->GetDataSize(0 /* index */);
2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!size) {
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    state_ = WAIT_FOR_DATA_READY_DONE;
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return OK;
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  read_buffer_ = new IOBuffer(size);
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  state_ = READ_COMPLETE;
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return entry_->ReadData(
2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      0 /* index */, 0 /* offset */, read_buffer_.get(), size, io_callback_);
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int DiskCacheBasedQuicServerInfo::DoWrite() {
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  write_buffer_ = new IOBuffer(new_data_.size());
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  memcpy(write_buffer_->data(), new_data_.data(), new_data_.size());
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  state_ = WRITE_COMPLETE;
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return entry_->WriteData(0 /* index */,
2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           0 /* offset */,
2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           write_buffer_.get(),
2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           new_data_.size(),
2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           io_callback_,
2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           true /* truncate */);
2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int DiskCacheBasedQuicServerInfo::DoCreateOrOpen() {
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  state_ = CREATE_OR_OPEN_COMPLETE;
2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (entry_)
2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return OK;
2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (found_entry_) {
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return backend_->OpenEntry(key(), &data_shim_->entry, io_callback_);
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return backend_->CreateEntry(key(), &data_shim_->entry, io_callback_);
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int DiskCacheBasedQuicServerInfo::DoWaitForDataReadyDone() {
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!ready_);
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  state_ = NONE;
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ready_ = true;
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // We close the entry because, if we shutdown before ::Persist is called,
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // then we might leak a cache reference, which causes a DCHECK on shutdown.
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (entry_)
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    entry_->Close();
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  entry_ = NULL;
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Parse(data_);
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return OK;
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int DiskCacheBasedQuicServerInfo::DoSetDone() {
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (entry_)
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    entry_->Close();
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  entry_ = NULL;
298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  new_data_.clear();
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  state_ = NONE;
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return OK;
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace net
304