1 // libTorrent - BitTorrent library
2 // Copyright (C) 2005-2011, Jari Sundell
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 //
18 // In addition, as a special exception, the copyright holders give
19 // permission to link the code of portions of this program with the
20 // OpenSSL library under certain conditions as described in each
21 // individual source file, and distribute linked combinations
22 // including the two.
23 //
24 // You must obey the GNU General Public License in all respects for
25 // all of the code used other than OpenSSL.  If you modify file(s)
26 // with this exception, you may extend this exception to your version
27 // of the file(s), but you are not obligated to do so.  If you do not
28 // wish to do so, delete this exception statement from your version.
29 // If you delete this exception statement from all source files in the
30 // program, then also delete it here.
31 //
32 // Contact:  Jari Sundell <jaris@ifi.uio.no>
33 //
34 //           Skomakerveien 33
35 //           3185 Skoppum, NORWAY
36 
37 #ifndef LIBTORRENT_NET_THROTTLE_LIST_H
38 #define LIBTORRENT_NET_THROTTLE_LIST_H
39 
40 #include <list>
41 
42 #include "torrent/rate.h"
43 
44 // To allow conditional compilation depending on whether this patch is applied or not.
45 #define LIBTORRENT_CUSTOM_THROTTLES 1
46 
47 namespace torrent {
48 
49 class ThrottleNode;
50 
51 class ThrottleList : private std::list<ThrottleNode*> {
52 public:
53   typedef std::list<ThrottleNode*> base_type;
54 
55   using base_type::iterator;
56   using base_type::const_iterator;
57   using base_type::reverse_iterator;
58   using base_type::clear;
59   using base_type::size;
60 
61   using base_type::begin;
62   using base_type::end;
63   using base_type::rbegin;
64   using base_type::rend;
65 
66   ThrottleList();
67 
is_enabled()68   bool                is_enabled() const             { return m_enabled; }
69 
70   bool                is_active(const ThrottleNode* node) const;
71   bool                is_inactive(const ThrottleNode* node) const;
72 
73   bool                is_throttled(const ThrottleNode* node) const;
74 
75   // When disabled all nodes are active at all times.
76   void                enable();
77   void                disable();
78 
79   // Returns the amount of quota used. May be negative if it had unused
80   // quota left over from the last call that was more than is now allowed.
81   int32_t             update_quota(uint32_t quota);
82 
size()83   uint32_t            size() const                   { return m_size; }
84 
outstanding_quota()85   uint32_t            outstanding_quota() const      { return m_outstandingQuota; }
unallocated_quota()86   uint32_t            unallocated_quota() const      { return m_unallocatedQuota; }
87 
min_chunk_size()88   uint32_t            min_chunk_size() const         { return m_minChunkSize; }
set_min_chunk_size(uint32_t v)89   void                set_min_chunk_size(uint32_t v) { m_minChunkSize = v; }
90 
max_chunk_size()91   uint32_t            max_chunk_size() const         { return m_maxChunkSize; }
set_max_chunk_size(uint32_t v)92   void                set_max_chunk_size(uint32_t v) { m_maxChunkSize = v; }
93 
94   uint32_t            node_quota(ThrottleNode* node);
95   uint32_t            node_used(ThrottleNode* node, uint32_t used);  // both node_used functions
96   uint32_t            node_used_unthrottled(uint32_t used);          // return the "used" argument
97   void                node_deactivate(ThrottleNode* node);
98 
rate_slow()99   const Rate*         rate_slow() const              { return &m_rateSlow; }
100 
101   void                add_rate(uint32_t used);
rate_added()102   uint32_t            rate_added()                   { uint32_t v = m_rateAdded; m_rateAdded = 0; return v; }
103 
104   // It is asumed that inserted nodes are currently active. It won't
105   // matter if they do not get any initial quota as a later activation
106   // of an active node should be safe.
107   void                insert(ThrottleNode* node);
108   void                erase(ThrottleNode* node);
109 
110 private:
111   inline void         allocate_quota(ThrottleNode* node);
112 
113   bool                m_enabled;
114   uint32_t            m_size;
115 
116   uint32_t            m_outstandingQuota;
117   uint32_t            m_unallocatedQuota;
118   uint32_t            m_unusedUnthrottledQuota;
119 
120   uint32_t            m_rateAdded;
121 
122   uint32_t            m_minChunkSize;
123   uint32_t            m_maxChunkSize;
124 
125   Rate                m_rateSlow;
126 
127   // [m_splitActive,end> contains nodes that are inactive and need
128   // more quote, sorted from the most urgent
129   // node. [begin,m_splitActive> holds nodes with a large enough quota
130   // to transmit, but are blocking. These are sorted from the longest
131   // blocking node.
132   iterator            m_splitActive;
133 };
134 
135 }
136 
137 #endif
138