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/base/scoped_ptr.h"
18 #include "webrtc/system_wrappers/interface/atomic32.h"
19 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
20 #include "webrtc/typedefs.h"
21 
22 namespace webrtc {
23 
24 class Config;
25 
26 namespace voe {
27 
28 class 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 //
46 class 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 
channel()55   Channel* channel() { return channel_ref_->channel.get(); }
IsValid()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 rtc::scoped_ptr<Channel> channel;
64     Atomic32 ref_count;
65   };
66 
67   ChannelRef* channel_ref_;
68 };
69 
70 class 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   const Config& config_;
113 
114  private:
115   // Create a channel given a configuration, |config|.
116   ChannelOwner CreateChannelInternal(const Config& config);
117 
118   uint32_t instance_id_;
119 
120   Atomic32 last_channel_id_;
121 
122   rtc::scoped_ptr<CriticalSectionWrapper> lock_;
123   std::vector<ChannelOwner> channels_;
124 
125   DISALLOW_COPY_AND_ASSIGN(ChannelManager);
126 };
127 }  // namespace voe
128 }  // namespace webrtc
129 
130 #endif  // WEBRTC_VOICE_ENGINE_CHANNEL_MANAGER_H
131