10
10
#include < variant>
11
11
12
12
#include < fmt/format.h>
13
+ #include < netinet/in.h>
14
+ #include < sys/socket.h>
13
15
#include < unistd.h>
14
16
15
17
#include " callback.h"
@@ -60,18 +62,7 @@ class ServerThread {
60
62
other.max_fd = -1 ;
61
63
}
62
64
63
- inline auto operator =(ServerThread && other) noexcept -> ServerThread & {
64
- fmt::print (" {}\n " , __PRETTY_FUNCTION__);
65
- std::lock_guard lock (mtx);
66
- std::lock_guard lock2 (other.mtx );
67
- id = other.id ;
68
- max_fd = other.max_fd ;
69
- rfds = other.rfds ;
70
- listening_sockets = std::move (other.listening_sockets );
71
- other.id = -1 ;
72
- other.max_fd = -1 ;
73
- return *this ;
74
- }
65
+ auto operator =(ServerThread && other) noexcept -> ServerThread &;
75
66
76
67
inline ~ServerThread () {
77
68
std::lock_guard lock (mtx);
@@ -81,82 +72,20 @@ class ServerThread {
81
72
}
82
73
}
83
74
84
- inline void update_connections (int new_sock_fd) {
85
- {
86
- std::lock_guard lock (mtx);
87
- listening_sockets.push_back (new_sock_fd);
88
- }
89
- cv.notify_one ();
90
- };
91
-
92
- inline auto incomming_requests () -> int {
93
- constexpr auto timeout_s = 10ULL ;
94
- timeval timeout {};
95
- timeout.tv_sec = timeout_s;
96
- timeout.tv_usec = 0 ;
97
- int retval = select ((max_fd + 1 ), &rfds, nullptr , nullptr , &timeout);
98
- if (retval == 0 ) {
99
- fmt::print (" update connections\n " );
100
- init ();
101
- } else if (retval < 0 ) {
102
- fmt::print (" timeout\n " );
103
- }
104
- return retval;
105
- }
75
+ void update_connections (int new_sock_fd);
106
76
107
- inline void cleanup_connection (int dead_connection) {
108
- // cleanup connection
109
- std::lock_guard lock (mtx);
110
- auto it = std::find (
111
- listening_sockets.begin (), listening_sockets.end (), dead_connection);
112
- listening_sockets.erase (it);
113
- fmt::print (" {}: {}\n " , __PRETTY_FUNCTION__, dead_connection);
114
- }
77
+ auto incomming_requests () -> int;
115
78
116
- inline auto process_req (size_t sz, char * buf) const -> void {
117
- sockets::client_msg msg;
118
- auto payload_sz = sz - 4 ;
119
- std::string tmp (buf + 4 , payload_sz);
120
- msg.ParseFromString (tmp);
121
- for (auto i = 0 ; i < msg.ops_size (); ++i) {
122
- auto const & op = msg.ops (i);
123
- callbacks[op.op_id ()](op);
124
- }
125
- }
79
+ void cleanup_connection (int dead_connection);
126
80
127
81
inline void register_callback (sockets::client_msg::OperationType op,
128
82
CallbackT cb) {
129
83
callbacks[op] = std::move (cb);
130
84
}
131
85
132
- inline auto get_new_requests () -> int {
133
- std::vector<int > lsockets;
134
- {
135
- std::lock_guard lock (mtx);
136
- lsockets = listening_sockets; // this is weird, you create a copy but do
137
- // not delete old vector?
138
- }
139
- for (auto csock : lsockets) {
140
- if (FD_ISSET (csock, &rfds)) { // NOLINT
141
- auto [bytecount, buffer] = secure_recv (csock);
142
- if (bytecount <= 0 ) {
143
- if (bytecount == 0 ) {
144
- cleanup_connection (csock);
145
- init ();
146
- }
147
- }
148
- // FIXME: We expect the provider of the function to handle error cases!
149
- process_req (bytecount, buffer.get ());
150
- }
151
- }
152
- // FIXME What do we actually return here???
153
- return 0 ;
154
- }
86
+ auto get_new_requests () -> int;
155
87
156
- void init () {
157
- get_new_connections ();
158
- reset_fds ();
159
- }
88
+ void init ();
160
89
161
90
private:
162
91
int id;
@@ -168,77 +97,23 @@ class ServerThread {
168
97
std::mutex mtx;
169
98
std::condition_variable cv;
170
99
171
- void get_new_connections () {
172
- std::unique_lock<std::mutex> lock (mtx);
173
- auto nb_connections = listening_sockets.size ();
174
- while (nb_connections == 0 ) {
175
- fmt::print (" {}: no connections\n " , __PRETTY_FUNCTION__);
176
- cv.wait (lock);
177
- nb_connections = listening_sockets.size ();
178
- }
179
- }
100
+ void get_new_connections ();
180
101
181
- void reset_fds () {
182
- max_fd = -1 ;
183
- FD_ZERO (&rfds); // NOLINT
184
- for (auto rfd : listening_sockets) {
185
- FD_SET (rfd, &rfds); // NOLINT
186
- max_fd = (max_fd < rfd) ? rfd : max_fd;
187
- }
188
- }
102
+ void reset_fds ();
189
103
190
104
/* *
191
- * * It returns the actual size of msg.
192
- * * Not that msg might not contain all payload data.
193
- * * The function expects at least that the msg contains the first 4 bytes
194
- * that
195
- * * indicate the actual size of the payload.
196
- * */
105
+ ** It returns the actual size of msg.
106
+ ** Not that msg might not contain all payload data.
107
+ ** The function expects at least that the msg contains the first 4 bytes that
108
+ ** indicate the actual size of the payload.
109
+ **/
197
110
static auto destruct_message (char * msg, size_t bytes)
198
- -> std::optional<uint32_t> {
199
- if (bytes < 4 ) {
200
- return std::nullopt;
201
- }
202
-
203
- auto actual_msg_size = convert_byte_array_to_int (msg);
111
+ -> std::optional<uint32_t>;
204
112
205
- return actual_msg_size;
206
- }
207
-
208
- static auto read_n (int fd, char * buffer, size_t n) -> size_t {
209
- size_t bytes_read = 0 ;
210
- while (bytes_read < n) {
211
- auto bytes_left = n - bytes_read;
212
- auto bytes_read_now = recv (fd, buffer + bytes_read, bytes_left, 0 );
213
- if (bytes_read_now <= 0 ) {
214
- return bytes_read_now;
215
- }
216
- bytes_read += bytes_read_now;
217
- }
218
- return bytes_read;
219
- }
113
+ static auto read_n (int fd, char * buffer, size_t n) -> size_t;
220
114
221
115
static auto secure_recv (int fd)
222
- -> std::pair<uint32_t, std::unique_ptr<char[]>> {
223
- char dlen[4 ];
224
- if (auto byte_read = read_n (fd, dlen, length_size_field);
225
- byte_read != length_size_field) {
226
- return {byte_read, nullptr };
227
- }
116
+ -> std::pair<uint32_t, std::unique_ptr<char[]>>;
228
117
229
- auto actual_msg_size_opt = destruct_message (dlen, length_size_field);
230
- if (!actual_msg_size_opt) {
231
- return {-1 , nullptr };
232
- }
233
- auto actual_msg_size = *actual_msg_size_opt;
234
- auto buf =
235
- std::make_unique<char []>(static_cast <size_t >(actual_msg_size) + 1 );
236
- buf[actual_msg_size] = ' \0 ' ;
237
- if (auto byte_read = read_n (fd, buf.get (), actual_msg_size);
238
- byte_read != actual_msg_size) {
239
- return {byte_read, nullptr };
240
- }
241
-
242
- return {actual_msg_size, std::move (buf)};
243
- }
118
+ inline auto process_req (size_t sz, char * buf) const -> void;
244
119
};
0 commit comments