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