blob: ea9938f078a1ede2c2979e650bd09a4be75e8ab0 [file] [log] [blame]
/*
* Copyright (c) 2012 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 "channel_manager_base.h"
#include "critical_section_wrapper.h"
#include "rw_lock_wrapper.h"
#include <cassert>
namespace webrtc
{
namespace voe
{
ChannelManagerBase::ChannelManagerBase() :
_itemsCritSectPtr(CriticalSectionWrapper::CreateCriticalSection()),
_itemsRWLockPtr(RWLockWrapper::CreateRWLock())
{
for (int i = 0; i < KMaxNumberOfItems; i++)
{
_freeItemIds[i] = true;
}
}
ChannelManagerBase::~ChannelManagerBase()
{
if (_itemsRWLockPtr)
{
delete _itemsRWLockPtr;
_itemsRWLockPtr = NULL;
}
if (_itemsCritSectPtr)
{
delete _itemsCritSectPtr;
_itemsCritSectPtr = NULL;
}
}
bool ChannelManagerBase::GetFreeItemId(WebRtc_Word32& itemId)
{
CriticalSectionScoped cs(*_itemsCritSectPtr);
WebRtc_Word32 i(0);
while (i < KMaxNumberOfItems)
{
if (_freeItemIds[i])
{
itemId = i;
_freeItemIds[i] = false;
return true;
}
i++;
}
return false;
}
void ChannelManagerBase::AddFreeItemId(WebRtc_Word32 itemId)
{
assert(itemId < KMaxNumberOfItems);
_freeItemIds[itemId] = true;
}
void ChannelManagerBase::RemoveFreeItemIds()
{
for (int i = 0; i < KMaxNumberOfItems; i++)
{
_freeItemIds[i] = false;
}
}
bool ChannelManagerBase::CreateItem(WebRtc_Word32& itemId)
{
_itemsCritSectPtr->Enter();
void* itemPtr;
itemId = -1;
const bool success = GetFreeItemId(itemId);
if (!success)
{
_itemsCritSectPtr->Leave();
return false;
}
itemPtr = NewItem(itemId);
if (!itemPtr)
{
_itemsCritSectPtr->Leave();
return false;
}
_itemsCritSectPtr->Leave();
InsertItem(itemId, itemPtr);
return true;
}
void ChannelManagerBase::InsertItem(WebRtc_Word32 itemId, void* item)
{
CriticalSectionScoped cs(*_itemsCritSectPtr);
assert(!_items.Find(itemId));
_items.Insert(itemId, item);
}
void*
ChannelManagerBase::RemoveItem(WebRtc_Word32 itemId)
{
CriticalSectionScoped cs(*_itemsCritSectPtr);
WriteLockScoped wlock(*_itemsRWLockPtr);
MapItem* it = _items.Find(itemId);
if (!it)
{
return 0;
}
void* returnItem = it->GetItem();
_items.Erase(it);
AddFreeItemId(itemId);
return returnItem;
}
void ChannelManagerBase::DestroyAllItems()
{
CriticalSectionScoped cs(*_itemsCritSectPtr);
MapItem* it = _items.First();
while (it)
{
DeleteItem(it->GetItem());
_items.Erase(it);
it = _items.First();
}
RemoveFreeItemIds();
}
WebRtc_Word32 ChannelManagerBase::NumOfItems() const
{
return _items.Size();
}
WebRtc_Word32 ChannelManagerBase::MaxNumOfItems() const
{
return static_cast<WebRtc_Word32> (KMaxNumberOfItems);
}
void*
ChannelManagerBase::GetItem(WebRtc_Word32 itemId) const
{
CriticalSectionScoped cs(*_itemsCritSectPtr);
MapItem* it = _items.Find(itemId);
if (!it)
{
return 0;
}
_itemsRWLockPtr->AcquireLockShared();
return it->GetItem();
}
void*
ChannelManagerBase::GetFirstItem(void*& iterator) const
{
CriticalSectionScoped cs(*_itemsCritSectPtr);
MapItem* it = _items.First();
iterator = (void*) it;
if (!it)
{
return 0;
}
return it->GetItem();
}
void*
ChannelManagerBase::GetNextItem(void*& iterator) const
{
CriticalSectionScoped cs(*_itemsCritSectPtr);
MapItem* it = (MapItem*) iterator;
if (!it)
{
iterator = 0;
return 0;
}
it = _items.Next(it);
iterator = (void*) it;
if (!it)
{
return 0;
}
return it->GetItem();
}
void ChannelManagerBase::ReleaseItem()
{
_itemsRWLockPtr->ReleaseLockShared();
}
void ChannelManagerBase::GetItemIds(WebRtc_Word32* channelsArray,
WebRtc_Word32& numOfChannels) const
{
MapItem* it = _items.First();
numOfChannels = (numOfChannels <= _items.Size()) ?
numOfChannels : _items.Size();
for (int i = 0; i < numOfChannels && it != NULL; i++)
{
channelsArray[i] = it->GetId();
it = _items.Next(it);
}
}
void ChannelManagerBase::GetChannels(MapWrapper& channels) const
{
CriticalSectionScoped cs(*_itemsCritSectPtr);
if (_items.Size() == 0)
{
return;
}
_itemsRWLockPtr->AcquireLockShared();
for (MapItem* it = _items.First(); it != NULL; it = _items.Next(it))
{
channels.Insert(it->GetId(), it->GetItem());
}
}
} // namespace voe
} // namespace webrtc