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#ifndef WEBRTC_VOICE_ENGINE_CHANNEL_MANAGER_H
12#define WEBRTC_VOICE_ENGINE_CHANNEL_MANAGER_H
13
14#include <vector>
15
16#include "webrtc/base/constructormagic.h"
17#include "webrtc/system_wrappers/interface/atomic32.h"
18#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
19#include "webrtc/system_wrappers/interface/scoped_ptr.h"
20#include "webrtc/typedefs.h"
21
22namespace webrtc {
23
24class Config;
25
26namespace voe {
27
28class Channel;
29
30// Shared-pointer implementation for keeping track of Channels. The underlying
31// shared instance will be dropped when no more ChannelOwners point to it.
32//
33// One common source of ChannelOwner instances are
34// ChannelManager::CreateChannel() and ChannelManager::GetChannel(...).
35// It has a similar use case to shared_ptr in C++11. Should this move to C++11
36// in the future, this class should be replaced by exactly that.
37//
38// To access the underlying Channel, use .channel().
39// IsValid() implements a convenience method as an alternative for checking
40// whether the underlying pointer is NULL or not.
41//
42// Channel channel_owner = channel_manager.GetChannel(channel_id);
43// if (channel_owner.IsValid())
44//   channel_owner.channel()->...;
45//
46class ChannelOwner {
47 public:
48  explicit ChannelOwner(Channel* channel);
49  ChannelOwner(const ChannelOwner& channel_owner);
50
51  ~ChannelOwner();
52
53  ChannelOwner& operator=(const ChannelOwner& other);
54
55  Channel* channel() { return channel_ref_->channel.get(); }
56  bool IsValid() { return channel_ref_->channel.get() != NULL; }
57 private:
58  // Shared instance of a Channel. Copying ChannelOwners increase the reference
59  // count and destroying ChannelOwners decrease references. Channels are
60  // deleted when no references to them are held.
61  struct ChannelRef {
62    ChannelRef(Channel* channel);
63    const scoped_ptr<Channel> channel;
64    Atomic32 ref_count;
65  };
66
67  ChannelRef* channel_ref_;
68};
69
70class ChannelManager {
71 public:
72  ChannelManager(uint32_t instance_id, const Config& config);
73
74  // Upon construction of an Iterator it will grab a copy of the channel list of
75  // the ChannelManager. The iteration will then occur over this state, not the
76  // current one of the ChannelManager. As the Iterator holds its own references
77  // to the Channels, they will remain valid even if they are removed from the
78  // ChannelManager.
79  class Iterator {
80   public:
81    explicit Iterator(ChannelManager* channel_manager);
82
83    Channel* GetChannel();
84    bool IsValid();
85
86    void Increment();
87
88   private:
89    size_t iterator_pos_;
90    std::vector<ChannelOwner> channels_;
91
92    DISALLOW_COPY_AND_ASSIGN(Iterator);
93  };
94
95  // CreateChannel will always return a valid ChannelOwner instance. The channel
96  // is created either based on internal configuration, i.e. |config_|, by
97  // calling CreateChannel(), or using and external configuration
98  // |external_config| if the overloaded method
99  // CreateChannel(const Config& external_config) is called.
100  ChannelOwner CreateChannel();
101  ChannelOwner CreateChannel(const Config& external_config);
102
103  // ChannelOwner.channel() will be NULL if channel_id is invalid or no longer
104  // exists. This should be checked with ChannelOwner::IsValid().
105  ChannelOwner GetChannel(int32_t channel_id);
106  void GetAllChannels(std::vector<ChannelOwner>* channels);
107
108  void DestroyChannel(int32_t channel_id);
109  void DestroyAllChannels();
110
111  size_t NumOfChannels() const;
112
113 private:
114  // Create a channel given a configuration, |config|.
115  ChannelOwner CreateChannelInternal(const Config& config);
116
117  uint32_t instance_id_;
118
119  Atomic32 last_channel_id_;
120
121  scoped_ptr<CriticalSectionWrapper> lock_;
122  std::vector<ChannelOwner> channels_;
123
124  const Config& config_;
125
126  DISALLOW_COPY_AND_ASSIGN(ChannelManager);
127};
128}  // namespace voe
129}  // namespace webrtc
130
131#endif  // WEBRTC_VOICE_ENGINE_CHANNEL_MANAGER_H
132