~alinuxninja/nginx-edge/trunk

« back to all changes in this revision

Viewing changes to debian/modules/ngx_pagespeed/psol/include/third_party/chromium/src/base/sequenced_task_runner.h

  • Committer: Vivian
  • Date: 2015-12-04 18:20:11 UTC
  • Revision ID: git-v1:a36f2bc32e884f7473b3a47040e5411306144d7d
* Do not extract psol.tar.gz

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright (c) 2012 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 BASE_SEQUENCED_TASKRUNNER_H_
6
 
#define BASE_SEQUENCED_TASKRUNNER_H_
7
 
 
8
 
#include "base/base_export.h"
9
 
#include "base/sequenced_task_runner_helpers.h"
10
 
#include "base/task_runner.h"
11
 
 
12
 
namespace base {
13
 
 
14
 
// A SequencedTaskRunner is a subclass of TaskRunner that provides
15
 
// additional guarantees on the order that tasks are started, as well
16
 
// as guarantees on when tasks are in sequence, i.e. one task finishes
17
 
// before the other one starts.
18
 
//
19
 
// Summary
20
 
// -------
21
 
// Non-nested tasks with the same delay will run one by one in FIFO
22
 
// order.
23
 
//
24
 
// Detailed guarantees
25
 
// -------------------
26
 
//
27
 
// SequencedTaskRunner also adds additional methods for posting
28
 
// non-nestable tasks.  In general, an implementation of TaskRunner
29
 
// may expose task-running methods which are themselves callable from
30
 
// within tasks.  A non-nestable task is one that is guaranteed to not
31
 
// be run from within an already-running task.  Conversely, a nestable
32
 
// task (the default) is a task that can be run from within an
33
 
// already-running task.
34
 
//
35
 
// The guarantees of SequencedTaskRunner are as follows:
36
 
//
37
 
//   - Given two tasks T2 and T1, T2 will start after T1 starts if:
38
 
//
39
 
//       * T2 is posted after T1; and
40
 
//       * T2 has equal or higher delay than T1; and
41
 
//       * T2 is non-nestable or T1 is nestable.
42
 
//
43
 
//   - If T2 will start after T1 starts by the above guarantee, then
44
 
//     T2 will start after T1 finishes and is destroyed if:
45
 
//
46
 
//       * T2 is non-nestable, or
47
 
//       * T1 doesn't call any task-running methods.
48
 
//
49
 
//   - If T2 will start after T1 finishes by the above guarantee, then
50
 
//     all memory changes in T1 and T1's destruction will be visible
51
 
//     to T2.
52
 
//
53
 
//   - If T2 runs nested within T1 via a call to the task-running
54
 
//     method M, then all memory changes in T1 up to the call to M
55
 
//     will be visible to T2, and all memory changes in T2 will be
56
 
//     visible to T1 from the return from M.
57
 
//
58
 
// Note that SequencedTaskRunner does not guarantee that tasks are run
59
 
// on a single dedicated thread, although the above guarantees provide
60
 
// most (but not all) of the same guarantees.  If you do need to
61
 
// guarantee that tasks are run on a single dedicated thread, see
62
 
// SingleThreadTaskRunner (in single_thread_task_runner.h).
63
 
//
64
 
// Some corollaries to the above guarantees, assuming the tasks in
65
 
// question don't call any task-running methods:
66
 
//
67
 
//   - Tasks posted via PostTask are run in FIFO order.
68
 
//
69
 
//   - Tasks posted via PostNonNestableTask are run in FIFO order.
70
 
//
71
 
//   - Tasks posted with the same delay and the same nestable state
72
 
//     are run in FIFO order.
73
 
//
74
 
//   - A list of tasks with the same nestable state posted in order of
75
 
//     non-decreasing delay is run in FIFO order.
76
 
//
77
 
//   - A list of tasks posted in order of non-decreasing delay with at
78
 
//     most a single change in nestable state from nestable to
79
 
//     non-nestable is run in FIFO order. (This is equivalent to the
80
 
//     statement of the first guarantee above.)
81
 
//
82
 
// Some theoretical implementations of SequencedTaskRunner:
83
 
//
84
 
//   - A SequencedTaskRunner that wraps a regular TaskRunner but makes
85
 
//     sure that only one task at a time is posted to the TaskRunner,
86
 
//     with appropriate memory barriers in between tasks.
87
 
//
88
 
//   - A SequencedTaskRunner that, for each task, spawns a joinable
89
 
//     thread to run that task and immediately quit, and then
90
 
//     immediately joins that thread.
91
 
//
92
 
//   - A SequencedTaskRunner that stores the list of posted tasks and
93
 
//     has a method Run() that runs each runnable task in FIFO order
94
 
//     that can be called from any thread, but only if another
95
 
//     (non-nested) Run() call isn't already happening.
96
 
class BASE_EXPORT SequencedTaskRunner : public TaskRunner {
97
 
 public:
98
 
  // The two PostNonNestable*Task methods below are like their
99
 
  // nestable equivalents in TaskRunner, but they guarantee that the
100
 
  // posted task will not run nested within an already-running task.
101
 
  //
102
 
  // A simple corollary is that posting a task as non-nestable can
103
 
  // only delay when the task gets run.  That is, posting a task as
104
 
  // non-nestable may not affect when the task gets run, or it could
105
 
  // make it run later than it normally would, but it won't make it
106
 
  // run earlier than it normally would.
107
 
 
108
 
  // TODO(akalin): Get rid of the boolean return value for the methods
109
 
  // below.
110
 
 
111
 
  bool PostNonNestableTask(const tracked_objects::Location& from_here,
112
 
                           const Closure& task);
113
 
 
114
 
  virtual bool PostNonNestableDelayedTask(
115
 
      const tracked_objects::Location& from_here,
116
 
      const Closure& task,
117
 
      base::TimeDelta delay) = 0;
118
 
 
119
 
  // Submits a non-nestable task to delete the given object.  Returns
120
 
  // true if the object may be deleted at some point in the future,
121
 
  // and false if the object definitely will not be deleted.
122
 
  template <class T>
123
 
  bool DeleteSoon(const tracked_objects::Location& from_here,
124
 
                  const T* object) {
125
 
    return
126
 
        subtle::DeleteHelperInternal<T, bool>::DeleteViaSequencedTaskRunner(
127
 
            this, from_here, object);
128
 
  }
129
 
 
130
 
  // Submits a non-nestable task to release the given object.  Returns
131
 
  // true if the object may be released at some point in the future,
132
 
  // and false if the object definitely will not be released.
133
 
  template <class T>
134
 
  bool ReleaseSoon(const tracked_objects::Location& from_here,
135
 
                   T* object) {
136
 
    return
137
 
        subtle::ReleaseHelperInternal<T, bool>::ReleaseViaSequencedTaskRunner(
138
 
            this, from_here, object);
139
 
  }
140
 
 
141
 
 protected:
142
 
  virtual ~SequencedTaskRunner() {}
143
 
 
144
 
 private:
145
 
  template <class T, class R> friend class subtle::DeleteHelperInternal;
146
 
  template <class T, class R> friend class subtle::ReleaseHelperInternal;
147
 
 
148
 
  bool DeleteSoonInternal(const tracked_objects::Location& from_here,
149
 
                          void(*deleter)(const void*),
150
 
                          const void* object);
151
 
 
152
 
  bool ReleaseSoonInternal(const tracked_objects::Location& from_here,
153
 
                           void(*releaser)(const void*),
154
 
                           const void* object);
155
 
};
156
 
 
157
 
}  // namespace base
158
 
 
159
 
#endif  // BASE_SEQUENCED_TASKRUNNER_H_