blob: bf7db3bc846be40ab5f29f5377317a0f3062a442 [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"
asapersson@webrtc.org8b2ec152014-04-11 07:59:43 +000013
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{
niklase@google.com470e71d2011-07-07 08:21:25 +000035}
36
37ProcessThreadImpl::~ProcessThreadImpl()
38{
henrike@webrtc.org105e0712011-12-16 19:53:46 +000039 delete _critSectModules;
niklase@google.com470e71d2011-07-07 08:21:25 +000040 delete &_timeEvent;
niklase@google.com470e71d2011-07-07 08:21:25 +000041}
42
pbos@webrtc.orgc75102e2013-04-09 13:32:55 +000043int32_t ProcessThreadImpl::Start()
niklase@google.com470e71d2011-07-07 08:21:25 +000044{
45 CriticalSectionScoped lock(_critSectModules);
46 if(_thread)
47 {
48 return -1;
49 }
50 _thread = ThreadWrapper::CreateThread(Run, this, kNormalPriority,
51 "ProcessThread");
52 unsigned int id;
pbos@webrtc.orgc75102e2013-04-09 13:32:55 +000053 int32_t retVal = _thread->Start(id);
niklase@google.com470e71d2011-07-07 08:21:25 +000054 if(retVal >= 0)
55 {
56 return 0;
57 }
58 delete _thread;
59 _thread = NULL;
60 return -1;
61}
62
pbos@webrtc.orgc75102e2013-04-09 13:32:55 +000063int32_t ProcessThreadImpl::Stop()
niklase@google.com470e71d2011-07-07 08:21:25 +000064{
henrike@webrtc.org105e0712011-12-16 19:53:46 +000065 _critSectModules->Enter();
niklase@google.com470e71d2011-07-07 08:21:25 +000066 if(_thread)
67 {
68 _thread->SetNotAlive();
69
70 ThreadWrapper* thread = _thread;
71 _thread = NULL;
72
73 _timeEvent.Set();
henrike@webrtc.org105e0712011-12-16 19:53:46 +000074 _critSectModules->Leave();
niklase@google.com470e71d2011-07-07 08:21:25 +000075
76 if(thread->Stop())
77 {
78 delete thread;
79 } else {
80 return -1;
81 }
82 } else {
henrike@webrtc.org105e0712011-12-16 19:53:46 +000083 _critSectModules->Leave();
niklase@google.com470e71d2011-07-07 08:21:25 +000084 }
85 return 0;
86}
87
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +000088int32_t ProcessThreadImpl::RegisterModule(Module* module)
niklase@google.com470e71d2011-07-07 08:21:25 +000089{
niklase@google.com470e71d2011-07-07 08:21:25 +000090 CriticalSectionScoped lock(_critSectModules);
91
92 // Only allow module to be registered once.
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +000093 for (ModuleList::iterator iter = _modules.begin();
94 iter != _modules.end(); ++iter) {
95 if(module == *iter)
niklase@google.com470e71d2011-07-07 08:21:25 +000096 {
97 return -1;
98 }
niklase@google.com470e71d2011-07-07 08:21:25 +000099 }
100
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +0000101 _modules.push_front(module);
asapersson@webrtc.org8b2ec152014-04-11 07:59:43 +0000102
niklase@google.com470e71d2011-07-07 08:21:25 +0000103 // Wake the thread calling ProcessThreadImpl::Process() to update the
104 // waiting time. The waiting time for the just registered module may be
105 // shorter than all other registered modules.
106 _timeEvent.Set();
107 return 0;
108}
109
pbos@webrtc.orgc75102e2013-04-09 13:32:55 +0000110int32_t ProcessThreadImpl::DeRegisterModule(const Module* module)
niklase@google.com470e71d2011-07-07 08:21:25 +0000111{
niklase@google.com470e71d2011-07-07 08:21:25 +0000112 CriticalSectionScoped lock(_critSectModules);
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +0000113 for (ModuleList::iterator iter = _modules.begin();
114 iter != _modules.end(); ++iter) {
115 if(module == *iter)
niklase@google.com470e71d2011-07-07 08:21:25 +0000116 {
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +0000117 _modules.erase(iter);
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +0000118 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000119 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000120 }
121 return -1;
122}
123
124bool ProcessThreadImpl::Run(void* obj)
125{
126 return static_cast<ProcessThreadImpl*>(obj)->Process();
127}
128
129bool ProcessThreadImpl::Process()
130{
131 // Wait for the module that should be called next, but don't block thread
132 // longer than 100 ms.
pbos@webrtc.orgc75102e2013-04-09 13:32:55 +0000133 int32_t minTimeToNext = 100;
niklase@google.com470e71d2011-07-07 08:21:25 +0000134 {
135 CriticalSectionScoped lock(_critSectModules);
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +0000136 for (ModuleList::iterator iter = _modules.begin();
137 iter != _modules.end(); ++iter) {
138 int32_t timeToNext = (*iter)->TimeUntilNextProcess();
niklase@google.com470e71d2011-07-07 08:21:25 +0000139 if(minTimeToNext > timeToNext)
140 {
141 minTimeToNext = timeToNext;
142 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000143 }
144 }
145
146 if(minTimeToNext > 0)
147 {
148 if(kEventError == _timeEvent.Wait(minTimeToNext))
149 {
150 return true;
151 }
henrika@webrtc.org4ff956f2013-04-02 11:59:11 +0000152 CriticalSectionScoped lock(_critSectModules);
niklase@google.com470e71d2011-07-07 08:21:25 +0000153 if(!_thread)
154 {
155 return false;
156 }
157 }
158 {
159 CriticalSectionScoped lock(_critSectModules);
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +0000160 for (ModuleList::iterator iter = _modules.begin();
161 iter != _modules.end(); ++iter) {
162 int32_t timeToNext = (*iter)->TimeUntilNextProcess();
niklase@google.com470e71d2011-07-07 08:21:25 +0000163 if(timeToNext < 1)
164 {
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +0000165 (*iter)->Process();
niklase@google.com470e71d2011-07-07 08:21:25 +0000166 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000167 }
168 }
169 return true;
170}
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000171} // namespace webrtc