blob: e2e9542c754d58c588a32ded5a368cd1aa91febb [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 {
niklase@google.com470e71d2011-07-07 08:21:25 +000068 ThreadWrapper* thread = _thread;
69 _thread = NULL;
70
71 _timeEvent.Set();
henrike@webrtc.org105e0712011-12-16 19:53:46 +000072 _critSectModules->Leave();
niklase@google.com470e71d2011-07-07 08:21:25 +000073
74 if(thread->Stop())
75 {
76 delete thread;
77 } else {
78 return -1;
79 }
80 } else {
henrike@webrtc.org105e0712011-12-16 19:53:46 +000081 _critSectModules->Leave();
niklase@google.com470e71d2011-07-07 08:21:25 +000082 }
83 return 0;
84}
85
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +000086int32_t ProcessThreadImpl::RegisterModule(Module* module)
niklase@google.com470e71d2011-07-07 08:21:25 +000087{
niklase@google.com470e71d2011-07-07 08:21:25 +000088 CriticalSectionScoped lock(_critSectModules);
89
90 // Only allow module to be registered once.
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +000091 for (ModuleList::iterator iter = _modules.begin();
92 iter != _modules.end(); ++iter) {
93 if(module == *iter)
niklase@google.com470e71d2011-07-07 08:21:25 +000094 {
95 return -1;
96 }
niklase@google.com470e71d2011-07-07 08:21:25 +000097 }
98
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +000099 _modules.push_front(module);
asapersson@webrtc.org8b2ec152014-04-11 07:59:43 +0000100
niklase@google.com470e71d2011-07-07 08:21:25 +0000101 // Wake the thread calling ProcessThreadImpl::Process() to update the
102 // waiting time. The waiting time for the just registered module may be
103 // shorter than all other registered modules.
104 _timeEvent.Set();
105 return 0;
106}
107
pbos@webrtc.orgc75102e2013-04-09 13:32:55 +0000108int32_t ProcessThreadImpl::DeRegisterModule(const Module* module)
niklase@google.com470e71d2011-07-07 08:21:25 +0000109{
niklase@google.com470e71d2011-07-07 08:21:25 +0000110 CriticalSectionScoped lock(_critSectModules);
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +0000111 for (ModuleList::iterator iter = _modules.begin();
112 iter != _modules.end(); ++iter) {
113 if(module == *iter)
niklase@google.com470e71d2011-07-07 08:21:25 +0000114 {
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +0000115 _modules.erase(iter);
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +0000116 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000117 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000118 }
119 return -1;
120}
121
122bool ProcessThreadImpl::Run(void* obj)
123{
124 return static_cast<ProcessThreadImpl*>(obj)->Process();
125}
126
127bool ProcessThreadImpl::Process()
128{
129 // Wait for the module that should be called next, but don't block thread
130 // longer than 100 ms.
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +0000131 int64_t minTimeToNext = 100;
niklase@google.com470e71d2011-07-07 08:21:25 +0000132 {
133 CriticalSectionScoped lock(_critSectModules);
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +0000134 for (ModuleList::iterator iter = _modules.begin();
135 iter != _modules.end(); ++iter) {
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +0000136 int64_t timeToNext = (*iter)->TimeUntilNextProcess();
niklase@google.com470e71d2011-07-07 08:21:25 +0000137 if(minTimeToNext > timeToNext)
138 {
139 minTimeToNext = timeToNext;
140 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000141 }
142 }
143
144 if(minTimeToNext > 0)
145 {
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +0000146 if(kEventError ==
147 _timeEvent.Wait(static_cast<unsigned long>(minTimeToNext)))
niklase@google.com470e71d2011-07-07 08:21:25 +0000148 {
149 return true;
150 }
henrika@webrtc.org4ff956f2013-04-02 11:59:11 +0000151 CriticalSectionScoped lock(_critSectModules);
niklase@google.com470e71d2011-07-07 08:21:25 +0000152 if(!_thread)
153 {
154 return false;
155 }
156 }
157 {
158 CriticalSectionScoped lock(_critSectModules);
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +0000159 for (ModuleList::iterator iter = _modules.begin();
160 iter != _modules.end(); ++iter) {
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +0000161 int64_t timeToNext = (*iter)->TimeUntilNextProcess();
niklase@google.com470e71d2011-07-07 08:21:25 +0000162 if(timeToNext < 1)
163 {
henrike@webrtc.org79cf3ac2014-01-13 15:21:30 +0000164 (*iter)->Process();
niklase@google.com470e71d2011-07-07 08:21:25 +0000165 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000166 }
167 }
168 return true;
169}
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +0000170} // namespace webrtc