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