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; 56 bool IsRunningOnPrimarySequence() const { 57 return IsRunningOnSequence(PRIMARY_SEQUENCE); 58 } 59 bool IsRunningOnCommitSequence() const { 60 return IsRunningOnSequence(COMMIT_SEQUENCE); 61 } 62 63 protected: 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