blob: 00370668acb38e22b7ff689f2ab12b4601beaf7f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
// Copyright (c) 2010 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.
#include "remoting/jingle_glue/jingle_thread.h"
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/message_pump.h"
#include "base/time.h"
#include "third_party/libjingle/source/talk/base/ssladapter.h"
namespace remoting {
const uint32 kRunTasksMessageId = 1;
const uint32 kStopMessageId = 2;
class JingleThread::JingleMessagePump : public base::MessagePump {
public:
JingleMessagePump(JingleThread* thread) : thread_(thread) { }
virtual void Run(Delegate* delegate) { NOTIMPLEMENTED() ;}
virtual void Quit() { NOTIMPLEMENTED(); }
virtual void ScheduleWork() {
thread_->Post(thread_, kRunTasksMessageId);
}
virtual void ScheduleDelayedWork(const base::Time& time) {
NOTIMPLEMENTED();
}
private:
JingleThread* thread_;
};
class JingleThread::JingleMessageLoop : public MessageLoop {
public:
JingleMessageLoop(JingleThread* thread)
: MessageLoop(MessageLoop::TYPE_IO) {
pump_ = new JingleMessagePump(thread);
}
};
TaskPump::TaskPump() {
}
void TaskPump::WakeTasks() {
talk_base::Thread::Current()->Post(this);
}
int64 TaskPump::CurrentTime() {
return static_cast<int64>(talk_base::Time());
}
void TaskPump::OnMessage(talk_base::Message* pmsg) {
RunTasks();
}
JingleThread::JingleThread()
: task_pump_(NULL),
started_event_(true, false),
stopped_event_(true, false),
message_loop_(NULL) {
}
JingleThread::~JingleThread() { }
void JingleThread::Start() {
Thread::Start();
started_event_.Wait();
}
void JingleThread::Run() {
JingleMessageLoop message_loop(this);
message_loop_ = &message_loop;
TaskPump task_pump;
task_pump_ = &task_pump;
// Signal after we've initialized |message_loop_| and |task_pump_|.
started_event_.Signal();
Thread::Run();
stopped_event_.Signal();
task_pump_ = NULL;
message_loop_ = NULL;
}
void JingleThread::Stop() {
// Shutdown gracefully: make sure that we excute all messages left in the
// queue before exiting. Thread::Stop() would not do that.
Post(this, kStopMessageId);
stopped_event_.Wait();
}
MessageLoop* JingleThread::message_loop() {
return message_loop_;
}
// Returns task pump if the thread is running, otherwise NULL is returned.
TaskPump* JingleThread::task_pump() {
return task_pump_;
}
void JingleThread::OnMessage(talk_base::Message* msg) {
if (msg->message_id == kRunTasksMessageId) {
// This code is executed whenever we get new message in |message_loop_|.
// JingleMessagePump posts new tasks in the jingle thread.
// TODO(sergeyu): Remove it when JingleThread moved on Chromium's
// base::Thread.
base::MessagePump::Delegate* delegate = message_loop_;
// Loop until we run out of work.
while (true) {
if (!delegate->DoWork())
break;
}
} else if (msg->message_id == kStopMessageId) {
// Stop the thread only if there are no more messages left in the queue,
// otherwise post another task to try again later.
if (msgq_.size() > 0 || fPeekKeep_) {
Post(this, kStopMessageId);
} else {
MessageQueue::Quit();
}
}
}
} // namespace remoting
|