1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "webrtc/common.h"
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "webrtc/voice_engine/channel_manager.h"
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
14b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org#include "webrtc/voice_engine/channel.h"
15b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org
16b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.orgnamespace webrtc {
17d54aa969545bd9c5ccc0077dd6645e742bf11418pbos@webrtc.orgnamespace voe {
18281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org
19281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.orgChannelOwner::ChannelOwner(class Channel* channel)
20281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org    : channel_ref_(new ChannelRef(channel)) {}
21281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org
22281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.orgChannelOwner::ChannelOwner(const ChannelOwner& channel_owner)
23281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org    : channel_ref_(channel_owner.channel_ref_) {
24281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org  ++channel_ref_->ref_count;
2524e2089750e9e51228b82d6c7ebf4fa064c797bapbos@webrtc.org}
26281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org
27281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.orgChannelOwner::~ChannelOwner() {
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (--channel_ref_->ref_count == 0)
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    delete channel_ref_;
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
31ac6d919eec548c708588f29923f617a17283c7e2andresp@webrtc.org
32bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.orgChannelOwner& ChannelOwner::operator=(const ChannelOwner& other) {
332e98d45e2455d3b48ceac1ad5457623d39802c9esprang@webrtc.org  if (other.channel_ref_ == channel_ref_)
345e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org    return *this;
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (--channel_ref_->ref_count == 0)
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    delete channel_ref_;
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  channel_ref_ = other.channel_ref_;
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ++channel_ref_->ref_count;
41bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org
425e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org  return *this;
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgChannelOwner::ChannelRef::ChannelRef(class Channel* channel)
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    : channel(channel), ref_count(1) {}
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgChannelManager::ChannelManager(uint32_t instance_id, const Config& config)
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    : instance_id_(instance_id),
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      last_channel_id_(-1),
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      lock_(CriticalSectionWrapper::CreateCriticalSection()),
525e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org      config_(config) {}
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
5467879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgChannelOwner ChannelManager::CreateChannel() {
5567879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org  return CreateChannelInternal(config_);
5667879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org}
57ac6d919eec548c708588f29923f617a17283c7e2andresp@webrtc.org
58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgChannelOwner ChannelManager::CreateChannel(const Config& external_config) {
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return CreateChannelInternal(external_config);
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgChannelOwner ChannelManager::CreateChannelInternal(const Config& config) {
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  Channel* channel;
64dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org  Channel::CreateChannel(channel, ++last_channel_id_, instance_id_, config);
65dca71b270896a8501d9f12506e7da48cde9abb20stefan@webrtc.org  ChannelOwner channel_owner(channel);
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  CriticalSectionScoped crit(lock_.get());
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  channels_.push_back(channel_owner);
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return channel_owner;
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
7467879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgChannelOwner ChannelManager::GetChannel(int32_t channel_id) {
7567879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org  CriticalSectionScoped crit(lock_.get());
7667879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org
7767879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org  for (size_t i = 0; i < channels_.size(); ++i) {
7867879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org    if (channels_[i].channel()->ChannelId() == channel_id)
7967879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org      return channels_[i];
8067879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org  }
8167879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org  return ChannelOwner(NULL);
8267879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org}
8367879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid ChannelManager::GetAllChannels(std::vector<ChannelOwner>* channels) {
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  CriticalSectionScoped crit(lock_.get());
86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
875e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org  *channels = channels_;
885e87b5f032780f6941a27c2d5068ab1e89e659a6pwestin@webrtc.org}
89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
9067879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgvoid ChannelManager::DestroyChannel(int32_t channel_id) {
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  assert(channel_id >= 0);
92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Holds a reference to a channel, this is used so that we never delete
93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Channels while holding a lock, but rather when the method returns.
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ChannelOwner reference(NULL);
95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  {
96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped crit(lock_.get());
973bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org
98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (std::vector<ChannelOwner>::iterator it = channels_.begin();
999cd0bbc6e184925752a04ed33ccbdc6e125e318ahenrike@webrtc.org         it != channels_.end();
1009cd0bbc6e184925752a04ed33ccbdc6e125e318ahenrike@webrtc.org         ++it) {
101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      if (it->channel()->ChannelId() == channel_id) {
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        reference = *it;
1039cd0bbc6e184925752a04ed33ccbdc6e125e318ahenrike@webrtc.org        channels_.erase(it);
104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        break;
1059cd0bbc6e184925752a04ed33ccbdc6e125e318ahenrike@webrtc.org      }
106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
10967879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org
11067879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgvoid ChannelManager::DestroyAllChannels() {
11167879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org  // Holds references so that Channels are not destroyed while holding this
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // lock, but rather when the method returns.
11355a2a27d1a1aa9bf8401312a0b31250af4e3bd11jiayl@webrtc.org  std::vector<ChannelOwner> references;
114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  {
11567879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org    CriticalSectionScoped crit(lock_.get());
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    references = channels_;
1177fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org    channels_.clear();
1187fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org  }
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
1209d6fcb37be4c9f49e1bb0b32bb01314c31f5e1ddmikhal@webrtc.org
1219d6fcb37be4c9f49e1bb0b32bb01314c31f5e1ddmikhal@webrtc.orgsize_t ChannelManager::NumOfChannels() const {
1220c66de6e75821a8e86fcbd166d725a5a859cab79mikhal@webrtc.org  CriticalSectionScoped crit(lock_.get());
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return channels_.size();
12467879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org}
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
12667879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgChannelManager::Iterator::Iterator(ChannelManager* channel_manager)
12767879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org    : iterator_pos_(0) {
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  channel_manager->GetAllChannels(&channels_);
12967879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org}
13067879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org
131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgChannel* ChannelManager::Iterator::GetChannel() {
1329cd0bbc6e184925752a04ed33ccbdc6e125e318ahenrike@webrtc.org  if (iterator_pos_ < channels_.size())
133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return channels_[iterator_pos_].channel();
134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return NULL;
135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool ChannelManager::Iterator::IsValid() {
13867879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org  return iterator_pos_ < channels_.size();
13967879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org}
1409cd0bbc6e184925752a04ed33ccbdc6e125e318ahenrike@webrtc.org
141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid ChannelManager::Iterator::Increment() {
142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ++iterator_pos_;
14367879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org}
1449cd0bbc6e184925752a04ed33ccbdc6e125e318ahenrike@webrtc.org
1459cd0bbc6e184925752a04ed33ccbdc6e125e318ahenrike@webrtc.org}  // namespace voe
14667879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org}  // namespace webrtc
147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org