@@ -24,7 +24,7 @@ namespace network {
2424class ProtocolReader {
2525 public:
2626 static uint32_t read_int32 (const char * buffer) {
27- uint32_t val;
27+ uint32_t val = 0 ;
2828 std::memcpy (&val, buffer, 4 );
2929 return ntohl (val);
3030 }
@@ -85,32 +85,41 @@ std::unique_ptr<Server> Server::create(uint16_t port, Catalog& catalog,
8585 * @brief Start the server
8686 */
8787bool Server::start () {
88- if (running_.load ()) return false ;
88+ {
89+ std::lock_guard<std::mutex> lock (state_mutex_);
90+ if (running_) return false ;
91+ }
8992
90- listen_fd_ = socket (AF_INET , SOCK_STREAM , 0 );
91- if (listen_fd_ < 0 ) return false ;
93+ int fd = socket (AF_INET , SOCK_STREAM , 0 );
94+ if (fd < 0 ) return false ;
9295
9396 int opt = 1 ;
94- setsockopt (listen_fd_ , SOL_SOCKET , SO_REUSEADDR , &opt, sizeof (opt));
97+ setsockopt (fd , SOL_SOCKET , SO_REUSEADDR , &opt, sizeof (opt));
9598
9699 struct sockaddr_in addr;
97100 memset (&addr, 0 , sizeof (addr));
98101 addr.sin_family = AF_INET ;
99102 addr.sin_addr .s_addr = INADDR_ANY ;
100103 addr.sin_port = htons (port_);
101104
102- if (bind (listen_fd_ , (struct sockaddr *)&addr, sizeof (addr)) < 0 ) {
103- close (listen_fd_ );
105+ if (bind (fd , (struct sockaddr *)&addr, sizeof (addr)) < 0 ) {
106+ close (fd );
104107 return false ;
105108 }
106109
107- if (listen (listen_fd_ , 10 ) < 0 ) {
108- close (listen_fd_ );
110+ if (listen (fd , 10 ) < 0 ) {
111+ close (fd );
109112 return false ;
110113 }
111114
112- status_ = ServerStatus::Running;
113- running_ = true ;
115+ {
116+ std::lock_guard<std::mutex> lock (state_mutex_);
117+ listen_fd_ = fd;
118+ status_ = ServerStatus::Running;
119+ running_ = true ;
120+ }
121+
122+ std::lock_guard<std::mutex> lock (thread_mutex_);
114123 accept_thread_ = std::thread (&Server::accept_connections, this );
115124 return true ;
116125}
@@ -119,40 +128,69 @@ bool Server::start() {
119128 * @brief Stop the server
120129 */
121130bool Server::stop () {
122- if (!running_.load ()) return true ;
123-
124- status_ = ServerStatus::Stopping;
125- running_ = false ;
131+ int fd_to_close = -1 ;
132+ {
133+ std::lock_guard<std::mutex> lock (state_mutex_);
134+ if (!running_) return true ;
135+ status_ = ServerStatus::Stopping;
136+ running_ = false ;
137+ if (listen_fd_ >= 0 ) {
138+ shutdown (listen_fd_, SHUT_RDWR );
139+ fd_to_close = listen_fd_;
140+ listen_fd_ = -1 ;
141+ }
142+ }
126143
127- shutdown (listen_fd_, SHUT_RDWR );
128- close (listen_fd_);
129- listen_fd_ = -1 ;
144+ {
145+ std::lock_guard<std::mutex> lock (thread_mutex_);
146+ if (accept_thread_.joinable ()) {
147+ accept_thread_.join ();
148+ }
130149
131- if (accept_thread_.joinable ()) {
132- accept_thread_.join ();
150+ /* Join all connection worker threads */
151+ for (auto & t : worker_threads_) {
152+ if (t.joinable ()) {
153+ t.join ();
154+ }
155+ }
156+ worker_threads_.clear ();
133157 }
134158
135- /* Join all connection worker threads */
136- std::lock_guard<std::mutex> lock (thread_mutex_);
137- for (auto & t : worker_threads_) {
138- if (t.joinable ()) {
139- t.join ();
140- }
159+ if (fd_to_close >= 0 ) {
160+ close (fd_to_close);
141161 }
142- worker_threads_.clear ();
143162
144- status_ = ServerStatus::Stopped;
163+ {
164+ std::lock_guard<std::mutex> lock (state_mutex_);
165+ status_ = ServerStatus::Stopped;
166+ }
145167 return true ;
146168}
147169
148170void Server::wait () {
171+ std::lock_guard<std::mutex> lock (thread_mutex_);
149172 if (accept_thread_.joinable ()) {
150173 accept_thread_.join ();
151174 }
152175}
153176
177+ bool Server::is_running () const {
178+ std::lock_guard<std::mutex> lock (state_mutex_);
179+ return running_;
180+ }
181+
182+ ServerStatus Server::get_status () const {
183+ std::lock_guard<std::mutex> lock (state_mutex_);
184+ return status_;
185+ }
186+
187+ int Server::get_listen_fd () const {
188+ std::lock_guard<std::mutex> lock (state_mutex_);
189+ return listen_fd_;
190+ }
191+
154192std::string Server::get_status_string () const {
155- switch (status_ ) {
193+ switch (get_status () ) {
156194 case ServerStatus::Stopped:
157195 return " Stopped" ;
158196 case ServerStatus::Starting:
@@ -169,13 +207,16 @@ std::string Server::get_status_string() const {
169207}
170208
171209void Server::accept_connections () {
172- while (running_. load ()) {
210+ while (is_running ()) {
173211 struct sockaddr_in client_addr;
174212 socklen_t client_len = sizeof (client_addr);
175213
176- int client_fd = accept (listen_fd_, (struct sockaddr *)&client_addr, &client_len);
214+ int fd = get_listen_fd ();
215+ if (fd < 0 ) break ;
216+
217+ int client_fd = accept (fd, (struct sockaddr *)&client_addr, &client_len);
177218 if (client_fd < 0 ) {
178- if (!running_. load ()) break ;
219+ if (!is_running ()) break ;
179220 continue ;
180221 }
181222
@@ -253,7 +294,7 @@ void Server::handle_connection(int client_fd) {
253294 send (client_fd, ready.data (), ready.size (), 0 );
254295
255296 /* 5. Main Message Loop */
256- while (running_. load ()) {
297+ while (is_running ()) {
257298 char type;
258299 n = recv (client_fd, &type, 1 , 0 );
259300 if (n <= 0 ) break ;
0 commit comments