/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file.
// This task is used to trigger the message loop to exit. class ThreadQuitTask : public mozilla::Runnable { public:
ThreadQuitTask() : mozilla::Runnable("ThreadQuitTask") {}
NS_IMETHOD Run() override {
MessageLoop::current()->Quit();
Thread::SetThreadWasQuitProperly(true); return NS_OK;
}
};
// Used to pass data to ThreadMain. This structure is allocated on the stack // from within StartWithOptions. struct Thread::StartupData { // We get away with a const reference here because of how we are allocated. const Thread::Options& options;
// Used to synchronize thread startup.
WaitableEvent event;
// We use this thread-local variable to record whether or not a thread exited // because its Stop method was called. This allows us to catch cases where // MessageLoop::Quit() is called directly, which is unexpected when using a // Thread to setup and run a MessageLoop.
if (!PlatformThread::Create(options.stack_size, this, &thread_)) {
DLOG(ERROR) << "failed to create thread";
startup_data_ = NULL; // Record that we failed to start. returnfalse;
}
// Wait for the thread to start and initialize message_loop_
startup_data.event.Wait();
DCHECK(message_loop_); returntrue;
}
void Thread::Stop() { if (!thread_was_started()) return;
// We should only be called on the same thread that started us.
DCHECK_NE(thread_id_, PlatformThread::CurrentId());
// StopSoon may have already been called. if (message_loop_) {
RefPtr<ThreadQuitTask> task = new ThreadQuitTask();
message_loop_->PostTask(task.forget());
}
// Wait for the thread to exit. It should already have terminated but make // sure this assumption is valid. // // TODO(darin): Unfortunately, we need to keep message_loop_ around until // the thread exits. Some consumers are abusing the API. Make them stop. //
PlatformThread::Join(thread_);
// The thread can't receive messages anymore.
message_loop_ = NULL;
// The thread no longer needs to be joined.
startup_data_ = NULL;
}
void Thread::StopSoon() { if (!message_loop_) return;
// We should only be called on the same thread that started us.
DCHECK_NE(thread_id_, PlatformThread::CurrentId());
// We had better have a message loop at this point! If we do not, then it // most likely means that the thread terminated unexpectedly, probably due // to someone calling Quit() on our message loop directly.
DCHECK(message_loop_);
RefPtr<ThreadQuitTask> task = new ThreadQuitTask();
message_loop_->PostTask(task.forget());
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.