Home | History | Annotate | Download | only in dom_storage
      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