Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Side by Side Diff: remoting/jingle_glue/jingle_thread.cc

Issue 7302002: Make JingleThreadMessageLoop usable without JingleThread. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: - Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « remoting/jingle_glue/jingle_thread.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/jingle_glue/jingle_thread.h" 5 #include "remoting/jingle_glue/jingle_thread.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_pump.h" 9 #include "base/message_pump.h"
10 #include "base/time.h" 10 #include "base/time.h"
11 #include "third_party/libjingle/source/talk/base/ssladapter.h" 11 #include "third_party/libjingle/source/talk/base/ssladapter.h"
12 12
13 namespace remoting { 13 namespace remoting {
14 14
15 const uint32 kRunTasksMessageId = 1; 15 const uint32 kRunTasksMessageId = 1;
16 const uint32 kStopMessageId = 2; 16 const uint32 kStopMessageId = 2;
17 17
18 class JingleThread::JingleMessagePump : public base::MessagePump, 18 namespace {
19 public talk_base::MessageHandler { 19
20 class JingleMessagePump : public base::MessagePump,
21 public talk_base::MessageHandler {
20 public: 22 public:
21 JingleMessagePump(JingleThread* thread) : thread_(thread) { } 23 JingleMessagePump(talk_base::Thread* thread)
24 : thread_(thread), delegate_(NULL) {
25 }
22 26
23 virtual void Run(Delegate* delegate) { NOTIMPLEMENTED(); } 27 virtual void Run(Delegate* delegate) {
24 virtual void Quit() { NOTIMPLEMENTED(); } 28 delegate_ = delegate;
29
30 talk_base::Thread::Current()->Thread::Run();
31 // Call Restart() so that we can run again.
32 talk_base::Thread::Current()->Restart();
33
34 delegate_ = NULL;
35 }
36
37 virtual void Quit() {
38 talk_base::Thread::Current()->Quit();
39 }
40
25 virtual void ScheduleWork() { 41 virtual void ScheduleWork() {
26 thread_->Post(this, kRunTasksMessageId); 42 thread_->Post(this, kRunTasksMessageId);
27 } 43 }
44
28 virtual void ScheduleDelayedWork(const base::TimeTicks& time) { 45 virtual void ScheduleDelayedWork(const base::TimeTicks& time) {
29 delayed_work_time_ = time; 46 delayed_work_time_ = time;
30 ScheduleNextDelayedTask(); 47 ScheduleNextDelayedTask();
31 } 48 }
32 49
33 void OnMessage(talk_base::Message* msg) { 50 void OnMessage(talk_base::Message* msg) {
34 DCHECK(msg->message_id == kRunTasksMessageId); 51 DCHECK(msg->message_id == kRunTasksMessageId);
52 DCHECK(delegate_);
35 53
36 // Clear currently pending messages in case there were delayed tasks. 54 // Clear currently pending messages in case there were delayed tasks.
37 // Will schedule it again from ScheduleNextDelayedTask() if neccessary. 55 // Will schedule it again from ScheduleNextDelayedTask() if neccessary.
38 thread_->Clear(this, kRunTasksMessageId); 56 thread_->Clear(this, kRunTasksMessageId);
39 57
40 // This code is executed whenever we get new message in |message_loop_|.
41 // JingleMessagePump posts new tasks in the jingle thread.
42 // TODO(sergeyu): Remove it when JingleThread moved on Chromium's
43 // base::Thread.
44 base::MessagePump::Delegate* delegate = thread_->message_loop();
45 // Process all pending tasks. 58 // Process all pending tasks.
46 while (true) { 59 while (true) {
47 if (delegate->DoWork()) 60 if (delegate_->DoWork())
48 continue; 61 continue;
49 if (delegate->DoDelayedWork(&delayed_work_time_)) 62 if (delegate_->DoDelayedWork(&delayed_work_time_))
63 continue;
64 if (delegate_->DoIdleWork())
50 continue; 65 continue;
51 break; 66 break;
52 } 67 }
53 68
54 ScheduleNextDelayedTask(); 69 ScheduleNextDelayedTask();
55 } 70 }
56 71
57 private: 72 private:
58 void ScheduleNextDelayedTask() { 73 void ScheduleNextDelayedTask() {
59 DCHECK_EQ(thread_->message_loop(), MessageLoop::current());
60
61 if (!delayed_work_time_.is_null()) { 74 if (!delayed_work_time_.is_null()) {
62 base::TimeTicks now = base::TimeTicks::Now(); 75 base::TimeTicks now = base::TimeTicks::Now();
63 int delay = static_cast<int>((delayed_work_time_ - now).InMilliseconds()); 76 int delay = static_cast<int>((delayed_work_time_ - now).InMilliseconds());
64 if (delay > 0) { 77 if (delay > 0) {
65 thread_->PostDelayed(delay, this, kRunTasksMessageId); 78 thread_->PostDelayed(delay, this, kRunTasksMessageId);
66 } else { 79 } else {
67 thread_->Post(this, kRunTasksMessageId); 80 thread_->Post(this, kRunTasksMessageId);
68 } 81 }
69 } 82 }
70 } 83 }
71 84
72 JingleThread* thread_; 85 talk_base::Thread* thread_;
86 Delegate* delegate_;
73 base::TimeTicks delayed_work_time_; 87 base::TimeTicks delayed_work_time_;
74 }; 88 };
75 89
76 class JingleThread::JingleMessageLoop : public MessageLoop { 90 } // namespace
77 public:
78 JingleMessageLoop(JingleThread* thread)
79 : MessageLoop(MessageLoop::TYPE_IO) {
80 pump_ = new JingleMessagePump(thread);
81 }
82 91
83 void Initialize() { 92 JingleThreadMessageLoop::JingleThreadMessageLoop(talk_base::Thread* thread)
84 jingle_message_loop_state_.reset(new AutoRunState(this)); 93 : MessageLoop(MessageLoop::TYPE_IO) {
85 } 94 pump_ = new JingleMessagePump(thread);
95 }
86 96
87 private: 97 JingleThreadMessageLoop::~JingleThreadMessageLoop() {
88 // AutoRunState sets |state_| for this message loop. It needs to be 98 }
89 // created here because we never call Run() or RunAllPending() for
90 // the thread.
91 scoped_ptr<AutoRunState> jingle_message_loop_state_;
92 };
93 99
94 TaskPump::TaskPump() { 100 TaskPump::TaskPump() {
95 } 101 }
96 102
97 void TaskPump::WakeTasks() { 103 void TaskPump::WakeTasks() {
98 talk_base::Thread::Current()->Post(this); 104 talk_base::Thread::Current()->Post(this);
99 } 105 }
100 106
101 int64 TaskPump::CurrentTime() { 107 int64 TaskPump::CurrentTime() {
102 return static_cast<int64>(talk_base::Time()); 108 return static_cast<int64>(talk_base::Time());
(...skipping 11 matching lines...) Expand all
114 } 120 }
115 121
116 JingleThread::~JingleThread() { } 122 JingleThread::~JingleThread() { }
117 123
118 void JingleThread::Start() { 124 void JingleThread::Start() {
119 Thread::Start(); 125 Thread::Start();
120 started_event_.Wait(); 126 started_event_.Wait();
121 } 127 }
122 128
123 void JingleThread::Run() { 129 void JingleThread::Run() {
124 JingleMessageLoop message_loop(this); 130 JingleThreadMessageLoop message_loop(this);
125 message_loop.Initialize();
126 message_loop_ = &message_loop; 131 message_loop_ = &message_loop;
127 132
128 TaskPump task_pump; 133 TaskPump task_pump;
129 task_pump_ = &task_pump; 134 task_pump_ = &task_pump;
130 135
131 // Signal after we've initialized |message_loop_| and |task_pump_|. 136 // Signal after we've initialized |message_loop_| and |task_pump_|.
132 started_event_.Signal(); 137 started_event_.Signal();
133 138
134 Thread::Run(); 139 message_loop.Run();
135 140
136 stopped_event_.Signal(); 141 stopped_event_.Signal();
137 142
138 task_pump_ = NULL; 143 task_pump_ = NULL;
139 message_loop_ = NULL; 144 message_loop_ = NULL;
140 } 145 }
141 146
142 void JingleThread::Stop() { 147 void JingleThread::Stop() {
143 // Shutdown gracefully: make sure that we excute all messages left in the 148 // Shutdown gracefully: make sure that we excute all messages left in the
144 // queue before exiting. Thread::Stop() would not do that. 149 // queue before exiting. Thread::Stop() would not do that.
145 Post(this, kStopMessageId); 150 Post(this, kStopMessageId);
146 stopped_event_.Wait(); 151 stopped_event_.Wait();
147 152
148 // This will wait until the thread is actually finished. 153 // This will wait until the thread is actually finished.
149 Thread::Stop(); 154 Thread::Stop();
150 } 155 }
151 156
152 MessageLoop* JingleThread::message_loop() { 157 MessageLoop* JingleThread::message_loop() {
153 return message_loop_; 158 return message_loop_;
154 } 159 }
155 160
156 // Returns task pump if the thread is running, otherwise NULL is returned.
157 TaskPump* JingleThread::task_pump() { 161 TaskPump* JingleThread::task_pump() {
158 return task_pump_; 162 return task_pump_;
159 } 163 }
160 164
161 void JingleThread::OnMessage(talk_base::Message* msg) { 165 void JingleThread::OnMessage(talk_base::Message* msg) {
162 DCHECK(msg->message_id == kStopMessageId); 166 DCHECK(msg->message_id == kStopMessageId);
163 167
164 // Stop the thread only if there are no more messages left in the queue, 168 // Stop the thread only if there are no more messages left in the queue,
165 // otherwise post another task to try again later. 169 // otherwise post another task to try again later.
166 if (!msgq_.empty() || fPeekKeep_) { 170 if (!msgq_.empty() || fPeekKeep_) {
167 Post(this, kStopMessageId); 171 Post(this, kStopMessageId);
168 } else { 172 } else {
169 MessageQueue::Quit(); 173 MessageQueue::Quit();
170 } 174 }
171 } 175 }
172 176
173 } // namespace remoting 177 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/jingle_glue/jingle_thread.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698