dodo  0.0.1
A C++ library to create containerized Linux services
tcplistener.hpp
Go to the documentation of this file.
1 /*
2  * This file is part of the dodo library (https://github.com/jmspit/dodo).
3  * Copyright (c) 2019 Jan-Marten Spit.
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, version 3.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * 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, see <http://www.gnu.org/licenses/>.
16  */
17 
18 /**
19  * @file tcplistener.hpp
20  * Defines the dodo::network::TCPListener class.
21  */
22 
23 #ifndef network_tcplistener_hpp
24 #define network_tcplistener_hpp
25 
26 #include <atomic>
27 #include <condition_variable>
28 #include <functional>
29 #include <map>
30 #include <queue>
31 #include <set>
32 #include <stdint.h>
33 #include <sys/epoll.h>
34 #include <sys/resource.h>
35 #include <sys/socket.h>
36 #include <yaml-cpp/yaml.h>
37 
38 #include "common/exception.hpp"
39 #include "common/bytes.hpp"
40 #include "network/socket.hpp"
41 #include "threads/mutex.hpp"
42 #include "threads/thread.hpp"
43 
44 
45 namespace dodo {
46 
47  namespace network {
48 
49  class TCPServer;
50  class TCPListenerTimer;
51 
52  /**
53  * Class to track a connection.
54  */
56  public:
57 
58  /**
59  * Construct
60  */
62 
63  /**
64  * Destruct.
65  */
66  virtual ~TCPConnectionData() {};
67 
68  /**
69  * Reads and appends data to read_buffer
70  * @param socket The socket to read from.
71  * @param received The number of bytes received.
72  * @return The number of bytes read.
73  */
74  common::SystemError readBuffer( BaseSocket* socket, ssize_t &received );
75 
76  /**
77  * Clears the read_buffer.
78  */
79  void clearBuffer();
80 
81  /**
82  * Get a reference to the read buffer.
83  * @return a reference to the read buffer.
84  */
85  const common::Bytes& getReadBuffer() const { return read_buffer; }
86 
87  protected:
88  /** Buffer for (incomplete) request data. */
90  };
91 
92  /**
93  *
94  * The TCPListener listens, accepts connections and generates socket events to produce TCP work to a pool of
95  * TCPServer worker objects. Developers must implement a protocol by subclassing TCPServer. The produced
96  * by a TCPListener is either
97  *
98  * - handling new connections (and optionally perform a protocol handShake).
99  * - reading data from sockets and sending responses
100  * - closing down connections on hangups or errors.
101  *
102  * The developer sub-classes TCPServer to implement a request-response protocol.
103  *
104  * TCPListener uses the Linux epoll_wait interface to pick up socket events and distribute the work to TCPServers.
105  *
106  * The TCPListener is started start( TCPServer *server ) with an initial TCPServer object. The
107  * TCPServer::addServer() method is used to spawn additional TCPServer objects up to Params.minservers when
108  * TCPListener::run() is invoked. The TCPListener will spawn TCPServer worker threads if the amount of pending
109  * work exceeds the number of existing TCPServer objects, up to Params.maxservers.
110  *
111  * The TCPServer descendant class implements the details of handShake, readSocket and shutDown, and are each
112  * passed a SocketWork that needs to be serviced -a SocketWork specifies the socket and the event state it is in.
113  *
114  * Sockets are set to non-blocking mode, and TCPServer::readSocket is not guaranteed to see a full request, data
115  * might arrive in multiple chunks.
116  *
117  * For a given connection, a TCPServer descendant will cycle through
118  *
119  * - a handShake call
120  * - zero or more readSocket calls
121  * - a shutDown call
122  *
123  * On connection errors and hangups call to shutDown will follow - the BaseSocket object passed to shutDown() is
124  * not destroyed yet, allowing TCPServer implementations to clean up failed connections.
125  */
126  class TCPListener : public threads::Thread {
127  public:
128 
129  /**
130  * Parameters affecting TCPListener behavior.
131  */
132  struct Params {
133 
134  /**
135  * Construct with default parameters.
136  */
137  Params() :
138  minservers(8),
139  maxservers(16),
140  maxconnections(6000),
141  maxqdepth(128),
142  sendbufsz(16384),
143  recvbufsz(32768),
144  server_idle_ttl_s(300),
145  pollbatch(128),
146  listener_sleep_ms(1000),
147  throttle_sleep_us(4000),
149  stat_trc_interval_s(300),
152  tcp_keep_alive(false)
153  {};
154 
155  /**
156  * Construct from a YAML::Node.
157  * @param node The YAML::Node to read parameters from.
158  */
159  Params( const YAML::Node &node );
160 
161  /**
162  * The minimum number of TCPServers
163  */
164  size_t minservers;
165 
166  /**
167  * The maximum number of TCPServers
168  */
169  size_t maxservers;
170 
171  /**
172  * The maximum number of connections (in effect, sockets) allowed.
173  */
175 
176  /**
177  * Maximum size of connection and request work queues.
178  */
179  size_t maxqdepth;
180 
181  /**
182  * The send buffer size, set on the listening socket, inherited by accepted sockets.
183  */
184  socklen_t sendbufsz;
185 
186  /**
187  * The receive buffer size, set on the listening socket, inherited by accepted sockets.
188  */
189  socklen_t recvbufsz;
190 
191  /**
192  * The maximum TCPServer idle time in seconds before stopping the server, honoring minservers.
193  */
195 
196  /**
197  * The number of epoll_wait events read in one epol__wait wake-up
198  */
200 
201  /**
202  * The TCPListener epoll_wait timeout in ms
203  */
205 
206  /**
207  * The time to sleep when the queue gets too big (letting workers clear from the queue without
208  * accepting new work.
209  */
211 
212  /**
213  * Maximum number of throttles per epoll_wait cycle. The listener thread is blocked no longer than
214  * cycle_max_throttles * throttle_sleep_us per epoll_wait cycle.
215  */
217 
218  /**
219  * The epol__wait timeout in ms
220  */
222 
223  /**
224  * Send timeout in seconds.
225  */
227 
228  /**
229  * Receive timeout in seconds.
230  */
232 
233  /**
234  * Toggle TCP keep-alive.
235  */
237  };
238 
239 
240  /**
241  * Load statisics.
242  */
243  struct Stats {
244  Stats() : connections(0), requests(0), throttles(0),received(0),sent(0) {};
245  /** The number of connections. */
246  ssize_t connections;
247  /** The number of requests. */
248  ssize_t requests;
249  /** The number of throttles. */
250  ssize_t throttles;
251  /** The number of bytes received */
252  ssize_t received;
253  /** The number of bytes sent */
254  ssize_t sent;
255  };
256 
257  /**
258  * BaseSocket lifecycle states.
259  */
260  enum class SockState {
261  None = 0, /**< Undefined / initial */
262  New = 1, /**< New connection, TCPServer::handShake() will be called */
263  Read = 2, /**< Data is ready to be read, TCPServer::readSocket() will be called */
264  Shut = 4 /**< BaseSocket is hung up or in error, TCPServer::shutDown() will be called */
265  };
266 
267  /**
268  * BaseSocket socket and state pair.
269  * @see clients_
270  */
271  struct SocketWork {
272  /** Pointer to the socket */
273  BaseSocket* socket = nullptr;
274  /** State of the socket */
276  /** Data context */
278  };
279 
280  /**
281  * Constructor
282  * @param address The address to listen on.
283  * @param params The Params to use.
284  * @see listen()
285  */
286  TCPListener( const Address& address, const Params &params );
287 
288  /**
289  * Constructor, read Address and params from the YAML::Node.
290  * @param yaml The YAML::NOde to read the configuration from.
291  */
292  TCPListener( const YAML::Node &yaml );
293 
294  ~TCPListener();
295 
296  /**
297  * Start the TCPListener and initialize with a TCPServer implementation object.
298  * @param server A TCPServer descendant as initial server.
299  */
300  void start( TCPServer *server );
301 
302  /**
303  * Request a stop on the TCPListener. Call wait() to wait for the thread to actually be stopped.
304  */
305  void stop() { stop_server_ = true; }
306 
307  private:
308 
309  /**
310  * Add an epoll event for the BaseSocket.
311  * @param s The BaseSocket
312  * @param events The events to set (see man epoll_ctl).
313  */
314  void pollAdd( const BaseSocket* s, uint32_t events );
315 
316  /**
317  * Modify an epoll event for the BaseSocket.
318  * @param s The BaseSocket
319  * @param events The events to set (see man epoll_ctl).
320  */
321  void pollMod( const BaseSocket* s, uint32_t events );
322 
323  /**
324  * Delete the epoll event for the BaseSocket.
325  * @param s The BaseSocket
326  */
327  void pollDel( const BaseSocket* s );
328 
329  /**
330  * Log TCPListener statistics to Logger::getLogger().
331  */
332  void logStats();
333 
334  /**
335  * Throttle the listener when work_q_sz_ exceeds params_.maxqdepth
336  */
337  void throttle();
338 
339  /**
340  * Add a server if work_q_sz_ exceeds servers.size() and servers_.size() < params_.maxservers
341  */
342  void addServers();
343 
344  /**
345  * Cleanup stopped TCPServers
346  */
347  void cleanStoppedServers();
348 
349  /**
350  * Tell the listener to close the socket.
351  * @param socket The socket to close.
352  */
353  void closeSocket( BaseSocket *socket );
354 
355  /**
356  * Called by the TCPServer, enters wait state until woken up by either a timeout or a notify
357  * by TCPListener that there are 1 or more requests to be handled.
358  * @param server The TCPServer calling this.
359  * @return True if there are pending requests or request_stop_ is true.
360  */
361  bool waitForActivity( TCPServer* server );
362 
363  /**
364  * Common constructor code.
365  * @param address The address to listen on.
366  * @param params The Params to use.*
367  */
368  void construct( const Address& address, const Params &params );
369 
370  /**
371  * Push work.
372  * @param work The SocketWork to handle.
373  * @see SocketWork.
374  */
375  //void pushWork( BaseSocket* socket, SockState state );
376  void pushWork( const SocketWork &work );
377 
378  /**
379  * Push work.
380  * @param fd The BaseSocket fieldescriptor.
381  * @param state The state the BaseSocket is in.
382  * @see SockState.
383  */
384  void pushWork( int fd, SockState state );
385 
386  /**
387  * Pop work.
388  * @return A SocketWork* to handle, or NULL if there is no work to handle.
389  */
390  SocketWork* popWork();
391 
392  /**
393  * Called by a TCPServer to signal that the work has been handled and event detection on it can resume.
394  * @param work The SocketWork.
395  */
396  void releaseWork( const SocketWork &work );
397 
398  /**
399  * Entrypoint, override of Thread::run()
400  */
401  virtual void run();
402 
403  /**
404  * Add received bytes.
405  * @param r The received bytes to add.
406  * @param s The sent bytes to add
407  */
408  void addReceivedSentBytes( ssize_t r, ssize_t s ) {
410  last_stats_.received += r;
411  last_stats_.sent += s;
412  }
413 
414  /**
415  * The listening address.
416  */
418 
419  /**
420  * TCPListener parameters
421  */
423 
424  /**
425  * The initial TCPServer, which will live as long as the TCPListener runs, and is sued
426  * to create new TCPServers under load.
427  */
429 
430  /**
431  * The listening BaseSocket.
432  */
434 
435  /**
436  * The backlog (incoming connection queue before accept calls clearing it) used by listen.
437  * @see man 2 listen
438  */
439  int backlog_;
440 
441  /**
442  * If true, the TCPListener will gracefully stop and finish.
443  */
445 
446  /**
447  * Protects both client_ and workload_
448  */
450 
451  /**
452  * Mutex used to wakeup TCPServer threads with condition variable cv_signal_.
453  * @see cv_signal_.
454  */
455  std::mutex mt_signal_;
456 
457  /**
458  * Condition variable used to wakeup TCPServer threads with mutex mt_signal_.
459  * @see mt_signal_.
460  */
461  std::condition_variable cv_signal_;
462 
463  /**
464  * Map of file descriptors to SocketWork for all connected clients. The work is either in progress or last
465  * completed state.
466  */
467  std::map<int,SocketWork> clients_;
468 
469  /**
470  * List of TCPServers.
471  */
472  std::list<TCPServer*> servers_;
473 
474  /**
475  * Queue of sockets with work for TCPServer instances.
476  */
477  std::deque<SocketWork*> workload_;
478 
479  /**
480  * The number of queued work items.
481  */
482  std::atomic<unsigned long long> work_q_sz_;
483 
484  /**
485  * The epoll interface file descriptor.
486  */
488 
489  /**
490  * The event mask for read events. This is the one-shot event mask for incoming data.
491  */
493 
494  /**
495  * The event mask for hangup events. This is the event mask for all error and hangup events, an event mode
496  * active whilst a read event for the socket is already queued for processing, so that errors may be caught
497  * without clearing any pending read events on the socket.
498  */
500 
501  /**
502  * The previous Stats.
503  */
505 
506  /**
507  * The last Stats.
508  */
510 
511  /**
512  * Protects prev_stats_, last_stats_.
513  */
515 
516  /**
517  * Time of last queueing warning
518  */
519  struct timeval warn_queue_time_;
520 
521  /**
522  * Time of previous statistics
523  */
524  struct timeval prev_stat_time_;
525 
526  /**
527  * Time of last statistics
528  */
529  struct timeval stat_time_;
530 
531  /**
532  * Time of last check for stopped servers
533  */
535 
536  /**
537  * Synchronize access to now_.
538  */
540 
541  /**
542  * Frequently updated by a TCPListenerTimer with enough precision for its use.
543  */
544  struct timeval now_;
545 
546  /**
547  * The number of times a connection was closed after accept because params_.maxconnectctions was reached.
548  */
550 
551  /**
552  * TCPListenerTimer needs access to now_ and now_mutex_
553  */
554  friend class TCPListenerTimer;
555 
556  /**
557  * TCPServer needs access to several private definitions, data and methods.
558  */
559  friend class TCPServer;
560 
563  friend bool operator&( const TCPListener::SockState&, const TCPListener::SockState& );
564 
566 
567  };
568 
569  /**
570  * Bitwise |= on SocketWork
571  * @param self the lvalue
572  * @param other the rvalue
573  * @return the lvalue
574  */
576  return self = static_cast<TCPListener::SockState>( static_cast<int>(self) | static_cast<int>(other) );
577  }
578 
579  /**
580  * Bitwise ^= on SocketWork
581  * @param self the lvalue
582  * @param other the rvalue
583  * @return the lvalue
584  */
586  return self = static_cast<TCPListener::SockState>( static_cast<int>(self) ^ static_cast<int>(other) );
587  }
588 
589  /**
590  * Bitwise & on SocketWork
591  * @param self the lvalue
592  * @param other the rvalue
593  * @return the lvalue
594  */
595  inline bool operator&( const TCPListener::SockState &self, const TCPListener::SockState &other ) {
596  return static_cast<int>(self) & static_cast<int>(other);
597  }
598 
599 
600  /**
601  * Nice-write to a Puts.
602  * @param os The output Puts
603  * @param state The TCPListener::SockState to write.
604  * @return The output Puts
605  */
607  if ( state & TCPListener::SockState::None ) os << "None|";
608  if ( state & TCPListener::SockState::New ) os << "New|";
609  if ( state & TCPListener::SockState::Read ) os << "Read|";
610  if ( state & TCPListener::SockState::Shut ) os << "Shut|";
611  //switch ( state ) {
612  //case TCPListener::SockState::None :
613  //os << "none";
614  //break;
615  //case TCPListener::SockState::New :
616  //os << "new";
617  //break;
618  //case TCPListener::SockState::Read :
619  //os << "read";
620  //break;
621  //case TCPListener::SockState::Shut :
622  //os << "shut";
623  //break;
624  //}
625  os << " (" << static_cast<int>(state) << ")";
626  return os;
627  }
628 
629  }
630 
631 }
632 
633 #endif
dodo::network::TCPConnectionData::getReadBuffer
const common::Bytes & getReadBuffer() const
Get a reference to the read buffer.
Definition: tcplistener.hpp:85
dodo::network::TCPListener::listen_socket_
BaseSocket * listen_socket_
The listening BaseSocket.
Definition: tcplistener.hpp:433
dodo::network::TCPListener::last_stats_
Stats last_stats_
The last Stats.
Definition: tcplistener.hpp:509
dodo::network::TCPListener::prev_stats_
Stats prev_stats_
The previous Stats.
Definition: tcplistener.hpp:504
dodo::threads::Mutexer
Waits for and locks the Mutex on construction, unlocks the Mutex when this Mutexer is destructed.
Definition: mutex.hpp:100
dodo::network::TCPListener::now_mutex_
threads::Mutex now_mutex_
Synchronize access to now_.
Definition: tcplistener.hpp:539
dodo::network::TCPListener::SocketWork::data
TCPConnectionData * data
Data context.
Definition: tcplistener.hpp:277
dodo::network::TCPListener::addServers
void addServers()
Add a server if work_q_sz_ exceeds servers.size() and servers_.size() < params_.maxservers.
Definition: tcplistener.cpp:488
dodo::network::TCPListener::event_maxconnections_reached_
size_t event_maxconnections_reached_
The number of times a connection was closed after accept because params_.maxconnectctions was reached...
Definition: tcplistener.hpp:549
dodo::network::TCPListener::cleanStoppedServers
void cleanStoppedServers()
Cleanup stopped TCPServers.
Definition: tcplistener.cpp:568
dodo::network::operator<<
const dodo::common::Puts & operator<<(const dodo::common::Puts &os, TCPListener::SockState state)
Nice-write to a Puts.
Definition: tcplistener.hpp:606
dodo::network::operator^=
TCPListener::SockState & operator^=(TCPListener::SockState &self, TCPListener::SockState other)
Bitwise ^= on SocketWork.
Definition: tcplistener.hpp:585
dodo::network::TCPListener::SockState
SockState
BaseSocket lifecycle states.
Definition: tcplistener.hpp:260
dodo::network::TCPListener::Params::sendbufsz
socklen_t sendbufsz
The send buffer size, set on the listening socket, inherited by accepted sockets.
Definition: tcplistener.hpp:184
dodo::network::TCPListener::SockState::None
@ None
Undefined / initial.
dodo::network::TCPListener::operator|=
friend TCPListener::SockState & operator|=(TCPListener::SockState &, TCPListener::SockState)
Bitwise |= on SocketWork.
Definition: tcplistener.hpp:575
dodo::network::TCPConnectionData::clearBuffer
void clearBuffer()
Clears the read_buffer.
Definition: tcplistener.cpp:62
dodo::network::TCPListener::Params::cycle_max_throttles
size_t cycle_max_throttles
Maximum number of throttles per epoll_wait cycle.
Definition: tcplistener.hpp:216
dodo::network::TCPListener::Stats::received
ssize_t received
The number of bytes received.
Definition: tcplistener.hpp:252
dodo::network::TCPListener::SocketWork::state
SockState state
State of the socket.
Definition: tcplistener.hpp:275
dodo::network::TCPListener::SockState::New
@ New
New connection, TCPServer::handShake() will be called.
dodo::network::TCPListener::clientmutex_
threads::Mutex clientmutex_
Protects both client_ and workload_.
Definition: tcplistener.hpp:449
dodo::network::TCPListener::Stats::sent
ssize_t sent
The number of bytes sent.
Definition: tcplistener.hpp:254
dodo::common::Bytes
An array of Octets with size elements.
Definition: bytes.hpp:44
dodo::network::TCPListener::SockState::Shut
@ Shut
BaseSocket is hung up or in error, TCPServer::shutDown() will be called.
dodo::network::Address
Generic network Address, supporting ipv4 and ipv6 transparently.
Definition: address.hpp:90
dodo::network::TCPListener::backlog_
int backlog_
The backlog (incoming connection queue before accept calls clearing it) used by listen.
Definition: tcplistener.hpp:439
dodo::network::TCPListenerTimer
Updates the attribute now_ in the TCPListener at a regular interval to avoid excessive number of call...
Definition: tcplistener.cpp:70
dodo::network::TCPListener::init_server_
TCPServer * init_server_
The initial TCPServer, which will live as long as the TCPListener runs, and is sued to create new TCP...
Definition: tcplistener.hpp:428
dodo::network::TCPListener::Params::minservers
size_t minservers
The minimum number of TCPServers.
Definition: tcplistener.hpp:164
dodo::network::TCPListener::Params::stat_trc_interval_s
time_t stat_trc_interval_s
The epol__wait timeout in ms.
Definition: tcplistener.hpp:221
dodo::network::TCPListener::Params::maxqdepth
size_t maxqdepth
Maximum size of connection and request work queues.
Definition: tcplistener.hpp:179
dodo::network::TCPListener::operator&
friend bool operator&(const TCPListener::SockState &, const TCPListener::SockState &)
Bitwise & on SocketWork.
Definition: tcplistener.hpp:595
dodo::network::TCPListener::closeSocket
void closeSocket(BaseSocket *socket)
Tell the listener to close the socket.
Definition: tcplistener.cpp:448
dodo::network::TCPListener::stop
void stop()
Request a stop on the TCPListener.
Definition: tcplistener.hpp:305
dodo::network::TCPConnectionData::TCPConnectionData
TCPConnectionData()
Construct.
Definition: tcplistener.hpp:61
dodo::network::TCPListener::read_event_mask_
uint32_t read_event_mask_
The event mask for read events.
Definition: tcplistener.hpp:492
dodo::threads::Thread::start
void start()
Start the thread.
Definition: thread.cpp:58
dodo::network::TCPListener::stat_time_
struct timeval stat_time_
Time of last statistics.
Definition: tcplistener.hpp:529
dodo::network::TCPListener::Params::maxconnections
size_t maxconnections
The maximum number of connections (in effect, sockets) allowed.
Definition: tcplistener.hpp:174
dodo::network::TCPListener::Stats
Load statisics.
Definition: tcplistener.hpp:243
dodo::network::TCPListener::SocketWork::socket
BaseSocket * socket
Pointer to the socket.
Definition: tcplistener.hpp:273
dodo::network::TCPListener::warn_queue_time_
struct timeval warn_queue_time_
Time of last queueing warning.
Definition: tcplistener.hpp:519
dodo::network::TCPListener::run
virtual void run()
Entrypoint, override of Thread::run()
Definition: tcplistener.cpp:236
dodo::network::TCPConnectionData::~TCPConnectionData
virtual ~TCPConnectionData()
Destruct.
Definition: tcplistener.hpp:66
dodo::network::TCPListener::Params::recvbufsz
socklen_t recvbufsz
The receive buffer size, set on the listening socket, inherited by accepted sockets.
Definition: tcplistener.hpp:189
dodo::network::TCPListener::cv_signal_
std::condition_variable cv_signal_
Condition variable used to wakeup TCPServer threads with mutex mt_signal_.
Definition: tcplistener.hpp:461
dodo::network::TCPListener::pollAdd
void pollAdd(const BaseSocket *s, uint32_t events)
Add an epoll event for the BaseSocket.
Definition: tcplistener.cpp:461
dodo::network::TCPListener::releaseWork
void releaseWork(const SocketWork &work)
Called by a TCPServer to signal that the work has been handled and event detection on it can resume.
Definition: tcplistener.cpp:435
dodo::network::TCPListener::listen_address_
Address listen_address_
The listening address.
Definition: tcplistener.hpp:417
dodo::threads::Mutex
A Mutex to synchronize access to resources between threads.
Definition: mutex.hpp:39
dodo
A C++ platform interface to lean Linux services tailored for containerized deployment.
Definition: application.hpp:29
dodo::network::TCPListener::workload_
std::deque< SocketWork * > workload_
Queue of sockets with work for TCPServer instances.
Definition: tcplistener.hpp:477
dodo::network::TCPListener::Params::receive_timeout_seconds
int receive_timeout_seconds
Receive timeout in seconds.
Definition: tcplistener.hpp:231
dodo::network::TCPListener::servers_
std::list< TCPServer * > servers_
List of TCPServers.
Definition: tcplistener.hpp:472
dodo::network::TCPListener::Params::Params
Params()
Construct with default parameters.
Definition: tcplistener.hpp:137
thread.hpp
dodo::network::TCPListener::mt_signal_
std::mutex mt_signal_
Mutex used to wakeup TCPServer threads with condition variable cv_signal_.
Definition: tcplistener.hpp:455
dodo::network::TCPListener::waitForActivity
bool waitForActivity(TCPServer *server)
Called by the TCPServer, enters wait state until woken up by either a timeout or a notify by TCPListe...
Definition: tcplistener.cpp:224
dodo::network::TCPListener::pollDel
void pollDel(const BaseSocket *s)
Delete the epoll event for the BaseSocket.
Definition: tcplistener.cpp:479
dodo::network::TCPListener::Params::throttle_sleep_us
size_t throttle_sleep_us
The time to sleep when the queue gets too big (letting workers clear from the queue without accepting...
Definition: tcplistener.hpp:210
dodo::network::TCPListener::popWork
SocketWork * popWork()
Pop work.
Definition: tcplistener.cpp:420
dodo::network::TCPListener::SockState::Read
@ Read
Data is ready to be read, TCPServer::readSocket() will be called.
dodo::network::TCPListener::Stats::throttles
ssize_t throttles
The number of throttles.
Definition: tcplistener.hpp:250
socket.hpp
dodo::network::TCPListener::throttle
void throttle()
Throttle the listener when work_q_sz_ exceeds params_.maxqdepth.
Definition: tcplistener.cpp:497
dodo::network::TCPListener::Params
Parameters affecting TCPListener behavior.
Definition: tcplistener.hpp:132
dodo::network::TCPServer
Used in conjunction with TCPListener to implement high speed, multithreaded TCP services.
Definition: tcpserver.hpp:56
dodo::network::TCPListener::operator<<
const friend dodo::common::Puts & operator<<(const dodo::common::Puts &, TCPListener::SockState)
Nice-write to a Puts.
Definition: tcplistener.hpp:606
dodo::network::TCPListener::prev_stat_time_
struct timeval prev_stat_time_
Time of previous statistics.
Definition: tcplistener.hpp:524
dodo::network::TCPListener::Params::listener_sleep_ms
int listener_sleep_ms
The TCPListener epoll_wait timeout in ms.
Definition: tcplistener.hpp:204
dodo::network::TCPListener::operator^=
friend TCPListener::SockState & operator^=(TCPListener::SockState &, TCPListener::SockState)
Bitwise ^= on SocketWork.
Definition: tcplistener.hpp:585
dodo::network::TCPConnectionData::readBuffer
common::SystemError readBuffer(BaseSocket *socket, ssize_t &received)
Reads and appends data to read_buffer.
Definition: tcplistener.cpp:38
dodo::network::TCPListener::TCPListener
TCPListener(const Address &address, const Params &params)
Constructor.
Definition: tcplistener.cpp:157
dodo::network::TCPListener::pollMod
void pollMod(const BaseSocket *s, uint32_t events)
Modify an epoll event for the BaseSocket.
Definition: tcplistener.cpp:470
dodo::network::TCPListener::SocketWork
BaseSocket socket and state pair.
Definition: tcplistener.hpp:271
dodo::network::TCPListener::clients_
std::map< int, SocketWork > clients_
Map of file descriptors to SocketWork for all connected clients.
Definition: tcplistener.hpp:467
dodo::network::TCPListener::addReceivedSentBytes
void addReceivedSentBytes(ssize_t r, ssize_t s)
Add received bytes.
Definition: tcplistener.hpp:408
dodo::network::TCPListener::logStats
void logStats()
Log TCPListener statistics to Logger::getLogger().
Definition: tcplistener.cpp:511
dodo::network::TCPListener::work_q_sz_
std::atomic< unsigned long long > work_q_sz_
The number of queued work items.
Definition: tcplistener.hpp:482
exception.hpp
dodo::network::TCPListener::Stats::requests
ssize_t requests
The number of requests.
Definition: tcplistener.hpp:248
dodo::common::Puts
Helper class to write strings in stream format, eg.
Definition: puts.hpp:46
dodo::network::TCPConnectionData
Class to track a connection.
Definition: tcplistener.hpp:55
dodo::common::SystemError
Linux system error primitive to provide a consistent interface to Linux error codes.
Definition: systemerror.hpp:53
dodo::threads::Thread
Abstract Thread class.
Definition: thread.hpp:38
dodo::network::TCPListener::construct
void construct(const Address &address, const Params &params)
Common constructor code.
Definition: tcplistener.cpp:166
dodo::network::TCPListener::Params::send_timeout_seconds
int send_timeout_seconds
Send timeout in seconds.
Definition: tcplistener.hpp:226
dodo::network::TCPListener::hangup_event_mask_
uint32_t hangup_event_mask_
The event mask for hangup events.
Definition: tcplistener.hpp:499
dodo::network::TCPListener::Params::tcp_keep_alive
bool tcp_keep_alive
Toggle TCP keep-alive.
Definition: tcplistener.hpp:236
dodo::network::TCPListener::Stats::connections
ssize_t connections
The number of connections.
Definition: tcplistener.hpp:244
dodo::network::TCPListener::now_
struct timeval now_
Frequently updated by a TCPListenerTimer with enough precision for its use.
Definition: tcplistener.hpp:544
dodo::network::TCPListener
The TCPListener listens, accepts connections and generates socket events to produce TCP work to a poo...
Definition: tcplistener.hpp:126
dodo::network::TCPListener::Params::maxservers
size_t maxservers
The maximum number of TCPServers.
Definition: tcplistener.hpp:169
dodo::network::TCPListener::pushWork
void pushWork(const SocketWork &work)
Push work.
Definition: tcplistener.cpp:408
dodo::network::TCPListener::params_
Params params_
TCPListener parameters.
Definition: tcplistener.hpp:422
dodo::network::operator&
bool operator&(const TCPListener::SockState &self, const TCPListener::SockState &other)
Bitwise & on SocketWork.
Definition: tcplistener.hpp:595
dodo::network::TCPListener::epoll_fd_
int epoll_fd_
The epoll interface file descriptor.
Definition: tcplistener.hpp:487
dodo::network::TCPConnectionData::read_buffer
common::Bytes read_buffer
Buffer for (incomplete) request data.
Definition: tcplistener.hpp:89
dodo::network::TCPListener::Params::server_idle_ttl_s
double server_idle_ttl_s
The maximum TCPServer idle time in seconds before stopping the server, honoring minservers.
Definition: tcplistener.hpp:194
dodo::network::TCPListener::stats_mutex_
threads::Mutex stats_mutex_
Protects prev_stats_, last_stats_.
Definition: tcplistener.hpp:514
dodo::network::TCPListener::stop_server_
bool stop_server_
If true, the TCPListener will gracefully stop and finish.
Definition: tcplistener.hpp:444
bytes.hpp
dodo::network::operator|=
TCPListener::SockState & operator|=(TCPListener::SockState &self, TCPListener::SockState other)
Bitwise |= on SocketWork.
Definition: tcplistener.hpp:575
dodo::network::BaseSocket
Interface to and common implementation of concrete sockets (Socket, TLSSocket).
Definition: basesocket.hpp:36
mutex.hpp
dodo::network::TCPListener::server_stopped_check_time_
struct timeval server_stopped_check_time_
Time of last check for stopped servers.
Definition: tcplistener.hpp:534
dodo::network::TCPListener::Params::pollbatch
int pollbatch
The number of epoll_wait events read in one epol__wait wake-up.
Definition: tcplistener.hpp:199