| Index: runtime/vm/thread_pool.h
 | 
| diff --git a/runtime/vm/thread_pool.h b/runtime/vm/thread_pool.h
 | 
| index 792aef7b23898d4cda77cf6345f11b6dfe0ff770..171378104e52df99d3c648193d56f3dd74ad726c 100644
 | 
| --- a/runtime/vm/thread_pool.h
 | 
| +++ b/runtime/vm/thread_pool.h
 | 
| @@ -5,6 +5,7 @@
 | 
|  #ifndef VM_THREAD_POOL_H_
 | 
|  #define VM_THREAD_POOL_H_
 | 
|  
 | 
| +#include "vm/allocation.h"
 | 
|  #include "vm/globals.h"
 | 
|  #include "vm/os_thread.h"
 | 
|  
 | 
| @@ -29,12 +30,12 @@ class ThreadPool {
 | 
|  
 | 
|    ThreadPool();
 | 
|  
 | 
| -  // Shuts down this thread pool.  Causes workers to terminate
 | 
| +  // Shuts down this thread pool. Causes workers to terminate
 | 
|    // themselves when they are active again.
 | 
|    ~ThreadPool();
 | 
|  
 | 
|    // Runs a task on the thread pool.
 | 
| -  void Run(Task* task);
 | 
| +  bool Run(Task* task);
 | 
|  
 | 
|    // Some simple stats.
 | 
|    uint64_t workers_running() const { return count_running_; }
 | 
| @@ -43,8 +44,6 @@ class ThreadPool {
 | 
|    uint64_t workers_stopped() const { return count_stopped_; }
 | 
|  
 | 
|   private:
 | 
| -  friend class ThreadPoolTestPeer;
 | 
| -
 | 
|    class Worker {
 | 
|     public:
 | 
|      explicit Worker(ThreadPool* pool);
 | 
| @@ -56,24 +55,30 @@ class ThreadPool {
 | 
|      // after a task has been set by the initial call to SetTask().
 | 
|      void StartThread();
 | 
|  
 | 
| -    // Main loop for a worker.
 | 
| -    void Loop();
 | 
| +    // Main loop for a worker. Returns true if worker is removed from thread
 | 
| +    // lists, false otherwise.
 | 
| +    bool Loop();
 | 
|  
 | 
|      // Causes worker to terminate eventually.
 | 
|      void Shutdown();
 | 
|  
 | 
| +    // Get the Worker's thread id.
 | 
| +    ThreadId id();
 | 
| +
 | 
|     private:
 | 
|      friend class ThreadPool;
 | 
|  
 | 
|      // The main entry point for new worker threads.
 | 
|      static void Main(uword args);
 | 
|  
 | 
| -    bool IsDone() const { return pool_ == NULL; }
 | 
| +    bool IsDone() const { return done_; }
 | 
|  
 | 
|      // Fields owned by Worker.
 | 
|      Monitor monitor_;
 | 
|      ThreadPool* pool_;
 | 
|      Task* task_;
 | 
| +    ThreadId id_;
 | 
| +    bool done_;
 | 
|  
 | 
|      // Fields owned by ThreadPool.  Workers should not look at these
 | 
|      // directly.  It's like looking at the sun.
 | 
| @@ -81,9 +86,31 @@ class ThreadPool {
 | 
|      Worker* all_next_;   // Protected by ThreadPool::mutex_
 | 
|      Worker* idle_next_;  // Protected by ThreadPool::mutex_
 | 
|  
 | 
| +    Worker* shutdown_next_;  // Protected by ThreadPool::exit_monitor
 | 
| +
 | 
|      DISALLOW_COPY_AND_ASSIGN(Worker);
 | 
|    };
 | 
|  
 | 
| +  class JoinList {
 | 
| +   public:
 | 
| +    explicit JoinList(ThreadJoinId id, JoinList* next) : id_(id), next_(next) {
 | 
| +    }
 | 
| +
 | 
| +    // The thread pool's mutex_ must be held when calling this.
 | 
| +    static void AddLocked(ThreadJoinId id, JoinList** list);
 | 
| +
 | 
| +    static void Join(JoinList** list);
 | 
| +
 | 
| +    ThreadJoinId id() const { return id_; }
 | 
| +    JoinList* next() const { return next_; }
 | 
| +
 | 
| +   private:
 | 
| +    ThreadJoinId id_;
 | 
| +    JoinList* next_;
 | 
| +
 | 
| +    DISALLOW_COPY_AND_ASSIGN(JoinList);
 | 
| +  };
 | 
| +
 | 
|    void Shutdown();
 | 
|  
 | 
|    // Expensive.  Use only in assertions.
 | 
| @@ -92,8 +119,13 @@ class ThreadPool {
 | 
|    bool RemoveWorkerFromIdleList(Worker* worker);
 | 
|    bool RemoveWorkerFromAllList(Worker* worker);
 | 
|  
 | 
| +  void AddWorkerToShutdownList(Worker* worker);
 | 
| +  bool RemoveWorkerFromShutdownList(Worker* worker);
 | 
| +
 | 
| +  void ReapExitedIdleThreads();
 | 
| +
 | 
|    // Worker operations.
 | 
| -  void SetIdle(Worker* worker);
 | 
| +  void SetIdleAndReapExited(Worker* worker);
 | 
|    bool ReleaseIdleWorker(Worker* worker);
 | 
|  
 | 
|    Mutex mutex_;
 | 
| @@ -105,8 +137,9 @@ class ThreadPool {
 | 
|    uint64_t count_running_;
 | 
|    uint64_t count_idle_;
 | 
|  
 | 
| -  static Monitor* exit_monitor_;  // Used only in testing.
 | 
| -  static int* exit_count_;        // Used only in testing.
 | 
| +  Monitor exit_monitor_;
 | 
| +  Worker* shutting_down_workers_;
 | 
| +  JoinList* join_list_;
 | 
|  
 | 
|    DISALLOW_COPY_AND_ASSIGN(ThreadPool);
 | 
|  };
 | 
| 
 |