summaryrefslogtreecommitdiff
path: root/chromium/content/browser/indexed_db/indexed_db_pre_close_task_queue.h
blob: 7e2aa847c55d2416118574d921a9a48de15116c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// Copyright 2017 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.

#ifndef CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_PRE_CLOSE_TASK_QUEUE_H_
#define CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_PRE_CLOSE_TASK_QUEUE_H_

#include <list>
#include <memory>
#include <vector>

#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "content/common/indexed_db/indexed_db_metadata.h"
#include "third_party/leveldatabase/src/include/leveldb/status.h"

namespace content {

// Holds a queue of PreCloseTask's to be run after an IndexedDBBackingStore no
// longer has any connections.
//
// There is a special IndexedDBMetadata fetcher task that runs beofre all the
// other tasks, and whose output is passed to each task before they start.
//
// Owned by IndexedDBBackingStore.
class CONTENT_EXPORT IndexedDBPreCloseTaskQueue {
 public:
  enum class StopReason {
    // A new connection was made to the closing backing store.
    NEW_CONNECTION,
    // The maximum time for all tasks to complete as passed.
    TIMEOUT,
    // There was an error reading the database metadata.
    METADATA_ERROR,
  };

  // Defines a task that will be run after closing an IndexedDB backing store
  // instance. The task can be destructed at any time if the browser process is
  // shutting down, otherwise Stop(...) will be called.
  // Instances of this class are sequence-hostile. Each instance must only be
  // used on the same SequencedTaskRunner.
  class CONTENT_EXPORT PreCloseTask {
   public:
    virtual ~PreCloseTask();

    // Called before RunRound. |metadata| is guaranteed to outlive this task.
    virtual void SetMetadata(
        std::vector<IndexedDBDatabaseMetadata> const* metadata) = 0;

    // Tells the task to stop before completion. It will be destroyed after this
    // call. Can be called at any time.
    virtual void Stop(StopReason reason) = 0;

    // Runs a round of work. Tasks are expected to keep round execution time
    // small. Returns if the task is complete and can be destroyed.
    virtual bool RunRound() = 0;
  };

  // |on_complete| must not contain a refptr to the IndexedDBBackingStore, as
  // this would create a cycle.
  IndexedDBPreCloseTaskQueue(std::list<std::unique_ptr<PreCloseTask>> tasks,
                             base::OnceClosure on_complete,
                             base::TimeDelta max_run_time,
                             std::unique_ptr<base::OneShotTimer> timer);
  ~IndexedDBPreCloseTaskQueue();

  bool started() const { return started_; }

  // Tasks are all complete or they have been stopped.
  bool done() const { return done_; }

  // Stops all tasks and destroys them. The |on_complete| callback will be
  // immediately called.
  void StopForNewConnection();

  // Starts running tasks. Can only be called once.
  void Start(base::OnceCallback<leveldb::Status(
                 std::vector<IndexedDBDatabaseMetadata>*)> metadata_fetcher);

 private:
  void OnComplete();

  void StopForTimout();
  void StopForMetadataError(const leveldb::Status& status);

  void RunLoop();

  std::vector<IndexedDBDatabaseMetadata> metadata_;

  bool started_ = false;
  bool done_ = false;
  std::list<std::unique_ptr<PreCloseTask>> tasks_;
  base::OnceClosure on_done_;

  base::TimeDelta timeout_time_;
  std::unique_ptr<base::OneShotTimer> timeout_timer_;
  scoped_refptr<base::SequencedTaskRunner> task_runner_;

  base::WeakPtrFactory<IndexedDBPreCloseTaskQueue> ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(IndexedDBPreCloseTaskQueue);
};

}  // namespace content

#endif  // CONTENT_BROWSER_INDEXED_DB_INDEXED_DB_PRE_CLOSE_TASK_QUEUE_H_