git-svn-id: http://webrtc.googlecode.com/svn/trunk@156 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
194
src/modules/utility/source/process_thread_impl.cc
Normal file
194
src/modules/utility/source/process_thread_impl.cc
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "process_thread_impl.h"
|
||||
#include "module.h"
|
||||
#include "trace.h"
|
||||
|
||||
namespace webrtc {
|
||||
ProcessThread::~ProcessThread()
|
||||
{
|
||||
}
|
||||
|
||||
ProcessThread* ProcessThread::CreateProcessThread()
|
||||
{
|
||||
WEBRTC_TRACE(kTraceModuleCall, kTraceUtility, -1, "CreateProcessThread()");
|
||||
return new ProcessThreadImpl();
|
||||
}
|
||||
|
||||
void ProcessThread::DestroyProcessThread(ProcessThread* module)
|
||||
{
|
||||
WEBRTC_TRACE(kTraceModuleCall, kTraceUtility, -1, "DestroyProcessThread()");
|
||||
delete module;
|
||||
}
|
||||
|
||||
ProcessThreadImpl::ProcessThreadImpl()
|
||||
: _timeEvent(*EventWrapper::Create()),
|
||||
_critSectModules(*CriticalSectionWrapper::CreateCriticalSection()),
|
||||
_thread(NULL)
|
||||
{
|
||||
WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1, "%s created", __FUNCTION__);
|
||||
}
|
||||
|
||||
ProcessThreadImpl::~ProcessThreadImpl()
|
||||
{
|
||||
delete &_critSectModules;
|
||||
delete &_timeEvent;
|
||||
WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1, "%s deleted", __FUNCTION__);
|
||||
}
|
||||
|
||||
WebRtc_Word32 ProcessThreadImpl::Start()
|
||||
{
|
||||
CriticalSectionScoped lock(_critSectModules);
|
||||
if(_thread)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
_thread = ThreadWrapper::CreateThread(Run, this, kNormalPriority,
|
||||
"ProcessThread");
|
||||
unsigned int id;
|
||||
WebRtc_Word32 retVal = _thread->Start(id);
|
||||
if(retVal >= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
delete _thread;
|
||||
_thread = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
WebRtc_Word32 ProcessThreadImpl::Stop()
|
||||
{
|
||||
_critSectModules.Enter();
|
||||
if(_thread)
|
||||
{
|
||||
_thread->SetNotAlive();
|
||||
|
||||
ThreadWrapper* thread = _thread;
|
||||
_thread = NULL;
|
||||
|
||||
_timeEvent.Set();
|
||||
_critSectModules.Leave();
|
||||
|
||||
if(thread->Stop())
|
||||
{
|
||||
delete thread;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
_critSectModules.Leave();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
WebRtc_Word32 ProcessThreadImpl::RegisterModule(const Module* module)
|
||||
{
|
||||
WEBRTC_TRACE(kTraceModuleCall, kTraceUtility, -1,
|
||||
"RegisterModule(module:0x%x)", module);
|
||||
CriticalSectionScoped lock(_critSectModules);
|
||||
|
||||
// Only allow module to be registered once.
|
||||
ListItem* item = _modules.First();
|
||||
for(WebRtc_UWord32 i = 0; i < _modules.GetSize() && item; i++)
|
||||
{
|
||||
if(module == item->GetItem())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
item = _modules.Next(item);
|
||||
}
|
||||
|
||||
_modules.PushFront(module);
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceUtility, -1,
|
||||
"number of registered modules has increased to %d",
|
||||
_modules.GetSize());
|
||||
// Wake the thread calling ProcessThreadImpl::Process() to update the
|
||||
// waiting time. The waiting time for the just registered module may be
|
||||
// shorter than all other registered modules.
|
||||
_timeEvent.Set();
|
||||
return 0;
|
||||
}
|
||||
|
||||
WebRtc_Word32 ProcessThreadImpl::DeRegisterModule(const Module* module)
|
||||
{
|
||||
WEBRTC_TRACE(kTraceModuleCall, kTraceUtility, -1,
|
||||
"DeRegisterModule(module:0x%x)", module);
|
||||
CriticalSectionScoped lock(_critSectModules);
|
||||
|
||||
ListItem* item = _modules.First();
|
||||
for(WebRtc_UWord32 i = 0; i < _modules.GetSize() && item; i++)
|
||||
{
|
||||
if(module == item->GetItem())
|
||||
{
|
||||
int res = _modules.Erase(item);
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceUtility, -1,
|
||||
"number of registered modules has decreased to %d",
|
||||
_modules.GetSize());
|
||||
return res;
|
||||
}
|
||||
item = _modules.Next(item);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool ProcessThreadImpl::Run(void* obj)
|
||||
{
|
||||
return static_cast<ProcessThreadImpl*>(obj)->Process();
|
||||
}
|
||||
|
||||
bool ProcessThreadImpl::Process()
|
||||
{
|
||||
// Wait for the module that should be called next, but don't block thread
|
||||
// longer than 100 ms.
|
||||
WebRtc_Word32 minTimeToNext = 100;
|
||||
{
|
||||
CriticalSectionScoped lock(_critSectModules);
|
||||
ListItem* item = _modules.First();
|
||||
for(WebRtc_UWord32 i = 0; i < _modules.GetSize() && item; i++)
|
||||
{
|
||||
WebRtc_Word32 timeToNext =
|
||||
static_cast<Module*>(item->GetItem())->TimeUntilNextProcess();
|
||||
if(minTimeToNext > timeToNext)
|
||||
{
|
||||
minTimeToNext = timeToNext;
|
||||
}
|
||||
item = _modules.Next(item);
|
||||
}
|
||||
}
|
||||
|
||||
if(minTimeToNext > 0)
|
||||
{
|
||||
if(kEventError == _timeEvent.Wait(minTimeToNext))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if(!_thread)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
{
|
||||
CriticalSectionScoped lock(_critSectModules);
|
||||
ListItem* item = _modules.First();
|
||||
for(WebRtc_UWord32 i = 0; i < _modules.GetSize() && item; i++)
|
||||
{
|
||||
WebRtc_Word32 timeToNext =
|
||||
static_cast<Module*>(item->GetItem())->TimeUntilNextProcess();
|
||||
if(timeToNext < 1)
|
||||
{
|
||||
static_cast<Module*>(item->GetItem())->Process();
|
||||
}
|
||||
item = _modules.Next(item);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace webrtc
|
Reference in New Issue
Block a user