// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/nacl/browser/pnacl_host.h"

#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/debug/leak_annotations.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/numerics/safe_math.h"
#include "base/task_scheduler/post_task.h"
#include "components/nacl/browser/nacl_browser.h"
#include "components/nacl/browser/pnacl_translation_cache.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"

using content::BrowserThread;

namespace {

static const base::FilePath::CharType kTranslationCacheDirectoryName[] =
    FILE_PATH_LITERAL("PnaclTranslationCache");
// Delay to wait for initialization of the cache backend
static const int kTranslationCacheInitializationDelayMs = 20;

void CloseBaseFile(base::File file) {
  base::PostTaskWithTraits(
      FROM_HERE,
      {base::MayBlock(), base::TaskPriority::BACKGROUND,
       base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
      base::Bind([](base::File file) {}, Passed(std::move(file))));
}

}  // namespace

namespace pnacl {

class FileProxy {
 public:
  FileProxy(std::unique_ptr<base::File> file, PnaclHost* host);
  int Write(scoped_refptr<net::DrainableIOBuffer> buffer);
  void WriteDone(const PnaclHost::TranslationID& id, int result);

 private:
  std::unique_ptr<base::File> file_;
  PnaclHost* host_;
};

FileProxy::FileProxy(std::unique_ptr<base::File> file, PnaclHost* host)
    : file_(std::move(file)), host_(host) {}

int FileProxy::Write(scoped_refptr<net::DrainableIOBuffer> buffer) {
  int rv = file_->Write(0, buffer->data(), buffer->size());
  if (rv == -1)
    PLOG(ERROR) << "FileProxy::Write error";
  return rv;
}

void FileProxy::WriteDone(const PnaclHost::TranslationID& id, int result) {
  host_->OnBufferCopiedToTempFile(id, std::move(file_), result);
}

PnaclHost::PnaclHost() = default;

PnaclHost* PnaclHost::GetInstance() {
  static PnaclHost* instance = nullptr;
  if (!instance) {
    instance = new PnaclHost;
    ANNOTATE_LEAKING_OBJECT_PTR(instance);
  }
  return instance;
}

PnaclHost::PendingTranslation::PendingTranslation()
    : process_handle(base::kNullProcessHandle),
      render_view_id(0),
      nexe_fd(NULL),
      got_nexe_fd(false),
      got_cache_reply(false),
      got_cache_hit(false),
      is_incognito(false),
      callback(NexeFdCallback()),
      cache_info(nacl::PnaclCacheInfo()) {
}

PnaclHost::PendingTranslation::PendingTranslation(
    const PendingTranslation& other) = default;

PnaclHost::PendingTranslation::~PendingTranslation() {
  if (nexe_fd)
    delete nexe_fd;
}

bool PnaclHost::TranslationMayBeCached(
    const PendingTranslationMap::iterator& entry) {
  return !entry->second.is_incognito &&
         !entry->second.cache_info.has_no_store_header;
}

/////////////////////////////////////// Initialization

static base::FilePath GetCachePath() {
  NaClBrowserDelegate* browser_delegate = nacl::NaClBrowser::GetDelegate();
  // Determine where the translation cache resides in the file system.  It
  // exists in Chrome's cache directory and is not tied to any specific
  // profile. If we fail, return an empty path.
  // Start by finding the user data directory.
  base::FilePath user_data_dir;
  if (!browser_delegate ||
      !browser_delegate->GetUserDirectory(&user_data_dir)) {
    return base::FilePath();
  }
  // The cache directory may or may not be the user data directory.
  base::FilePath cache_file_path;
  browser_delegate->GetCacheDirectory(&cache_file_path);

  // Append the base file name to the cache directory.
  return cache_file_path.Append(kTranslationCacheDirectoryName);
}

void PnaclHost::OnCacheInitialized(int net_error) {
  DCHECK(thread_checker_.CalledOnValidThread());
  // If the cache was cleared before the load completed, ignore.
  if (cache_state_ == CacheReady)
    return;
  if (net_error != net::OK) {
    // This will cause the cache to attempt to re-init on the next call to
    // GetNexeFd.
    cache_state_ = CacheUninitialized;
  } else {
    cache_state_ = CacheReady;
  }
}

void PnaclHost::Init() {
  // Extra check that we're on the real IO thread since this version of
  // Init isn't used in unit tests.
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  DCHECK(thread_checker_.CalledOnValidThread());
  base::FilePath cache_path(GetCachePath());
  if (cache_path.empty() || cache_state_ != CacheUninitialized)
    return;
  disk_cache_.reset(new PnaclTranslationCache());
  cache_state_ = CacheInitializing;
  int rv = disk_cache_->InitOnDisk(
      cache_path,
      base::Bind(&PnaclHost::OnCacheInitialized, base::Unretained(this)));
  if (rv != net::ERR_IO_PENDING)
    OnCacheInitialized(rv);
}

// Initialize for testing, optionally using the in-memory backend, and manually
// setting the temporary file directory instead of using the system directory.
void PnaclHost::InitForTest(base::FilePath temp_dir, bool in_memory) {
  DCHECK(thread_checker_.CalledOnValidThread());
  disk_cache_.reset(new PnaclTranslationCache());
  cache_state_ = CacheInitializing;
  temp_dir_ = temp_dir;
  int rv;
  if (in_memory) {
    rv = disk_cache_->InitInMemory(
        base::Bind(&PnaclHost::OnCacheInitialized, base::Unretained(this)));
  } else {
    rv = disk_cache_->InitOnDisk(
        temp_dir,
        base::Bind(&PnaclHost::OnCacheInitialized, base::Unretained(this)));
  }
  if (rv != net::ERR_IO_PENDING)
    OnCacheInitialized(rv);
}

///////////////////////////////////////// Temp files

// Create a temporary file on |file_task_runner_|.
// static
void PnaclHost::DoCreateTemporaryFile(base::FilePath temp_dir,
                                      TempFileCallback cb) {
  base::FilePath file_path;
  base::File file;
  bool rv = temp_dir.empty()
                ? base::CreateTemporaryFile(&file_path)
                : base::CreateTemporaryFileInDir(temp_dir, &file_path);
  if (!rv) {
    PLOG(ERROR) << "Temp file creation failed.";
  } else {
    file.Initialize(
        file_path,
        base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_READ |
            base::File::FLAG_WRITE | base::File::FLAG_TEMPORARY |
            base::File::FLAG_DELETE_ON_CLOSE);

    if (!file.IsValid())
      PLOG(ERROR) << "Temp file open failed: " << file.error_details();
  }
  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
                          base::Bind(cb, Passed(std::move(file))));
}

void PnaclHost::CreateTemporaryFile(TempFileCallback cb) {
  if (!file_task_runner_->PostTask(
          FROM_HERE,
          base::Bind(&PnaclHost::DoCreateTemporaryFile, temp_dir_, cb))) {
    DCHECK(thread_checker_.CalledOnValidThread());
    cb.Run(base::File());
  }
}

///////////////////////////////////////// GetNexeFd implementation
////////////////////// Common steps

void PnaclHost::GetNexeFd(int render_process_id,
                          int render_view_id,
                          int pp_instance,
                          bool is_incognito,
                          const nacl::PnaclCacheInfo& cache_info,
                          const NexeFdCallback& cb) {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (cache_state_ == CacheUninitialized) {
    Init();
  }
  if (cache_state_ != CacheReady) {
    // If the backend hasn't yet initialized, try the request again later.
    BrowserThread::PostDelayedTask(BrowserThread::IO,
                                   FROM_HERE,
                                   base::Bind(&PnaclHost::GetNexeFd,
                                              base::Unretained(this),
                                              render_process_id,
                                              render_view_id,
                                              pp_instance,
                                              is_incognito,
                                              cache_info,
                                              cb),
                                   base::TimeDelta::FromMilliseconds(
                                       kTranslationCacheInitializationDelayMs));
    return;
  }

  TranslationID id(render_process_id, pp_instance);
  PendingTranslationMap::iterator entry = pending_translations_.find(id);
  if (entry != pending_translations_.end()) {
    // Existing translation must have been abandonded. Clean it up.
    LOG(ERROR) << "GetNexeFd for already-pending translation";
    pending_translations_.erase(entry);
  }

  std::string cache_key(disk_cache_->GetKey(cache_info));
  if (cache_key.empty()) {
    LOG(ERROR) << "GetNexeFd: Invalid cache info";
    cb.Run(base::File(), false);
    return;
  }

  PendingTranslation pt;
  pt.render_view_id = render_view_id;
  pt.callback = cb;
  pt.cache_info = cache_info;
  pt.cache_key = cache_key;
  pt.is_incognito = is_incognito;
  pending_translations_[id] = pt;
  SendCacheQueryAndTempFileRequest(cache_key, id);
}

// Dispatch the cache read request and the temp file creation request
// simultaneously; currently we need a temp file regardless of whether the
// request hits.
void PnaclHost::SendCacheQueryAndTempFileRequest(const std::string& cache_key,
                                                 const TranslationID& id) {
  DCHECK(thread_checker_.CalledOnValidThread());
  pending_backend_operations_++;
  disk_cache_->GetNexe(cache_key, base::Bind(&PnaclHost::OnCacheQueryReturn,
                                             base::Unretained(this), id));

  CreateTemporaryFile(
      base::Bind(&PnaclHost::OnTempFileReturn, base::Unretained(this), id));
}

// Callback from the translation cache query. |id| is bound from
// SendCacheQueryAndTempFileRequest, |net_error| is a net::Error code (which for
// our purposes means a hit if it's net::OK (i.e. 0). |buffer| is allocated
// by PnaclTranslationCache and now belongs to PnaclHost.
// (Bound callbacks must re-lookup the TranslationID because the translation
// could be cancelled before they get called).
void PnaclHost::OnCacheQueryReturn(
    const TranslationID& id,
    int net_error,
    scoped_refptr<net::DrainableIOBuffer> buffer) {
  DCHECK(thread_checker_.CalledOnValidThread());
  pending_backend_operations_--;
  PendingTranslationMap::iterator entry(pending_translations_.find(id));
  if (entry == pending_translations_.end()) {
    LOG(ERROR) << "OnCacheQueryReturn: id not found";
    DeInitIfSafe();
    return;
  }
  PendingTranslation* pt = &entry->second;
  pt->got_cache_reply = true;
  pt->got_cache_hit = (net_error == net::OK);
  if (pt->got_cache_hit)
    pt->nexe_read_buffer = buffer;
  CheckCacheQueryReady(entry);
}

// Callback from temp file creation. |id| is bound from
// SendCacheQueryAndTempFileRequest, and |file| is the created file.
// If there was an error, file is invalid.
// (Bound callbacks must re-lookup the TranslationID because the translation
// could be cancelled before they get called).
void PnaclHost::OnTempFileReturn(const TranslationID& id,
                                 base::File file) {
  DCHECK(thread_checker_.CalledOnValidThread());
  PendingTranslationMap::iterator entry(pending_translations_.find(id));
  if (entry == pending_translations_.end()) {
    // The renderer may have signaled an error or closed while the temp
    // file was being created.
    LOG(ERROR) << "OnTempFileReturn: id not found";
    CloseBaseFile(std::move(file));
    return;
  }
  if (!file.IsValid()) {
    // This translation will fail, but we need to retry any translation
    // waiting for its result.
    LOG(ERROR) << "OnTempFileReturn: temp file creation failed";
    std::string key(entry->second.cache_key);
    entry->second.callback.Run(base::File(), false);
    bool may_be_cached = TranslationMayBeCached(entry);
    pending_translations_.erase(entry);
    // No translations will be waiting for entries that will not be stored.
    if (may_be_cached)
      RequeryMatchingTranslations(key);
    return;
  }
  PendingTranslation* pt = &entry->second;
  pt->got_nexe_fd = true;
  pt->nexe_fd = new base::File(std::move(file));
  CheckCacheQueryReady(entry);
}

// Check whether both the cache query and the temp file have returned, and check
// whether we actually got a hit or not.
void PnaclHost::CheckCacheQueryReady(
    const PendingTranslationMap::iterator& entry) {
  DCHECK(thread_checker_.CalledOnValidThread());
  PendingTranslation* pt = &entry->second;
  if (!(pt->got_cache_reply && pt->got_nexe_fd))
    return;
  if (!pt->got_cache_hit) {
    // Check if there is already a pending translation for this file. If there
    // is, we will wait for it to come back, to avoid redundant translations.
    for (PendingTranslationMap::iterator it = pending_translations_.begin();
         it != pending_translations_.end();
         ++it) {
      // Another translation matches if it's a request for the same file,
      if (it->second.cache_key == entry->second.cache_key &&
          // and it's not this translation,
          it->first != entry->first &&
          // and it can be stored in the cache,
          TranslationMayBeCached(it) &&
          // and it's already gotten past this check and returned the miss.
          it->second.got_cache_reply &&
          it->second.got_nexe_fd) {
        return;
      }
    }
    ReturnMiss(entry);
    return;
  }

  std::unique_ptr<base::File> file(pt->nexe_fd);
  pt->nexe_fd = NULL;
  pt->got_nexe_fd = false;
  FileProxy* proxy(new FileProxy(std::move(file), this));

  base::PostTaskWithTraitsAndReplyWithResult(
      FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND},
      base::Bind(&FileProxy::Write, base::Unretained(proxy),
                 pt->nexe_read_buffer),
      base::Bind(&FileProxy::WriteDone, base::Owned(proxy), entry->first));
}

//////////////////// GetNexeFd miss path
// Return the temp fd to the renderer, reporting a miss.
void PnaclHost::ReturnMiss(const PendingTranslationMap::iterator& entry) {
  // Return the fd
  PendingTranslation* pt = &entry->second;
  NexeFdCallback cb(pt->callback);
  cb.Run(*pt->nexe_fd, false);
  if (!pt->nexe_fd->IsValid()) {
    // Bad FD is unrecoverable, so clear out the entry.
    pending_translations_.erase(entry);
  }
}

// On error, just return a null refptr.
// static
scoped_refptr<net::DrainableIOBuffer> PnaclHost::CopyFileToBuffer(
    std::unique_ptr<base::File> file) {
  scoped_refptr<net::DrainableIOBuffer> buffer;

  // TODO(eroman): Maximum size should be changed to size_t once that is
  // what IOBuffer requires. crbug.com/488553. Also I don't think the
  // max size should be inclusive here...
  int64_t file_size = file->GetLength();
  if (file_size < 0 || file_size > std::numeric_limits<int>::max()) {
    PLOG(ERROR) << "Get file length failed " << file_size;
    return buffer;
  }

  buffer = new net::DrainableIOBuffer(
      new net::IOBuffer(base::checked_cast<size_t>(file_size)),
      base::checked_cast<size_t>(file_size));
  if (file->Read(0, buffer->data(), buffer->size()) != file_size) {
    PLOG(ERROR) << "CopyFileToBuffer file read failed";
    buffer = nullptr;
  }
  return buffer;
}

// Called by the renderer in the miss path to report a finished translation
void PnaclHost::TranslationFinished(int render_process_id,
                                    int pp_instance,
                                    bool success) {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (cache_state_ != CacheReady)
    return;
  TranslationID id(render_process_id, pp_instance);
  PendingTranslationMap::iterator entry(pending_translations_.find(id));
  if (entry == pending_translations_.end()) {
    LOG(ERROR) << "TranslationFinished: TranslationID " << render_process_id
               << "," << pp_instance << " not found.";
    return;
  }
  bool store_nexe = true;
  // If this is a premature response (i.e. we haven't returned a temp file
  // yet) or if it's an unsuccessful translation, or if we are incognito,
  // don't store in the cache.
  // TODO(dschuff): use a separate in-memory cache for incognito
  // translations.
  if (!entry->second.got_nexe_fd || !entry->second.got_cache_reply ||
      !success || !TranslationMayBeCached(entry)) {
    store_nexe = false;
  } else {
    std::unique_ptr<base::File> file(entry->second.nexe_fd);
    entry->second.nexe_fd = NULL;
    entry->second.got_nexe_fd = false;

    base::PostTaskWithTraitsAndReplyWithResult(
        FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND},
        base::Bind(&PnaclHost::CopyFileToBuffer, Passed(&file)),
        base::Bind(&PnaclHost::StoreTranslatedNexe, base::Unretained(this),
                   id));
  }

  if (!store_nexe) {
    // If store_nexe is true, the fd will be closed by CopyFileToBuffer.
    if (entry->second.got_nexe_fd) {
      std::unique_ptr<base::File> file(entry->second.nexe_fd);
      entry->second.nexe_fd = NULL;
      CloseBaseFile(std::move(*file.get()));
    }
    pending_translations_.erase(entry);
  }
}

// Store the translated nexe in the translation cache. Called back with the
// TranslationID from the host and the result of CopyFileToBuffer.
// (Bound callbacks must re-lookup the TranslationID because the translation
// could be cancelled before they get called).
void PnaclHost::StoreTranslatedNexe(
    TranslationID id,
    scoped_refptr<net::DrainableIOBuffer> buffer) {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (cache_state_ != CacheReady)
    return;
  PendingTranslationMap::iterator it(pending_translations_.find(id));
  if (it == pending_translations_.end()) {
    LOG(ERROR) << "StoreTranslatedNexe: TranslationID " << id.first << ","
               << id.second << " not found.";
    return;
  }

  if (buffer.get() == NULL) {
    LOG(ERROR) << "Error reading translated nexe";
    return;
  }
  pending_backend_operations_++;
  disk_cache_->StoreNexe(it->second.cache_key, buffer.get(),
                         base::Bind(&PnaclHost::OnTranslatedNexeStored,
                                    base::Unretained(this), it->first));
}

// After we know the nexe has been stored, we can clean up, and unblock any
// outstanding requests for the same file.
// (Bound callbacks must re-lookup the TranslationID because the translation
// could be cancelled before they get called).
void PnaclHost::OnTranslatedNexeStored(const TranslationID& id, int net_error) {
  PendingTranslationMap::iterator entry(pending_translations_.find(id));
  pending_backend_operations_--;
  if (entry == pending_translations_.end()) {
    // If the renderer closed while we were storing the nexe, we land here.
    // Make sure we try to de-init.
    DeInitIfSafe();
    return;
  }
  std::string key(entry->second.cache_key);
  pending_translations_.erase(entry);
  RequeryMatchingTranslations(key);
}

// Check if any pending translations match |key|. If so, re-issue the cache
// query. In the overlapped miss case, we expect a hit this time, but a miss
// is also possible in case of an error.
void PnaclHost::RequeryMatchingTranslations(const std::string& key) {
  DCHECK(thread_checker_.CalledOnValidThread());
  // Check for outstanding misses to this same file
  for (PendingTranslationMap::iterator it = pending_translations_.begin();
       it != pending_translations_.end();
       ++it) {
    if (it->second.cache_key == key) {
      // Re-send the cache read request. This time we expect a hit, but if
      // something goes wrong, it will just handle it like a miss.
      it->second.got_cache_reply = false;
      pending_backend_operations_++;
      disk_cache_->GetNexe(key, base::Bind(&PnaclHost::OnCacheQueryReturn,
                                           base::Unretained(this), it->first));
    }
  }
}

//////////////////// GetNexeFd hit path

void PnaclHost::OnBufferCopiedToTempFile(const TranslationID& id,
                                         std::unique_ptr<base::File> file,
                                         int file_error) {
  DCHECK(thread_checker_.CalledOnValidThread());
  PendingTranslationMap::iterator entry(pending_translations_.find(id));
  if (entry == pending_translations_.end()) {
    CloseBaseFile(std::move(*file.get()));
    return;
  }
  if (file_error == -1) {
    // Write error on the temp file. Request a new file and start over.
    CloseBaseFile(std::move(*file.get()));
    CreateTemporaryFile(base::Bind(&PnaclHost::OnTempFileReturn,
                                   base::Unretained(this), entry->first));
    return;
  }
  entry->second.callback.Run(*file.get(), true);
  CloseBaseFile(std::move(*file.get()));
  pending_translations_.erase(entry);
}

///////////////////

void PnaclHost::RendererClosing(int render_process_id) {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (cache_state_ != CacheReady)
    return;
  for (PendingTranslationMap::iterator it = pending_translations_.begin();
       it != pending_translations_.end();) {
    PendingTranslationMap::iterator to_erase(it++);
    if (to_erase->first.first == render_process_id) {
      // Clean up the open files.
      std::unique_ptr<base::File> file(to_erase->second.nexe_fd);
      to_erase->second.nexe_fd = NULL;
      CloseBaseFile(std::move(*file.get()));
      std::string key(to_erase->second.cache_key);
      bool may_be_cached = TranslationMayBeCached(to_erase);
      pending_translations_.erase(to_erase);
      // No translations will be waiting for entries that will not be stored.
      if (may_be_cached)
        RequeryMatchingTranslations(key);
    }
  }
  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      base::Bind(&PnaclHost::DeInitIfSafe, base::Unretained(this)));
}

////////////////// Cache data removal
void PnaclHost::ClearTranslationCacheEntriesBetween(
    base::Time initial_time,
    base::Time end_time,
    const base::Closure& callback) {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (cache_state_ == CacheUninitialized) {
    Init();
  }
  if (cache_state_ == CacheInitializing) {
    // If the backend hasn't yet initialized, try the request again later.
    BrowserThread::PostDelayedTask(
        BrowserThread::IO, FROM_HERE,
        base::Bind(&PnaclHost::ClearTranslationCacheEntriesBetween,
                   base::Unretained(this), initial_time, end_time, callback),
        base::TimeDelta::FromMilliseconds(
            kTranslationCacheInitializationDelayMs));
    return;
  }
  pending_backend_operations_++;
  int rv = disk_cache_->DoomEntriesBetween(
      initial_time, end_time, base::Bind(&PnaclHost::OnEntriesDoomed,
                                         base::Unretained(this), callback));
  if (rv != net::ERR_IO_PENDING)
    OnEntriesDoomed(callback, rv);
}

void PnaclHost::OnEntriesDoomed(const base::Closure& callback, int net_error) {
  DCHECK(thread_checker_.CalledOnValidThread());
  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, callback);
  pending_backend_operations_--;
  // When clearing the cache, the UI is blocked on all the cache-clearing
  // operations, and freeing the backend actually blocks the IO thread. So
  // instead of calling DeInitIfSafe directly, post it for later.
  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      base::Bind(&PnaclHost::DeInitIfSafe, base::Unretained(this)));
}

// Destroying the cache backend causes it to post tasks to the cache thread to
// flush to disk. PnaclHost is leaked on shutdown because registering it as a
// Singleton with AtExitManager would result in it not being destroyed until all
// the browser threads have gone away and it's too late to post anything
// (attempting to do so hangs shutdown) at that point anyways.  So we make sure
// to destroy it when we no longer have any outstanding operations that need it.
// These include pending translations, cache clear requests, and requests to
// read or write translated nexes.  We check when renderers close, when cache
// clear requests finish, and when backend operations complete.

// It is not safe to delete the backend while it is initializing, nor if it has
// outstanding entry open requests; it is in theory safe to delete it with
// outstanding read/write requests, but because that distinction is hidden
// inside PnaclTranslationCache, we do not delete the backend if there are any
// backend requests in flight.  As a last resort in the destructor, we just leak
// the backend to avoid hanging shutdown.
void PnaclHost::DeInitIfSafe() {
  DCHECK(pending_backend_operations_ >= 0);
  if (pending_translations_.empty() &&
      pending_backend_operations_ <= 0 &&
      cache_state_ == CacheReady) {
    cache_state_ = CacheUninitialized;
    disk_cache_.reset();
  }
}

}  // namespace pnacl
