| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 
| 3  * | 3  * | 
| 4  *  Use of this source code is governed by a BSD-style license | 4  *  Use of this source code is governed by a BSD-style license | 
| 5  *  that can be found in the LICENSE file in the root of the source | 5  *  that can be found in the LICENSE file in the root of the source | 
| 6  *  tree. An additional intellectual property rights grant can be found | 6  *  tree. An additional intellectual property rights grant can be found | 
| 7  *  in the file PATENTS.  All contributing project authors may | 7  *  in the file PATENTS.  All contributing project authors may | 
| 8  *  be found in the AUTHORS file in the root of the source tree. | 8  *  be found in the AUTHORS file in the root of the source tree. | 
| 9  */ | 9  */ | 
| 10 | 10 | 
| 11 #include "webrtc/modules/utility/source/process_thread_impl.h" | 11 #include "webrtc/modules/utility/source/process_thread_impl.h" | 
| 12 | 12 | 
| 13 #include "webrtc/base/checks.h" | 13 #include "webrtc/base/checks.h" | 
| 14 #include "webrtc/base/task_queue.h" | 14 #include "webrtc/base/task_queue.h" | 
| 15 #include "webrtc/base/timeutils.h" | 15 #include "webrtc/base/timeutils.h" | 
|  | 16 #include "webrtc/base/trace_event.h" | 
| 16 #include "webrtc/modules/include/module.h" | 17 #include "webrtc/modules/include/module.h" | 
| 17 #include "webrtc/system_wrappers/include/logging.h" | 18 #include "webrtc/system_wrappers/include/logging.h" | 
| 18 | 19 | 
| 19 namespace webrtc { | 20 namespace webrtc { | 
| 20 namespace { | 21 namespace { | 
| 21 | 22 | 
| 22 // We use this constant internally to signal that a module has requested | 23 // We use this constant internally to signal that a module has requested | 
| 23 // a callback right away.  When this is set, no call to TimeUntilNextProcess | 24 // a callback right away.  When this is set, no call to TimeUntilNextProcess | 
| 24 // should be made, but Process() should be called directly. | 25 // should be made, but Process() should be called directly. | 
| 25 const int64_t kCallProcessImmediately = -1; | 26 const int64_t kCallProcessImmediately = -1; | 
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 122 | 123 | 
| 123 void ProcessThreadImpl::PostTask(std::unique_ptr<rtc::QueuedTask> task) { | 124 void ProcessThreadImpl::PostTask(std::unique_ptr<rtc::QueuedTask> task) { | 
| 124   // Allowed to be called on any thread. | 125   // Allowed to be called on any thread. | 
| 125   { | 126   { | 
| 126     rtc::CritScope lock(&lock_); | 127     rtc::CritScope lock(&lock_); | 
| 127     queue_.push(task.release()); | 128     queue_.push(task.release()); | 
| 128   } | 129   } | 
| 129   wake_up_->Set(); | 130   wake_up_->Set(); | 
| 130 } | 131 } | 
| 131 | 132 | 
| 132 void ProcessThreadImpl::RegisterModule(Module* module) { | 133 void ProcessThreadImpl::RegisterModule(Module* module, | 
|  | 134                                        const rtc::Location& from) { | 
| 133   RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 135   RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 
| 134   RTC_DCHECK(module); | 136   RTC_DCHECK(module); | 
| 135 | 137 | 
| 136 #if RTC_DCHECK_IS_ON | 138 #if RTC_DCHECK_IS_ON | 
| 137   { | 139   { | 
| 138     // Catch programmer error. | 140     // Catch programmer error. | 
| 139     rtc::CritScope lock(&lock_); | 141     rtc::CritScope lock(&lock_); | 
| 140     for (const ModuleCallback& mc : modules_) | 142     for (const ModuleCallback& mc : modules_) | 
| 141       RTC_DCHECK(mc.module != module); | 143       RTC_DCHECK(mc.module != module); | 
| 142   } | 144   } | 
| 143 #endif | 145 #endif | 
| 144 | 146 | 
| 145   // Now that we know the module isn't in the list, we'll call out to notify | 147   // Now that we know the module isn't in the list, we'll call out to notify | 
| 146   // the module that it's attached to the worker thread.  We don't hold | 148   // the module that it's attached to the worker thread.  We don't hold | 
| 147   // the lock while we make this call. | 149   // the lock while we make this call. | 
| 148   if (thread_.get()) | 150   if (thread_.get()) | 
| 149     module->ProcessThreadAttached(this); | 151     module->ProcessThreadAttached(this); | 
| 150 | 152 | 
| 151   { | 153   { | 
| 152     rtc::CritScope lock(&lock_); | 154     rtc::CritScope lock(&lock_); | 
| 153     modules_.push_back(ModuleCallback(module)); | 155     modules_.push_back(ModuleCallback(module, from)); | 
| 154   } | 156   } | 
| 155 | 157 | 
| 156   // Wake the thread calling ProcessThreadImpl::Process() to update the | 158   // Wake the thread calling ProcessThreadImpl::Process() to update the | 
| 157   // waiting time. The waiting time for the just registered module may be | 159   // waiting time. The waiting time for the just registered module may be | 
| 158   // shorter than all other registered modules. | 160   // shorter than all other registered modules. | 
| 159   wake_up_->Set(); | 161   wake_up_->Set(); | 
| 160 } | 162 } | 
| 161 | 163 | 
| 162 void ProcessThreadImpl::DeRegisterModule(Module* module) { | 164 void ProcessThreadImpl::DeRegisterModule(Module* module) { | 
| 163   // Allowed to be called on any thread. | 165   // Allowed to be called on any thread. | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
| 182       module->ProcessThreadAttached(nullptr); | 184       module->ProcessThreadAttached(nullptr); | 
| 183   } | 185   } | 
| 184 } | 186 } | 
| 185 | 187 | 
| 186 // static | 188 // static | 
| 187 bool ProcessThreadImpl::Run(void* obj) { | 189 bool ProcessThreadImpl::Run(void* obj) { | 
| 188   return static_cast<ProcessThreadImpl*>(obj)->Process(); | 190   return static_cast<ProcessThreadImpl*>(obj)->Process(); | 
| 189 } | 191 } | 
| 190 | 192 | 
| 191 bool ProcessThreadImpl::Process() { | 193 bool ProcessThreadImpl::Process() { | 
|  | 194   TRACE_EVENT1("webrtc", "ProcessThreadImpl", "name", thread_name_); | 
| 192   int64_t now = rtc::TimeMillis(); | 195   int64_t now = rtc::TimeMillis(); | 
| 193   int64_t next_checkpoint = now + (1000 * 60); | 196   int64_t next_checkpoint = now + (1000 * 60); | 
| 194 | 197 | 
| 195   { | 198   { | 
| 196     rtc::CritScope lock(&lock_); | 199     rtc::CritScope lock(&lock_); | 
| 197     if (stop_) | 200     if (stop_) | 
| 198       return false; | 201       return false; | 
| 199     for (ModuleCallback& m : modules_) { | 202     for (ModuleCallback& m : modules_) { | 
| 200       // TODO(tommi): Would be good to measure the time TimeUntilNextProcess | 203       // TODO(tommi): Would be good to measure the time TimeUntilNextProcess | 
| 201       // takes and dcheck if it takes too long (e.g. >=10ms).  Ideally this | 204       // takes and dcheck if it takes too long (e.g. >=10ms).  Ideally this | 
| 202       // operation should not require taking a lock, so querying all modules | 205       // operation should not require taking a lock, so querying all modules | 
| 203       // should run in a matter of nanoseconds. | 206       // should run in a matter of nanoseconds. | 
| 204       if (m.next_callback == 0) | 207       if (m.next_callback == 0) | 
| 205         m.next_callback = GetNextCallbackTime(m.module, now); | 208         m.next_callback = GetNextCallbackTime(m.module, now); | 
| 206 | 209 | 
| 207       if (m.next_callback <= now || | 210       if (m.next_callback <= now || | 
| 208           m.next_callback == kCallProcessImmediately) { | 211           m.next_callback == kCallProcessImmediately) { | 
| 209         m.module->Process(); | 212         { | 
|  | 213           TRACE_EVENT2("webrtc", "ModuleProcess", "function", | 
|  | 214                        m.location.function_name(), "file", | 
|  | 215                        m.location.file_and_line()); | 
|  | 216           m.module->Process(); | 
|  | 217         } | 
| 210         // Use a new 'now' reference to calculate when the next callback | 218         // Use a new 'now' reference to calculate when the next callback | 
| 211         // should occur.  We'll continue to use 'now' above for the baseline | 219         // should occur.  We'll continue to use 'now' above for the baseline | 
| 212         // of calculating how long we should wait, to reduce variance. | 220         // of calculating how long we should wait, to reduce variance. | 
| 213         int64_t new_now = rtc::TimeMillis(); | 221         int64_t new_now = rtc::TimeMillis(); | 
| 214         m.next_callback = GetNextCallbackTime(m.module, new_now); | 222         m.next_callback = GetNextCallbackTime(m.module, new_now); | 
| 215       } | 223       } | 
| 216 | 224 | 
| 217       if (m.next_callback < next_checkpoint) | 225       if (m.next_callback < next_checkpoint) | 
| 218         next_checkpoint = m.next_callback; | 226         next_checkpoint = m.next_callback; | 
| 219     } | 227     } | 
| 220 | 228 | 
| 221     while (!queue_.empty()) { | 229     while (!queue_.empty()) { | 
| 222       rtc::QueuedTask* task = queue_.front(); | 230       rtc::QueuedTask* task = queue_.front(); | 
| 223       queue_.pop(); | 231       queue_.pop(); | 
| 224       lock_.Leave(); | 232       lock_.Leave(); | 
| 225       task->Run(); | 233       task->Run(); | 
| 226       delete task; | 234       delete task; | 
| 227       lock_.Enter(); | 235       lock_.Enter(); | 
| 228     } | 236     } | 
| 229   } | 237   } | 
| 230 | 238 | 
| 231   int64_t time_to_wait = next_checkpoint - rtc::TimeMillis(); | 239   int64_t time_to_wait = next_checkpoint - rtc::TimeMillis(); | 
| 232   if (time_to_wait > 0) | 240   if (time_to_wait > 0) | 
| 233     wake_up_->Wait(static_cast<unsigned long>(time_to_wait)); | 241     wake_up_->Wait(static_cast<unsigned long>(time_to_wait)); | 
| 234 | 242 | 
| 235   return true; | 243   return true; | 
| 236 } | 244 } | 
| 237 }  // namespace webrtc | 245 }  // namespace webrtc | 
| OLD | NEW | 
|---|