xref: /aosp_15_r20/external/cronet/base/task/thread_pool/worker_thread_semaphore.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2024 The Chromium Authors
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_TASK_THREAD_POOL_WORKER_THREAD_SEMAPHORE_H_
6 #define BASE_TASK_THREAD_POOL_WORKER_THREAD_SEMAPHORE_H_
7 
8 #include "base/task/thread_pool/worker_thread.h"
9 
10 #include "base/task/thread_pool/semaphore.h"
11 #include "base/task/thread_pool/task_tracker.h"
12 
13 namespace base::internal {
14 
15 class TaskTracker;
16 
17 class BASE_EXPORT WorkerThreadSemaphore : public WorkerThread {
18  public:
19   class BASE_EXPORT Delegate : public WorkerThread::Delegate {
20    protected:
21     friend WorkerThreadSemaphore;
22     explicit Delegate(Semaphore* semaphore,
23                       AtomicFlag* join_called_for_testing);
24 
25     bool TimedWait(TimeDelta timeout) override;
26 
27     // Common semaphore to wake up threads managed by the WorkerThreads sharing
28     // this semaphore.
29     raw_ptr<Semaphore> semaphore_;
30     raw_ptr<AtomicFlag> join_called_for_testing_;
31 
32     // Whether the worker timed out last wakeup. Set in TimedWait().
33     bool timed_out_;
34   };
35 
36   // Everything is passed to WorkerThread's constructor, except the Delegate.
37   WorkerThreadSemaphore(ThreadType thread_type_hint,
38                         std::unique_ptr<Delegate> delegate,
39                         TrackedRef<TaskTracker> task_tracker,
40                         size_t sequence_num,
41                         const CheckedLock* predecessor_lock = nullptr,
42                         void* flow_terminator = nullptr);
43 
44   WorkerThreadSemaphore(const WorkerThread&) = delete;
45   WorkerThreadSemaphore& operator=(const WorkerThread&) = delete;
46 
47   // Joins this WorkerThread. This function must be called after the caller has
48   // set Delegate::join_called_for_testing_ and signaled the semaphore. Note
49   // that this implementation is different than WorkerThreadWaitableEvent,
50   // because this worker joins on a per-group basis rather than a per-worker
51   // basis, given that the workers share the wakeup mechanism.
52   //
53   // Note: A thread that detaches before JoinForTesting() is called may still be
54   // running after JoinForTesting() returns. However, it can't run tasks after
55   // JoinForTesting() returns.
56   void JoinForTesting();
57 
58   // WorkerThread:
59   void Cleanup() override;
60   Delegate* delegate() override;
61   bool join_called_for_testing() const override;
62 
63  private:
64   const std::unique_ptr<Delegate> delegate_;
65 
66   ~WorkerThreadSemaphore() override;
67 };
68 
69 }  // namespace base::internal
70 
71 #endif  // BASE_TASK_THREAD_POOL_WORKER_THREAD_SEMAPHORE_H_
72