Home | History | Annotate | Download | only in voice_engine
      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 
     16 namespace webrtc {
     17 namespace voe {
     18 
     19 ChannelOwner::ChannelOwner(class Channel* channel)
     20     : channel_ref_(new ChannelRef(channel)) {}
     21 
     22 ChannelOwner::ChannelOwner(const ChannelOwner& channel_owner)
     23     : channel_ref_(channel_owner.channel_ref_) {
     24   ++channel_ref_->ref_count;
     25 }
     26 
     27 ChannelOwner::~ChannelOwner() {
     28   if (--channel_ref_->ref_count == 0)
     29     delete channel_ref_;
     30 }
     31 
     32 ChannelOwner& 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 
     45 ChannelOwner::ChannelRef::ChannelRef(class Channel* channel)
     46     : channel(channel), ref_count(1) {}
     47 
     48 ChannelManager::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 
     54 ChannelOwner ChannelManager::CreateChannel() {
     55   return CreateChannelInternal(config_);
     56 }
     57 
     58 ChannelOwner ChannelManager::CreateChannel(const Config& external_config) {
     59   return CreateChannelInternal(external_config);
     60 }
     61 
     62 ChannelOwner 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 
     74 ChannelOwner 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 
     84 void ChannelManager::GetAllChannels(std::vector<ChannelOwner>* channels) {
     85   CriticalSectionScoped crit(lock_.get());
     86 
     87   *channels = channels_;
     88 }
     89 
     90 void 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 
    110 void 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 
    121 size_t ChannelManager::NumOfChannels() const {
    122   CriticalSectionScoped crit(lock_.get());
    123   return channels_.size();
    124 }
    125 
    126 ChannelManager::Iterator::Iterator(ChannelManager* channel_manager)
    127     : iterator_pos_(0) {
    128   channel_manager->GetAllChannels(&channels_);
    129 }
    130 
    131 Channel* ChannelManager::Iterator::GetChannel() {
    132   if (iterator_pos_ < channels_.size())
    133     return channels_[iterator_pos_].channel();
    134   return NULL;
    135 }
    136 
    137 bool ChannelManager::Iterator::IsValid() {
    138   return iterator_pos_ < channels_.size();
    139 }
    140 
    141 void ChannelManager::Iterator::Increment() {
    142   ++iterator_pos_;
    143 }
    144 
    145 }  // namespace voe
    146 }  // namespace webrtc
    147