| Index: jingle/notifier/base/signal_thread_task.h
|
| diff --git a/jingle/notifier/base/signal_thread_task.h b/jingle/notifier/base/signal_thread_task.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..8a6ff271b79ced3be9fac0aad67b56e042bf35d0
|
| --- /dev/null
|
| +++ b/jingle/notifier/base/signal_thread_task.h
|
| @@ -0,0 +1,96 @@
|
| +// Copyright (c) 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.
|
| +
|
| +#ifndef JINGLE_NOTIFIER_BASE_SIGNAL_THREAD_TASK_H_
|
| +#define JINGLE_NOTIFIER_BASE_SIGNAL_THREAD_TASK_H_
|
| +
|
| +#include "base/logging.h"
|
| +#include "talk/base/common.h"
|
| +#include "talk/base/signalthread.h"
|
| +#include "talk/base/sigslot.h"
|
| +#include "talk/base/task.h"
|
| +
|
| +namespace notifier {
|
| +
|
| +template<class T>
|
| +class SignalThreadTask : public talk_base::Task,
|
| + public sigslot::has_slots<> {
|
| + public:
|
| + // Takes ownership of signal_thread.
|
| + SignalThreadTask(talk_base::Task* task_parent, T** signal_thread)
|
| + : talk_base::Task(task_parent),
|
| + signal_thread_(NULL),
|
| + finished_(false) {
|
| + SetSignalThread(signal_thread);
|
| + }
|
| +
|
| + virtual ~SignalThreadTask() {
|
| + ClearSignalThread();
|
| + }
|
| +
|
| + virtual void Stop() {
|
| + Task::Stop();
|
| + ClearSignalThread();
|
| + }
|
| +
|
| + virtual int ProcessStart() {
|
| + DCHECK_EQ(GetState(), talk_base::Task::STATE_START);
|
| + signal_thread_->SignalWorkDone.connect(
|
| + this,
|
| + &SignalThreadTask<T>::OnWorkDone);
|
| + signal_thread_->Start();
|
| + return talk_base::Task::STATE_RESPONSE;
|
| + }
|
| +
|
| + int ProcessResponse() {
|
| + if (!finished_) {
|
| + return talk_base::Task::STATE_BLOCKED;
|
| + }
|
| + SignalWorkDone(signal_thread_);
|
| + ClearSignalThread();
|
| + return talk_base::Task::STATE_DONE;
|
| + }
|
| +
|
| + sigslot::signal1<T*> SignalWorkDone;
|
| +
|
| + private:
|
| + // Takes ownership of signal_thread.
|
| + void SetSignalThread(T** signal_thread) {
|
| + DCHECK(!signal_thread_);
|
| + DCHECK(signal_thread);
|
| + DCHECK(*signal_thread);
|
| + // No one should be listening to the signal thread for work done.
|
| + // They should be using this class instead. Unfortunately, we
|
| + // can't verify this.
|
| +
|
| + signal_thread_ = *signal_thread;
|
| +
|
| + // Helps callers not to use signal thread after this point since this class
|
| + // has taken ownership (and avoid the error of doing
|
| + // signal_thread->Start()).
|
| + *signal_thread = NULL;
|
| + }
|
| +
|
| + void OnWorkDone(talk_base::SignalThread* signal_thread) {
|
| + DCHECK_EQ(signal_thread, signal_thread_);
|
| + finished_ = true;
|
| + Wake();
|
| + }
|
| +
|
| + void ClearSignalThread() {
|
| + if (signal_thread_) {
|
| + // Don't wait on the thread destruction, or we may deadlock.
|
| + signal_thread_->Destroy(false);
|
| + signal_thread_ = NULL;
|
| + }
|
| + }
|
| +
|
| + T* signal_thread_;
|
| + bool finished_;
|
| + DISALLOW_COPY_AND_ASSIGN(SignalThreadTask);
|
| +};
|
| +
|
| +} // namespace notifier
|
| +
|
| +#endif // JINGLE_NOTIFIER_BASE_SIGNAL_THREAD_TASK_H_
|
|
|