1 // Copyright 2016 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_SEQUENCE_TOKEN_H_
6 #define BASE_SEQUENCE_TOKEN_H_
7 
8 #include "base/base_export.h"
9 #include "base/macros.h"
10 
11 namespace base {
12 
13 // A token that identifies a series of sequenced tasks (i.e. tasks that run one
14 // at a time in posting order).
15 class BASE_EXPORT SequenceToken {
16  public:
17   // Instantiates an invalid SequenceToken.
18   SequenceToken() = default;
19 
20   // Explicitly allow copy.
21   SequenceToken(const SequenceToken& other) = default;
22   SequenceToken& operator=(const SequenceToken& other) = default;
23 
24   // An invalid SequenceToken is not equal to any other SequenceToken, including
25   // other invalid SequenceTokens.
26   bool operator==(const SequenceToken& other) const;
27   bool operator!=(const SequenceToken& other) const;
28 
29   // Returns true if this is a valid SequenceToken.
30   bool IsValid() const;
31 
32   // Returns the integer uniquely representing this SequenceToken. This method
33   // should only be used for tracing and debugging.
34   int ToInternalValue() const;
35 
36   // Returns a valid SequenceToken which isn't equal to any previously returned
37   // SequenceToken.
38   static SequenceToken Create();
39 
40   // Returns the SequenceToken associated with the task running on the current
41   // thread, as determined by the active ScopedSetSequenceTokenForCurrentThread
42   // if any.
43   static SequenceToken GetForCurrentThread();
44 
45  private:
SequenceToken(int token)46   explicit SequenceToken(int token) : token_(token) {}
47 
48   static constexpr int kInvalidSequenceToken = -1;
49   int token_ = kInvalidSequenceToken;
50 };
51 
52 // A token that identifies a task.
53 //
54 // This is used by ThreadCheckerImpl to determine whether calls to
55 // CalledOnValidThread() come from the same task and hence are deterministically
56 // single-threaded (vs. calls coming from different sequenced or parallel tasks,
57 // which may or may not run on the same thread).
58 class BASE_EXPORT TaskToken {
59  public:
60   // Instantiates an invalid TaskToken.
61   TaskToken() = default;
62 
63   // Explicitly allow copy.
64   TaskToken(const TaskToken& other) = default;
65   TaskToken& operator=(const TaskToken& other) = default;
66 
67   // An invalid TaskToken is not equal to any other TaskToken, including
68   // other invalid TaskTokens.
69   bool operator==(const TaskToken& other) const;
70   bool operator!=(const TaskToken& other) const;
71 
72   // Returns true if this is a valid TaskToken.
73   bool IsValid() const;
74 
75   // In the scope of a ScopedSetSequenceTokenForCurrentThread, returns a valid
76   // TaskToken which isn't equal to any TaskToken returned in the scope of a
77   // different ScopedSetSequenceTokenForCurrentThread. Otherwise, returns an
78   // invalid TaskToken.
79   static TaskToken GetForCurrentThread();
80 
81  private:
82   friend class ScopedSetSequenceTokenForCurrentThread;
83 
TaskToken(int token)84   explicit TaskToken(int token) : token_(token) {}
85 
86   // Returns a valid TaskToken which isn't equal to any previously returned
87   // TaskToken. This is private as it only meant to be instantiated by
88   // ScopedSetSequenceTokenForCurrentThread.
89   static TaskToken Create();
90 
91   static constexpr int kInvalidTaskToken = -1;
92   int token_ = kInvalidTaskToken;
93 };
94 
95 // Instantiate this in the scope where a single task runs.
96 class BASE_EXPORT ScopedSetSequenceTokenForCurrentThread {
97  public:
98   // Throughout the lifetime of the constructed object,
99   // SequenceToken::GetForCurrentThread() will return |sequence_token| and
100   // TaskToken::GetForCurrentThread() will return a TaskToken which is not equal
101   // to any TaskToken returned in the scope of another
102   // ScopedSetSequenceTokenForCurrentThread.
103   ScopedSetSequenceTokenForCurrentThread(const SequenceToken& sequence_token);
104   ~ScopedSetSequenceTokenForCurrentThread();
105 
106  private:
107   const SequenceToken sequence_token_;
108   const TaskToken task_token_;
109 
110   DISALLOW_COPY_AND_ASSIGN(ScopedSetSequenceTokenForCurrentThread);
111 };
112 
113 }  // namespace base
114 
115 #endif  // BASE_SEQUENCE_TOKEN_H_
116