| // Copyright 2019 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef BASE_MESSAGE_LOOP_WORK_ID_PROVIDER_H_ | 
 | #define BASE_MESSAGE_LOOP_WORK_ID_PROVIDER_H_ | 
 |  | 
 | #include <atomic> | 
 |  | 
 | #include "base/base_export.h" | 
 | #include "base/threading/thread_checker.h" | 
 |  | 
 | namespace base { | 
 | namespace sequence_manager { | 
 | namespace internal { | 
 | class ThreadControllerWithMessagePumpImpl; | 
 | } | 
 | }  // namespace sequence_manager | 
 |  | 
 | // WorkIdProvider associates with the current thread (via TLS) an id state | 
 | // reflecting the current work item being executed by the message loop. The item | 
 | // is accessed lock-free from other threads to provide a snapshot of the | 
 | // currently-executing work item. | 
 | // | 
 | // The expected user is the ThreadProfiler which samples the id along with the | 
 | // thread's stack to identify cases where the same task spans multiple | 
 | // samples. The state is stored in TLS rather than on the MessageLoop or the | 
 | // ThreadProfiler because the lifetime relationship between the two classes | 
 | // varies depending on which thread is being profiled, plus the fact that | 
 | // MessageLoop doesn't have a well-defined creation point/owner on some threads. | 
 | class BASE_EXPORT WorkIdProvider { | 
 |  public: | 
 |   // Returns the WorkIdProvider for the current thread. Allocates a | 
 |   // WorkIdProvider in TLS if not already present. | 
 |   static WorkIdProvider* GetForCurrentThread(); | 
 |  | 
 |   // Returns the work id for the thread to which this WorkIdProvider | 
 |   // belongs. The work id is 0 before calls to IncrementWorkId() and always | 
 |   // non-zero after that point. The implementation supports being invoked while | 
 |   // other threads are suspended, and thus is guaranteed to take no locks, | 
 |   // directly or indirectly. May be called from any thread, as long as the | 
 |   // owning thread hasn't been destroyed. | 
 |   unsigned int GetWorkId(); | 
 |  | 
 |   // Public to support unique_ptr<WorkIdProvider>. | 
 |   ~WorkIdProvider(); | 
 |  | 
 |   void SetCurrentWorkIdForTesting(unsigned int id); | 
 |   void IncrementWorkIdForTesting(); | 
 |  | 
 |   WorkIdProvider(const WorkIdProvider&) = delete; | 
 |   WorkIdProvider& operator=(const WorkIdProvider&) = delete; | 
 |  | 
 |  private: | 
 |   // Friended to allow use of IncrementWorkId(). | 
 |   friend class sequence_manager::internal::ThreadControllerWithMessagePumpImpl; | 
 |  | 
 |   WorkIdProvider(); | 
 |  | 
 |   void IncrementWorkId(); | 
 |  | 
 |   std::atomic_uint work_id_; | 
 |  | 
 |   THREAD_CHECKER(thread_checker_); | 
 | }; | 
 |  | 
 | }  // namespace base | 
 |  | 
 | #endif  // BASE_MESSAGE_LOOP_WORK_ID_PROVIDER_H_ |