1// Copyright (c) 2011 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// The thread pool used in the POSIX implementation of WorkerPool dynamically 6// adds threads as necessary to handle all tasks. It keeps old threads around 7// for a period of time to allow them to be reused. After this waiting period, 8// the threads exit. This thread pool uses non-joinable threads, therefore 9// worker threads are not joined during process shutdown. This means that 10// potentially long running tasks (such as DNS lookup) do not block process 11// shutdown, but also means that process shutdown may "leak" objects. Note that 12// although PosixDynamicThreadPool spawns the worker threads and manages the 13// task queue, it does not own the worker threads. The worker threads ask the 14// PosixDynamicThreadPool for work and eventually clean themselves up. The 15// worker threads all maintain scoped_refptrs to the PosixDynamicThreadPool 16// instance, which prevents PosixDynamicThreadPool from disappearing before all 17// worker threads exit. The owner of PosixDynamicThreadPool should likewise 18// maintain a scoped_refptr to the PosixDynamicThreadPool instance. 19// 20// NOTE: The classes defined in this file are only meant for use by the POSIX 21// implementation of WorkerPool. No one else should be using these classes. 22// These symbols are exported in a header purely for testing purposes. 23 24#ifndef BASE_THREADING_WORKER_POOL_POSIX_H_ 25#define BASE_THREADING_WORKER_POOL_POSIX_H_ 26#pragma once 27 28#include <queue> 29#include <string> 30 31#include "base/basictypes.h" 32#include "base/memory/ref_counted.h" 33#include "base/memory/scoped_ptr.h" 34#include "base/synchronization/condition_variable.h" 35#include "base/synchronization/lock.h" 36#include "base/threading/platform_thread.h" 37 38class Task; 39 40namespace base { 41 42class PosixDynamicThreadPool 43 : public RefCountedThreadSafe<PosixDynamicThreadPool> { 44 public: 45 class PosixDynamicThreadPoolPeer; 46 47 // All worker threads will share the same |name_prefix|. They will exit after 48 // |idle_seconds_before_exit|. 49 PosixDynamicThreadPool(const std::string& name_prefix, 50 int idle_seconds_before_exit); 51 ~PosixDynamicThreadPool(); 52 53 // Indicates that the thread pool is going away. Stops handing out tasks to 54 // worker threads. Wakes up all the idle threads to let them exit. 55 void Terminate(); 56 57 // Adds |task| to the thread pool. PosixDynamicThreadPool assumes ownership 58 // of |task|. 59 void PostTask(Task* task); 60 61 // Worker thread method to wait for up to |idle_seconds_before_exit| for more 62 // work from the thread pool. Returns NULL if no work is available. 63 Task* WaitForTask(); 64 65 private: 66 friend class PosixDynamicThreadPoolPeer; 67 68 const std::string name_prefix_; 69 const int idle_seconds_before_exit_; 70 71 Lock lock_; // Protects all the variables below. 72 73 // Signal()s worker threads to let them know more tasks are available. 74 // Also used for Broadcast()'ing to worker threads to let them know the pool 75 // is being deleted and they can exit. 76 ConditionVariable tasks_available_cv_; 77 int num_idle_threads_; 78 std::queue<Task*> tasks_; 79 bool terminated_; 80 // Only used for tests to ensure correct thread ordering. It will always be 81 // NULL in non-test code. 82 scoped_ptr<ConditionVariable> num_idle_threads_cv_; 83 84 DISALLOW_COPY_AND_ASSIGN(PosixDynamicThreadPool); 85}; 86 87} // namespace base 88 89#endif // BASE_THREADING_WORKER_POOL_POSIX_H_ 90