ipc/chromium/src/base/simple_thread.cc

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
michael@0 2 // Use of this source code is governed by a BSD-style license that can be
michael@0 3 // found in the LICENSE file.
michael@0 4
michael@0 5 #include "base/simple_thread.h"
michael@0 6
michael@0 7 #include "base/waitable_event.h"
michael@0 8 #include "base/logging.h"
michael@0 9 #include "base/platform_thread.h"
michael@0 10 #include "base/string_util.h"
michael@0 11
michael@0 12 namespace base {
michael@0 13
michael@0 14 void SimpleThread::Start() {
michael@0 15 DCHECK(!HasBeenStarted()) << "Tried to Start a thread multiple times.";
michael@0 16 bool success = PlatformThread::Create(options_.stack_size(), this, &thread_);
michael@0 17 CHECK(success);
michael@0 18 event_.Wait(); // Wait for the thread to complete initialization.
michael@0 19 }
michael@0 20
michael@0 21 void SimpleThread::Join() {
michael@0 22 DCHECK(HasBeenStarted()) << "Tried to Join a never-started thread.";
michael@0 23 DCHECK(!HasBeenJoined()) << "Tried to Join a thread multiple times.";
michael@0 24 PlatformThread::Join(thread_);
michael@0 25 joined_ = true;
michael@0 26 }
michael@0 27
michael@0 28 void SimpleThread::ThreadMain() {
michael@0 29 tid_ = PlatformThread::CurrentId();
michael@0 30 // Construct our full name of the form "name_prefix_/TID".
michael@0 31 name_.push_back('/');
michael@0 32 name_.append(IntToString(tid_));
michael@0 33 PlatformThread::SetName(name_.c_str());
michael@0 34
michael@0 35 // We've initialized our new thread, signal that we're done to Start().
michael@0 36 event_.Signal();
michael@0 37
michael@0 38 Run();
michael@0 39 }
michael@0 40
michael@0 41 SimpleThread::~SimpleThread() {
michael@0 42 DCHECK(HasBeenStarted()) << "SimpleThread was never started.";
michael@0 43 DCHECK(HasBeenJoined()) << "SimpleThread destroyed without being Join()ed.";
michael@0 44 }
michael@0 45
michael@0 46 void DelegateSimpleThread::Run() {
michael@0 47 DCHECK(delegate_) << "Tried to call Run without a delegate (called twice?)";
michael@0 48 delegate_->Run();
michael@0 49 delegate_ = NULL;
michael@0 50 }
michael@0 51
michael@0 52 DelegateSimpleThreadPool::~DelegateSimpleThreadPool() {
michael@0 53 DCHECK(threads_.empty());
michael@0 54 DCHECK(delegates_.empty());
michael@0 55 DCHECK(!dry_.IsSignaled());
michael@0 56 }
michael@0 57
michael@0 58 void DelegateSimpleThreadPool::Start() {
michael@0 59 DCHECK(threads_.empty()) << "Start() called with outstanding threads.";
michael@0 60 for (int i = 0; i < num_threads_; ++i) {
michael@0 61 DelegateSimpleThread* thread = new DelegateSimpleThread(this, name_prefix_);
michael@0 62 thread->Start();
michael@0 63 threads_.push_back(thread);
michael@0 64 }
michael@0 65 }
michael@0 66
michael@0 67 void DelegateSimpleThreadPool::JoinAll() {
michael@0 68 DCHECK(!threads_.empty()) << "JoinAll() called with no outstanding threads.";
michael@0 69
michael@0 70 // Tell all our threads to quit their worker loop.
michael@0 71 AddWork(NULL, num_threads_);
michael@0 72
michael@0 73 // Join and destroy all the worker threads.
michael@0 74 for (int i = 0; i < num_threads_; ++i) {
michael@0 75 threads_[i]->Join();
michael@0 76 delete threads_[i];
michael@0 77 }
michael@0 78 threads_.clear();
michael@0 79 DCHECK(delegates_.empty());
michael@0 80 }
michael@0 81
michael@0 82 void DelegateSimpleThreadPool::AddWork(Delegate* delegate, int repeat_count) {
michael@0 83 AutoLock locked(lock_);
michael@0 84 for (int i = 0; i < repeat_count; ++i)
michael@0 85 delegates_.push(delegate);
michael@0 86 // If we were empty, signal that we have work now.
michael@0 87 if (!dry_.IsSignaled())
michael@0 88 dry_.Signal();
michael@0 89 }
michael@0 90
michael@0 91 void DelegateSimpleThreadPool::Run() {
michael@0 92 Delegate* work;
michael@0 93
michael@0 94 while (true) {
michael@0 95 dry_.Wait();
michael@0 96 {
michael@0 97 AutoLock locked(lock_);
michael@0 98 if (!dry_.IsSignaled())
michael@0 99 continue;
michael@0 100
michael@0 101 DCHECK(!delegates_.empty());
michael@0 102 work = delegates_.front();
michael@0 103 delegates_.pop();
michael@0 104
michael@0 105 // Signal to any other threads that we're currently out of work.
michael@0 106 if (delegates_.empty())
michael@0 107 dry_.Reset();
michael@0 108 }
michael@0 109
michael@0 110 // A NULL delegate pointer signals us to quit.
michael@0 111 if (!work)
michael@0 112 break;
michael@0 113
michael@0 114 work->Run();
michael@0 115 }
michael@0 116 }
michael@0 117
michael@0 118 } // namespace base

mercurial