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