/
descriptors.h
138 lines (117 loc) · 2.86 KB
/
descriptors.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/**
* Descriptors.h
*
* Class that collects all filedescriptors that are in use
*
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
* @author Toon Schoenmakers <toon.schoenmakers@copernica.com>
* @copyright 2015 - 2016 Copernica BV
*/
/**
* Include guard
*/
#pragma once
/**
* Dependencies
*/
#include <set>
/**
* Class definition
*/
class Descriptors
{
private:
/**
* Filedescriptors for readability and writability
* @var std::set
*/
std::set<int> _read;
std::set<int> _write;
/**
* All filedescriptors
* @var std::set
*/
std::set<int> _all;
/**
* Highest descriptor in the set
* @var int
*/
int _highest = 0;
public:
/**
* Constructor
*/
Descriptors() = default;
/**
* Destructor
*/
virtual ~Descriptors() = default;
/**
* Cast to boolean
* @return bool
*/
operator bool () const { return !_all.empty(); }
bool operator! () const { return _all.empty(); }
/**
* Expose the readable and writable sets
* @return std::set
*/
const std::set<int> &readable() const { return _read; }
const std::set<int> &writable() const { return _write; }
/**
* Highest value in the set
* @return int
*/
int highest() const { return _highest; }
/**
* Iterators to traverse the filedescriptors
* @return std::set<int>::const_iterato
*/
std::set<int>::const_iterator begin() const { return _all.begin(); }
std::set<int>::const_iterator end() const { return _all.end(); }
/**
* Add another set of descriptors
* @param that
*/
void add(const Descriptors &that)
{
// merge all the sets
_all.insert(that._all.begin(), that._all.end());
_read.insert(that._read.begin(), that._read.end());
_write.insert(that._write.begin(), that._write.end());
// check highest
_highest = std::max(_highest, that._highest);
}
/**
* Add a filedescriptor
* @param fd
* @param flags
*/
void add(int fd, int flags)
{
// should we remove instead?
if (flags == 0) return remove(fd);
// add to all set
_all.insert(fd);
// add to appropriate sets
if (flags & AMQP::readable) _read.insert(fd);
if (flags & AMQP::writable) _write.insert(fd);
// was this the highest?
if (fd > _highest) _highest = fd;
}
/**
* Remove a filedescriptor
* @param fd
*/
void remove(int fd)
{
// remove from all sets
_all.erase(fd);
_read.erase(fd);
_write.erase(fd);
// was this the highest?
if (fd != _highest) return;
// we need to find out the new highest number
_highest = _all.empty() ? 0 : *_all.rbegin();
}
};