blob: 500101ce17b883ef3a2fdb47b539d499c30008e9 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
xians@webrtc.org79af7342012-01-31 12:22:14 +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
11#include "channel_manager_base.h"
12
13#include "critical_section_wrapper.h"
14#include "rw_lock_wrapper.h"
15#include <cassert>
16
17namespace webrtc
18{
19
20namespace voe
21{
22
23ChannelManagerBase::ChannelManagerBase() :
24 _itemsCritSectPtr(CriticalSectionWrapper::CreateCriticalSection()),
25 _itemsRWLockPtr(RWLockWrapper::CreateRWLock())
26{
andrew@webrtc.org4a6f62d2013-02-01 23:42:44 +000027 for (int i = 0; i < kVoiceEngineMaxNumChannels; i++)
niklase@google.com470e71d2011-07-07 08:21:25 +000028 {
29 _freeItemIds[i] = true;
30 }
31}
32
33ChannelManagerBase::~ChannelManagerBase()
34{
35 if (_itemsRWLockPtr)
36 {
37 delete _itemsRWLockPtr;
38 _itemsRWLockPtr = NULL;
39 }
40 if (_itemsCritSectPtr)
41 {
42 delete _itemsCritSectPtr;
43 _itemsCritSectPtr = NULL;
44 }
45}
46
pbos@webrtc.org6141e132013-04-09 10:09:10 +000047bool ChannelManagerBase::GetFreeItemId(int32_t& itemId)
niklase@google.com470e71d2011-07-07 08:21:25 +000048{
mflodman@webrtc.org9a065d12012-03-07 08:12:21 +000049 CriticalSectionScoped cs(_itemsCritSectPtr);
pbos@webrtc.org6141e132013-04-09 10:09:10 +000050 int32_t i(0);
andrew@webrtc.org4a6f62d2013-02-01 23:42:44 +000051 while (i < kVoiceEngineMaxNumChannels)
niklase@google.com470e71d2011-07-07 08:21:25 +000052 {
53 if (_freeItemIds[i])
54 {
55 itemId = i;
56 _freeItemIds[i] = false;
57 return true;
58 }
59 i++;
60 }
61 return false;
62}
63
pbos@webrtc.org6141e132013-04-09 10:09:10 +000064void ChannelManagerBase::AddFreeItemId(int32_t itemId)
niklase@google.com470e71d2011-07-07 08:21:25 +000065{
andrew@webrtc.org4a6f62d2013-02-01 23:42:44 +000066 assert(itemId < kVoiceEngineMaxNumChannels);
niklase@google.com470e71d2011-07-07 08:21:25 +000067 _freeItemIds[itemId] = true;
68}
69
70void ChannelManagerBase::RemoveFreeItemIds()
71{
andrew@webrtc.org4a6f62d2013-02-01 23:42:44 +000072 for (int i = 0; i < kVoiceEngineMaxNumChannels; i++)
niklase@google.com470e71d2011-07-07 08:21:25 +000073 {
74 _freeItemIds[i] = false;
75 }
76}
77
pbos@webrtc.org6141e132013-04-09 10:09:10 +000078bool ChannelManagerBase::CreateItem(int32_t& itemId)
niklase@google.com470e71d2011-07-07 08:21:25 +000079{
80 _itemsCritSectPtr->Enter();
81 void* itemPtr;
82 itemId = -1;
83 const bool success = GetFreeItemId(itemId);
84 if (!success)
85 {
86 _itemsCritSectPtr->Leave();
87 return false;
88 }
89 itemPtr = NewItem(itemId);
90 if (!itemPtr)
91 {
92 _itemsCritSectPtr->Leave();
93 return false;
94 }
95 _itemsCritSectPtr->Leave();
96 InsertItem(itemId, itemPtr);
97
98 return true;
99}
100
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000101void ChannelManagerBase::InsertItem(int32_t itemId, void* item)
niklase@google.com470e71d2011-07-07 08:21:25 +0000102{
mflodman@webrtc.org9a065d12012-03-07 08:12:21 +0000103 CriticalSectionScoped cs(_itemsCritSectPtr);
niklase@google.com470e71d2011-07-07 08:21:25 +0000104 assert(!_items.Find(itemId));
105 _items.Insert(itemId, item);
106}
107
108void*
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000109ChannelManagerBase::RemoveItem(int32_t itemId)
niklase@google.com470e71d2011-07-07 08:21:25 +0000110{
mflodman@webrtc.org9a065d12012-03-07 08:12:21 +0000111 CriticalSectionScoped cs(_itemsCritSectPtr);
niklase@google.com470e71d2011-07-07 08:21:25 +0000112 WriteLockScoped wlock(*_itemsRWLockPtr);
113 MapItem* it = _items.Find(itemId);
114 if (!it)
115 {
116 return 0;
117 }
118 void* returnItem = it->GetItem();
119 _items.Erase(it);
120 AddFreeItemId(itemId);
121
122 return returnItem;
123}
124
125void ChannelManagerBase::DestroyAllItems()
126{
mflodman@webrtc.org9a065d12012-03-07 08:12:21 +0000127 CriticalSectionScoped cs(_itemsCritSectPtr);
niklase@google.com470e71d2011-07-07 08:21:25 +0000128 MapItem* it = _items.First();
129 while (it)
130 {
131 DeleteItem(it->GetItem());
132 _items.Erase(it);
133 it = _items.First();
134 }
135 RemoveFreeItemIds();
136}
137
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000138int32_t ChannelManagerBase::NumOfItems() const
niklase@google.com470e71d2011-07-07 08:21:25 +0000139{
140 return _items.Size();
141}
142
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000143int32_t ChannelManagerBase::MaxNumOfItems() const
niklase@google.com470e71d2011-07-07 08:21:25 +0000144{
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000145 return static_cast<int32_t> (kVoiceEngineMaxNumChannels);
niklase@google.com470e71d2011-07-07 08:21:25 +0000146}
147
148void*
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000149ChannelManagerBase::GetItem(int32_t itemId) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000150{
mflodman@webrtc.org9a065d12012-03-07 08:12:21 +0000151 CriticalSectionScoped cs(_itemsCritSectPtr);
niklase@google.com470e71d2011-07-07 08:21:25 +0000152 MapItem* it = _items.Find(itemId);
153 if (!it)
154 {
155 return 0;
156 }
157 _itemsRWLockPtr->AcquireLockShared();
158 return it->GetItem();
159}
160
161void*
162ChannelManagerBase::GetFirstItem(void*& iterator) const
163{
mflodman@webrtc.org9a065d12012-03-07 08:12:21 +0000164 CriticalSectionScoped cs(_itemsCritSectPtr);
niklase@google.com470e71d2011-07-07 08:21:25 +0000165 MapItem* it = _items.First();
166 iterator = (void*) it;
167 if (!it)
168 {
169 return 0;
170 }
171 return it->GetItem();
172}
173
174void*
175ChannelManagerBase::GetNextItem(void*& iterator) const
176{
mflodman@webrtc.org9a065d12012-03-07 08:12:21 +0000177 CriticalSectionScoped cs(_itemsCritSectPtr);
niklase@google.com470e71d2011-07-07 08:21:25 +0000178 MapItem* it = (MapItem*) iterator;
179 if (!it)
180 {
181 iterator = 0;
182 return 0;
183 }
184 it = _items.Next(it);
185 iterator = (void*) it;
186 if (!it)
187 {
188 return 0;
189 }
190 return it->GetItem();
191}
192
193void ChannelManagerBase::ReleaseItem()
194{
195 _itemsRWLockPtr->ReleaseLockShared();
196}
197
pbos@webrtc.org6141e132013-04-09 10:09:10 +0000198void ChannelManagerBase::GetItemIds(int32_t* channelsArray,
199 int32_t& numOfChannels) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000200{
201 MapItem* it = _items.First();
202 numOfChannels = (numOfChannels <= _items.Size()) ?
203 numOfChannels : _items.Size();
xians@webrtc.org79af7342012-01-31 12:22:14 +0000204 for (int i = 0; i < numOfChannels && it != NULL; i++)
niklase@google.com470e71d2011-07-07 08:21:25 +0000205 {
206 channelsArray[i] = it->GetId();
207 it = _items.Next(it);
208 }
209}
210
211void ChannelManagerBase::GetChannels(MapWrapper& channels) const
212{
mflodman@webrtc.org9a065d12012-03-07 08:12:21 +0000213 CriticalSectionScoped cs(_itemsCritSectPtr);
niklase@google.com470e71d2011-07-07 08:21:25 +0000214 if (_items.Size() == 0)
215 {
216 return;
217 }
218 _itemsRWLockPtr->AcquireLockShared();
219 for (MapItem* it = _items.First(); it != NULL; it = _items.Next(it))
220 {
221 channels.Insert(it->GetId(), it->GetItem());
222 }
223}
224
225} // namespace voe
226
227} // namespace webrtc