1
// libTorrent - BitTorrent library
2
// Copyright (C) 2005-2007, Jari Sundell
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.
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.
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
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
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.
32
// Contact: Jari Sundell <jaris@ifi.uio.no>
35
// 3185 Skoppum, NORWAY
37
#ifndef LIBTORRENT_NET_SOCKET_SET_H
38
#define LIBTORRENT_NET_SOCKET_SET_H
43
#include <rak/allocators.h>
45
#include "torrent/exceptions.h"
46
#include "torrent/event.h"
50
// SocketSet's Base is a vector of active SocketBase
51
// instances. 'm_table' is a vector with the size 'openMax', each
52
// element of which points to an active instance in the Base vector.
54
// Propably should rename to EventSet...
56
class SocketSet : private std::vector<Event*, rak::cacheline_allocator<> > {
58
typedef uint32_t size_type;
60
typedef std::vector<Event*, rak::cacheline_allocator<> > base_type;
61
typedef std::vector<size_type, rak::cacheline_allocator<> > Table;
63
static const size_type npos = static_cast<size_type>(-1);
65
using base_type::value_type;
67
using base_type::iterator;
68
using base_type::reverse_iterator;
69
using base_type::empty;
70
using base_type::size;
72
using base_type::begin;
74
using base_type::rbegin;
75
using base_type::rend;
77
bool has(Event* s) const { return _index(s) != npos; }
79
iterator find(Event* s);
80
void insert(Event* s);
83
// Remove all erased elements from the container.
85
// Allocate storage for fd's with up to 'openMax' value. TODO: Remove reserve
86
void reserve(size_t openMax);
88
size_t max_size() const { return m_table.size(); }
91
size_type& _index(Event* s) { return m_table[s->file_descriptor()]; }
92
const size_type& _index(Event* s) const { return m_table[s->file_descriptor()]; }
94
inline void _replace_with_last(size_type idx);
96
// TODO: Table of indexes or iterators?
101
inline SocketSet::iterator
102
SocketSet::find(Event* s) {
103
if (_index(s) == npos)
106
return begin() + _index(s);
110
SocketSet::insert(Event* s) {
111
if (static_cast<size_type>(s->file_descriptor()) >= m_table.size())
112
throw internal_error("Tried to insert an out-of-bounds file descriptor to SocketSet");
114
if (_index(s) != npos)
118
base_type::push_back(s);
122
SocketSet::erase(Event* s) {
123
if (static_cast<size_type>(s->file_descriptor()) >= m_table.size())
124
throw internal_error("Tried to erase an out-of-bounds file descriptor from SocketSet");
126
size_type idx = _index(s);
133
*(begin() + idx) = NULL;
134
m_erased.push_back(idx);