blob: dd5c42cf4bea9bcecd214f6ced2d4f401910360b [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
xians@webrtc.org6bde7a82012-02-20 08:39:25 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
pbos@webrtc.org8b062002013-07-12 08:28:10 +000011#include "webrtc/modules/interface/module.h"
12#include "webrtc/modules/utility/source/process_thread_impl.h"
13#include "webrtc/system_wrappers/interface/trace.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000014
15namespace webrtc {
16ProcessThread::~ProcessThread()
17{
18}
19
20ProcessThread* ProcessThread::CreateProcessThread()
21{
niklase@google.com470e71d2011-07-07 08:21:25 +000022 return new ProcessThreadImpl();
23}
24
25void ProcessThread::DestroyProcessThread(ProcessThread* module)
26{
niklase@google.com470e71d2011-07-07 08:21:25 +000027 delete module;
28}
29
30ProcessThreadImpl::ProcessThreadImpl()
31 : _timeEvent(*EventWrapper::Create()),
henrike@webrtc.org105e0712011-12-16 19:53:46 +000032 _critSectModules(CriticalSectionWrapper::CreateCriticalSection()),
niklase@google.com470e71d2011-07-07 08:21:25 +000033 _thread(NULL)
34{
35 WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1, "%s created", __FUNCTION__);
36}
37
38ProcessThreadImpl::~ProcessThreadImpl()
39{
henrike@webrtc.org105e0712011-12-16 19:53:46 +000040 delete _critSectModules;
niklase@google.com470e71d2011-07-07 08:21:25 +000041 delete &_timeEvent;
42 WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1, "%s deleted", __FUNCTION__);
43}
44
pbos@webrtc.orgc75102e2013-04-09 13:32:55 +000045int32_t ProcessThreadImpl::Start()
niklase@google.com470e71d2011-07-07 08:21:25 +000046{
47 CriticalSectionScoped lock(_critSectModules);
48 if(_thread)
49 {
50 return -1;
51 }
52 _thread = ThreadWrapper::CreateThread(Run, this, kNormalPriority,
53 "ProcessThread");
54 unsigned int id;
pbos@webrtc.orgc75102e2013-04-09 13:32:55 +000055 int32_t retVal = _thread->Start(id);
niklase@google.com470e71d2011-07-07 08:21:25 +000056 if(retVal >= 0)
57 {
58 return 0;
59 }
60 delete _thread;
61 _thread = NULL;
62 return -1;
63}
64
pbos@webrtc.orgc75102e2013-04-09 13:32:55 +000065int32_t ProcessThreadImpl::Stop()
niklase@google.com470e71d2011-07-07 08:21:25 +000066{
henrike@webrtc.org105e0712011-12-16 19:53:46 +000067 _critSectModules->Enter();
niklase@google.com470e71d2011-07-07 08:21:25 +000068 if(_thread)
69 {
70 _thread->SetNotAlive();
71
72 ThreadWrapper* thread = _thread;
73 _thread = NULL;
74
75 _timeEvent.Set();
henrike@webrtc.org105e0712011-12-16 19:53:46 +000076 _critSectModules->Leave();
niklase@google.com470e71d2011-07-07 08:21:25 +000077
78 if(thread->Stop())
79 {
80 delete thread;
81 } else {
82 return -1;
83 }
84 } else {
henrike@webrtc.org105e0712011-12-16 19:53:46 +000085 _critSectModules->Leave();
niklase@google.com470e71d2011-07-07 08:21:25 +000086 }
87 return 0;
88}
89
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +000090int32_t ProcessThreadImpl::RegisterModule(Module* module)
niklase@google.com470e71d2011-07-07 08:21:25 +000091{
niklase@google.com470e71d2011-07-07 08:21:25 +000092 CriticalSectionScoped lock(_critSectModules);
93
94 // Only allow module to be registered once.
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +000095 for (ModuleList::iterator iter = _modules.begin();
96 iter != _modules.end(); ++iter) {
97 if(module == *iter)
niklase@google.com470e71d2011-07-07 08:21:25 +000098 {
99 return -1;
100 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000101 }
102
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +0000103 _modules.push_front(module);
niklase@google.com470e71d2011-07-07 08:21:25 +0000104 WEBRTC_TRACE(kTraceInfo, kTraceUtility, -1,
105 "number of registered modules has increased to %d",
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +0000106 _modules.size());
niklase@google.com470e71d2011-07-07 08:21:25 +0000107 // Wake the thread calling ProcessThreadImpl::Process() to update the
108 // waiting time. The waiting time for the just registered module may be
109 // shorter than all other registered modules.
110 _timeEvent.Set();
111 return 0;
112}
113
pbos@webrtc.orgc75102e2013-04-09 13:32:55 +0000114int32_t ProcessThreadImpl::DeRegisterModule(const Module* module)
niklase@google.com470e71d2011-07-07 08:21:25 +0000115{
niklase@google.com470e71d2011-07-07 08:21:25 +0000116 CriticalSectionScoped lock(_critSectModules);
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +0000117 for (ModuleList::iterator iter = _modules.begin();
118 iter != _modules.end(); ++iter) {
119 if(module == *iter)
niklase@google.com470e71d2011-07-07 08:21:25 +0000120 {
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +0000121 _modules.erase(iter);
niklase@google.com470e71d2011-07-07 08:21:25 +0000122 WEBRTC_TRACE(kTraceInfo, kTraceUtility, -1,
123 "number of registered modules has decreased to %d",
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +0000124 _modules.size());
125 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000126 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000127 }
128 return -1;
129}
130
131bool ProcessThreadImpl::Run(void* obj)
132{
133 return static_cast<ProcessThreadImpl*>(obj)->Process();
134}
135
136bool ProcessThreadImpl::Process()
137{
138 // Wait for the module that should be called next, but don't block thread
139 // longer than 100 ms.
pbos@webrtc.orgc75102e2013-04-09 13:32:55 +0000140 int32_t minTimeToNext = 100;
niklase@google.com470e71d2011-07-07 08:21:25 +0000141 {
142 CriticalSectionScoped lock(_critSectModules);
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +0000143 for (ModuleList::iterator iter = _modules.begin();
144 iter != _modules.end(); ++iter) {
145 int32_t timeToNext = (*iter)->TimeUntilNextProcess();
niklase@google.com470e71d2011-07-07 08:21:25 +0000146 if(minTimeToNext > timeToNext)
147 {
148 minTimeToNext = timeToNext;
149 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000150 }
151 }
152
153 if(minTimeToNext > 0)
154 {
155 if(kEventError == _timeEvent.Wait(minTimeToNext))
156 {
157 return true;
158 }
henrika@webrtc.org4ff956f2013-04-02 11:59:11 +0000159 CriticalSectionScoped lock(_critSectModules);
niklase@google.com470e71d2011-07-07 08:21:25 +0000160 if(!_thread)
161 {
162 return false;
163 }
164 }
165 {
166 CriticalSectionScoped lock(_critSectModules);
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +0000167 for (ModuleList::iterator iter = _modules.begin();
168 iter != _modules.end(); ++iter) {
169 int32_t timeToNext = (*iter)->TimeUntilNextProcess();
niklase@google.com470e71d2011-07-07 08:21:25 +0000170 if(timeToNext < 1)
171 {
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +0000172 (*iter)->Process();
niklase@google.com470e71d2011-07-07 08:21:25 +0000173 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000174 }
175 }
176 return true;
177}
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000178} // namespace webrtc