• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 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.
4 
5 #ifndef CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_TASK_RUNNER_
6 #define CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_TASK_RUNNER_
7 
8 #include "base/memory/ref_counted.h"
9 #include "base/sequenced_task_runner.h"
10 #include "base/threading/sequenced_worker_pool.h"
11 #include "base/time/time.h"
12 #include "content/common/content_export.h"
13 
14 namespace base {
15 class MessageLoopProxy;
16 }
17 
18 namespace content {
19 
20 // DOMStorage uses two task sequences (primary vs commit) to avoid
21 // primary access from queuing up behind commits to disk.
22 // * Initialization, shutdown, and administrative tasks are performed as
23 //   shutdown-blocking primary sequence tasks.
24 // * Tasks directly related to the javascript'able interface are performed
25 //   as shutdown-blocking primary sequence tasks.
26 //   TODO(michaeln): Skip tasks for reading during shutdown.
27 // * Internal tasks related to committing changes to disk are performed as
28 //   shutdown-blocking commit sequence tasks.
29 class CONTENT_EXPORT DOMStorageTaskRunner
30     : public base::TaskRunner {
31  public:
32   enum SequenceID {
33     PRIMARY_SEQUENCE,
34     COMMIT_SEQUENCE
35   };
36 
37   // The PostTask() and PostDelayedTask() methods defined by TaskRunner
38   // post shutdown-blocking tasks on the primary sequence.
39   virtual bool PostDelayedTask(
40       const tracked_objects::Location& from_here,
41       const base::Closure& task,
42       base::TimeDelta delay) = 0;
43 
44   // Posts a shutdown blocking task to |sequence_id|.
45   virtual bool PostShutdownBlockingTask(
46       const tracked_objects::Location& from_here,
47       SequenceID sequence_id,
48       const base::Closure& task) = 0;
49 
50   // The TaskRunner override returns true if the current thread is running
51   // on the primary sequence.
52   virtual bool RunsTasksOnCurrentThread() const OVERRIDE;
53 
54   // Returns true if the current thread is running on the given |sequence_id|.
55   virtual bool IsRunningOnSequence(SequenceID sequence_id) const = 0;
IsRunningOnPrimarySequence()56   bool IsRunningOnPrimarySequence() const {
57     return IsRunningOnSequence(PRIMARY_SEQUENCE);
58   }
IsRunningOnCommitSequence()59   bool IsRunningOnCommitSequence() const {
60     return IsRunningOnSequence(COMMIT_SEQUENCE);
61   }
62 
63  protected:
~DOMStorageTaskRunner()64   virtual ~DOMStorageTaskRunner() {}
65 };
66 
67 // A derived class used in chromium that utilizes a SequenceWorkerPool
68 // under dom_storage specific SequenceTokens. The |delayed_task_loop|
69 // is used to delay scheduling on the worker pool.
70 class CONTENT_EXPORT DOMStorageWorkerPoolTaskRunner :
71       public DOMStorageTaskRunner {
72  public:
73   DOMStorageWorkerPoolTaskRunner(
74       base::SequencedWorkerPool* sequenced_worker_pool,
75       base::SequencedWorkerPool::SequenceToken primary_sequence_token,
76       base::SequencedWorkerPool::SequenceToken commit_sequence_token,
77       base::MessageLoopProxy* delayed_task_loop);
78 
79   virtual bool PostDelayedTask(
80       const tracked_objects::Location& from_here,
81       const base::Closure& task,
82       base::TimeDelta delay) OVERRIDE;
83 
84   virtual bool PostShutdownBlockingTask(
85       const tracked_objects::Location& from_here,
86       SequenceID sequence_id,
87       const base::Closure& task) OVERRIDE;
88 
89   virtual bool IsRunningOnSequence(SequenceID sequence_id) const OVERRIDE;
90 
91  protected:
92   virtual ~DOMStorageWorkerPoolTaskRunner();
93 
94  private:
95 
96   base::SequencedWorkerPool::SequenceToken IDtoToken(SequenceID id) const;
97 
98   const scoped_refptr<base::MessageLoopProxy> message_loop_;
99   const scoped_refptr<base::SequencedWorkerPool> sequenced_worker_pool_;
100   base::SequencedWorkerPool::SequenceToken primary_sequence_token_;
101   base::SequencedWorkerPool::SequenceToken commit_sequence_token_;
102 };
103 
104 // A derived class used in unit tests that ignores all delays so
105 // we don't block in unit tests waiting for timeouts to expire.
106 // There is no distinction between [non]-shutdown-blocking or
107 // the primary sequence vs the commit sequence in the mock,
108 // all tasks are scheduled on |message_loop| with zero delay.
109 class CONTENT_EXPORT MockDOMStorageTaskRunner :
110       public DOMStorageTaskRunner {
111  public:
112   explicit MockDOMStorageTaskRunner(base::MessageLoopProxy* message_loop);
113 
114   virtual bool PostDelayedTask(
115       const tracked_objects::Location& from_here,
116       const base::Closure& task,
117       base::TimeDelta delay) OVERRIDE;
118 
119   virtual bool PostShutdownBlockingTask(
120       const tracked_objects::Location& from_here,
121       SequenceID sequence_id,
122       const base::Closure& task) OVERRIDE;
123 
124   virtual bool IsRunningOnSequence(SequenceID sequence_id) const OVERRIDE;
125 
126  protected:
127   virtual ~MockDOMStorageTaskRunner();
128 
129  private:
130   const scoped_refptr<base::MessageLoopProxy> message_loop_;
131 };
132 
133 }  // namespace content
134 
135 #endif  // CONTENT_BROWSER_DOM_STORAGE_DOM_STORAGE_TASK_RUNNER_
136