3232#include < atomic>
3333#include < chrono>
3434#include < functional>
35+ #include < mutex>
3536#include < thread>
3637#include < vector>
3738
@@ -77,9 +78,14 @@ class TCPServer
7778 *
7879 * \param func Function handling the event information. The file descriptor created by the
7980 * connection event will be passed to the function.
81+ *
82+ * \note: For thread safety, this will block when there is an active callback around connection
83+ * (connection, disconnection, shutdown). Thus, trying to call setConnectCallback e.g. by a
84+ * handler function registered as disconnectCallback will result in a deadlock.
8085 */
8186 void setConnectCallback (std::function<void (const socket_t )> func)
8287 {
88+ std::lock_guard<std::mutex> lk (clients_mutex_);
8389 new_connection_callback_ = func;
8490 }
8591
@@ -88,9 +94,14 @@ class TCPServer
8894 *
8995 * \param func Function handling the event information. The file descriptor created by the
9096 * connection event will be passed to the function.
97+ *
98+ * \note: For thread safety, this will block when there is an active callback around connection
99+ * (connection, disconnection, shutdown). Thus, trying to call setDisconnectCallback e.g. by a
100+ * handler function registered as connectCallback will result in a deadlock.
91101 */
92102 void setDisconnectCallback (std::function<void (const socket_t )> func)
93103 {
104+ std::lock_guard<std::mutex> lk (clients_mutex_);
94105 disconnect_callback_ = func;
95106 }
96107
@@ -99,9 +110,13 @@ class TCPServer
99110 *
100111 * \param func Function handling the event information. The file client's file_descriptor will be
101112 * passed to the function as well as the actual message received from the client.
113+ *
114+ * \note: For thread safety, this will block when there is an active message callback. Thus, trying to call
115+ * setMessageCallback e.g. from a handler function registered as messageCallback will result in a deadlock.
102116 */
103117 void setMessageCallback (std::function<void (const socket_t , char *, int )> func)
104118 {
119+ std::lock_guard<std::mutex> lk (message_mutex_);
105120 message_callback_ = func;
106121 }
107122
@@ -180,7 +195,7 @@ class TCPServer
180195 void handleDisconnect (const socket_t fd);
181196
182197 // ! read data from socket
183- void readData (const socket_t fd);
198+ bool readData (const socket_t fd);
184199
185200 // ! Event handler. Blocks until activity on any client or connection attempt
186201 void spin ();
@@ -200,6 +215,8 @@ class TCPServer
200215
201216 uint32_t max_clients_allowed_;
202217 std::vector<socket_t > client_fds_;
218+ std::mutex clients_mutex_;
219+ std::mutex message_mutex_;
203220
204221 static const int INPUT_BUFFER_SIZE = 4096 ;
205222 char input_buffer_[INPUT_BUFFER_SIZE];
0 commit comments