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
11b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org#include "webrtc/common.h"
12471ae72f18e7b23a96b245dbd508386fe139449cpbos@webrtc.org#include "webrtc/voice_engine/channel_manager.h"
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
14b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org#include "webrtc/voice_engine/channel.h"
15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
16b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.orgnamespace webrtc {
17b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.orgnamespace voe {
18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
19b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.orgChannelOwner::ChannelOwner(class Channel* channel)
20b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    : channel_ref_(new ChannelRef(channel)) {}
21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
22b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.orgChannelOwner::ChannelOwner(const ChannelOwner& channel_owner)
23b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    : channel_ref_(channel_owner.channel_ref_) {
24b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  ++channel_ref_->ref_count;
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
27b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.orgChannelOwner::~ChannelOwner() {
28b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  if (--channel_ref_->ref_count == 0)
29b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    delete channel_ref_;
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
32b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.orgChannelOwner& ChannelOwner::operator=(const ChannelOwner& other) {
33b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  if (other.channel_ref_ == channel_ref_)
34b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    return *this;
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
36b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  if (--channel_ref_->ref_count == 0)
37b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    delete channel_ref_;
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
39b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  channel_ref_ = other.channel_ref_;
40b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  ++channel_ref_->ref_count;
41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
42b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  return *this;
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
45b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.orgChannelOwner::ChannelRef::ChannelRef(class Channel* channel)
46b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    : channel(channel), ref_count(1) {}
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
484489c51faaf5b7e9f8845c5fb661f6ae91f7da48minyue@webrtc.orgChannelManager::ChannelManager(uint32_t instance_id, const Config& config)
49b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    : instance_id_(instance_id),
50b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org      last_channel_id_(-1),
514489c51faaf5b7e9f8845c5fb661f6ae91f7da48minyue@webrtc.org      lock_(CriticalSectionWrapper::CreateCriticalSection()),
524489c51faaf5b7e9f8845c5fb661f6ae91f7da48minyue@webrtc.org      config_(config) {}
53b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org
54b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.orgChannelOwner ChannelManager::CreateChannel() {
55b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org  return CreateChannelInternal(config_);
56b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org}
57b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org
58b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.orgChannelOwner ChannelManager::CreateChannel(const Config& external_config) {
59b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org  return CreateChannelInternal(external_config);
60b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org}
61b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org
62b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.orgChannelOwner ChannelManager::CreateChannelInternal(const Config& config) {
63b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  Channel* channel;
64b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org  Channel::CreateChannel(channel, ++last_channel_id_, instance_id_, config);
65b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  ChannelOwner channel_owner(channel);
66b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org
67b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  CriticalSectionScoped crit(lock_.get());
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
69b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  channels_.push_back(channel_owner);
70b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org
71b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  return channel_owner;
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
74b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.orgChannelOwner ChannelManager::GetChannel(int32_t channel_id) {
75b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  CriticalSectionScoped crit(lock_.get());
76b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org
77b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  for (size_t i = 0; i < channels_.size(); ++i) {
78b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    if (channels_[i].channel()->ChannelId() == channel_id)
79b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org      return channels_[i];
80b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  }
81b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  return ChannelOwner(NULL);
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
84b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.orgvoid ChannelManager::GetAllChannels(std::vector<ChannelOwner>* channels) {
85b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  CriticalSectionScoped crit(lock_.get());
86b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org
87b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  *channels = channels_;
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
90b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.orgvoid ChannelManager::DestroyChannel(int32_t channel_id) {
91b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  assert(channel_id >= 0);
92a4a1afa4dd9e34e7c3e17d1048b0d49df03a36a0pbos@webrtc.org  // Holds a reference to a channel, this is used so that we never delete
93a4a1afa4dd9e34e7c3e17d1048b0d49df03a36a0pbos@webrtc.org  // Channels while holding a lock, but rather when the method returns.
94a4a1afa4dd9e34e7c3e17d1048b0d49df03a36a0pbos@webrtc.org  ChannelOwner reference(NULL);
95a4a1afa4dd9e34e7c3e17d1048b0d49df03a36a0pbos@webrtc.org  {
96a4a1afa4dd9e34e7c3e17d1048b0d49df03a36a0pbos@webrtc.org    CriticalSectionScoped crit(lock_.get());
97a4a1afa4dd9e34e7c3e17d1048b0d49df03a36a0pbos@webrtc.org
98a4a1afa4dd9e34e7c3e17d1048b0d49df03a36a0pbos@webrtc.org    for (std::vector<ChannelOwner>::iterator it = channels_.begin();
99a4a1afa4dd9e34e7c3e17d1048b0d49df03a36a0pbos@webrtc.org         it != channels_.end();
100a4a1afa4dd9e34e7c3e17d1048b0d49df03a36a0pbos@webrtc.org         ++it) {
101a4a1afa4dd9e34e7c3e17d1048b0d49df03a36a0pbos@webrtc.org      if (it->channel()->ChannelId() == channel_id) {
102a4a1afa4dd9e34e7c3e17d1048b0d49df03a36a0pbos@webrtc.org        reference = *it;
103a4a1afa4dd9e34e7c3e17d1048b0d49df03a36a0pbos@webrtc.org        channels_.erase(it);
104a4a1afa4dd9e34e7c3e17d1048b0d49df03a36a0pbos@webrtc.org        break;
105a4a1afa4dd9e34e7c3e17d1048b0d49df03a36a0pbos@webrtc.org      }
106b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    }
107b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  }
108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
110b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.orgvoid ChannelManager::DestroyAllChannels() {
111a4a1afa4dd9e34e7c3e17d1048b0d49df03a36a0pbos@webrtc.org  // Holds references so that Channels are not destroyed while holding this
112a4a1afa4dd9e34e7c3e17d1048b0d49df03a36a0pbos@webrtc.org  // lock, but rather when the method returns.
113a4a1afa4dd9e34e7c3e17d1048b0d49df03a36a0pbos@webrtc.org  std::vector<ChannelOwner> references;
114a4a1afa4dd9e34e7c3e17d1048b0d49df03a36a0pbos@webrtc.org  {
115a4a1afa4dd9e34e7c3e17d1048b0d49df03a36a0pbos@webrtc.org    CriticalSectionScoped crit(lock_.get());
116a4a1afa4dd9e34e7c3e17d1048b0d49df03a36a0pbos@webrtc.org    references = channels_;
117a4a1afa4dd9e34e7c3e17d1048b0d49df03a36a0pbos@webrtc.org    channels_.clear();
118a4a1afa4dd9e34e7c3e17d1048b0d49df03a36a0pbos@webrtc.org  }
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
121b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.orgsize_t ChannelManager::NumOfChannels() const {
122b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  CriticalSectionScoped crit(lock_.get());
123b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  return channels_.size();
124b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org}
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
126b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.orgChannelManager::Iterator::Iterator(ChannelManager* channel_manager)
127b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    : iterator_pos_(0) {
128b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  channel_manager->GetAllChannels(&channels_);
129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
131b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.orgChannel* ChannelManager::Iterator::GetChannel() {
132b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  if (iterator_pos_ < channels_.size())
133b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    return channels_[iterator_pos_].channel();
134b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  return NULL;
135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
137b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.orgbool ChannelManager::Iterator::IsValid() {
138b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  return iterator_pos_ < channels_.size();
139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
141b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.orgvoid ChannelManager::Iterator::Increment() {
142b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  ++iterator_pos_;
143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1453b89e10f31160da35b408fd00cb8f89d2b08862dpbos@webrtc.org}  // namespace voe
1463b89e10f31160da35b408fd00cb8f89d2b08862dpbos@webrtc.org}  // namespace webrtc
147