Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 // Copyright (c) 2006-2008 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.
5 #include "base/simple_thread.h"
7 #include "base/waitable_event.h"
8 #include "base/logging.h"
9 #include "base/platform_thread.h"
10 #include "base/string_util.h"
12 namespace base {
14 void SimpleThread::Start() {
15 DCHECK(!HasBeenStarted()) << "Tried to Start a thread multiple times.";
16 bool success = PlatformThread::Create(options_.stack_size(), this, &thread_);
17 CHECK(success);
18 event_.Wait(); // Wait for the thread to complete initialization.
19 }
21 void SimpleThread::Join() {
22 DCHECK(HasBeenStarted()) << "Tried to Join a never-started thread.";
23 DCHECK(!HasBeenJoined()) << "Tried to Join a thread multiple times.";
24 PlatformThread::Join(thread_);
25 joined_ = true;
26 }
28 void SimpleThread::ThreadMain() {
29 tid_ = PlatformThread::CurrentId();
30 // Construct our full name of the form "name_prefix_/TID".
31 name_.push_back('/');
32 name_.append(IntToString(tid_));
33 PlatformThread::SetName(name_.c_str());
35 // We've initialized our new thread, signal that we're done to Start().
36 event_.Signal();
38 Run();
39 }
41 SimpleThread::~SimpleThread() {
42 DCHECK(HasBeenStarted()) << "SimpleThread was never started.";
43 DCHECK(HasBeenJoined()) << "SimpleThread destroyed without being Join()ed.";
44 }
46 void DelegateSimpleThread::Run() {
47 DCHECK(delegate_) << "Tried to call Run without a delegate (called twice?)";
48 delegate_->Run();
49 delegate_ = NULL;
50 }
52 DelegateSimpleThreadPool::~DelegateSimpleThreadPool() {
53 DCHECK(threads_.empty());
54 DCHECK(delegates_.empty());
55 DCHECK(!dry_.IsSignaled());
56 }
58 void DelegateSimpleThreadPool::Start() {
59 DCHECK(threads_.empty()) << "Start() called with outstanding threads.";
60 for (int i = 0; i < num_threads_; ++i) {
61 DelegateSimpleThread* thread = new DelegateSimpleThread(this, name_prefix_);
62 thread->Start();
63 threads_.push_back(thread);
64 }
65 }
67 void DelegateSimpleThreadPool::JoinAll() {
68 DCHECK(!threads_.empty()) << "JoinAll() called with no outstanding threads.";
70 // Tell all our threads to quit their worker loop.
71 AddWork(NULL, num_threads_);
73 // Join and destroy all the worker threads.
74 for (int i = 0; i < num_threads_; ++i) {
75 threads_[i]->Join();
76 delete threads_[i];
77 }
78 threads_.clear();
79 DCHECK(delegates_.empty());
80 }
82 void DelegateSimpleThreadPool::AddWork(Delegate* delegate, int repeat_count) {
83 AutoLock locked(lock_);
84 for (int i = 0; i < repeat_count; ++i)
85 delegates_.push(delegate);
86 // If we were empty, signal that we have work now.
87 if (!dry_.IsSignaled())
88 dry_.Signal();
89 }
91 void DelegateSimpleThreadPool::Run() {
92 Delegate* work;
94 while (true) {
95 dry_.Wait();
96 {
97 AutoLock locked(lock_);
98 if (!dry_.IsSignaled())
99 continue;
101 DCHECK(!delegates_.empty());
102 work = delegates_.front();
103 delegates_.pop();
105 // Signal to any other threads that we're currently out of work.
106 if (delegates_.empty())
107 dry_.Reset();
108 }
110 // A NULL delegate pointer signals us to quit.
111 if (!work)
112 break;
114 work->Run();
115 }
116 }
118 } // namespace base