提交 15cef6f2 编写于 作者: Y youngwolf

Make function server_base::start_listen() and server_base::stop_listen thread safe.

Fix race condition during call acceptor::async_accept concurrently.
上级 5e1f17ba
......@@ -182,7 +182,7 @@ public:
normal_server(service_pump& service_pump_) : server_base(service_pump_) {}
protected:
virtual int async_accept_num() {return 1;} //this make on_accept to be called in single thread, because stop_listen() is not thread safe
virtual int async_accept_num() {return 1;}
virtual bool on_accept(object_ctype& socket_ptr) {stop_listen(); return true;}
};
......
......@@ -664,8 +664,10 @@
*
* HIGHLIGHT:
* Support changing the send buffer and recv buffer at runtime.
* Make function server_base::start_listen() and server_base::stop_listen thread safe.
*
* FIX:
* Fix race condition during call acceptor::async_accept concurrently.
*
* ENHANCEMENTS:
* Try parsing messages even errors occurred.
......
......@@ -49,6 +49,10 @@ public:
bool start_listen()
{
std::lock_guard<std::mutex> lock(mutex);
if (is_listening())
return false;
asio::error_code ec;
if (!acceptor.is_open()) {acceptor.open(server_addr.protocol(), ec); assert(!ec);} //user maybe has opened this acceptor (to set options for example)
#ifndef ASCS_NOT_REUSE_ADDRESS
......@@ -88,7 +92,7 @@ public:
return true;
}
bool is_listening() const {return acceptor.is_open();}
void stop_listen() {asio::error_code ec; acceptor.cancel(ec); acceptor.close(ec);}
void stop_listen() {std::lock_guard<std::mutex> lock(mutex); asio::error_code ec; acceptor.cancel(ec); acceptor.close(ec);}
asio::ip::tcp::acceptor& next_layer() {return acceptor;}
const asio::ip::tcp::acceptor& next_layer() const {return acceptor;}
......@@ -158,7 +162,7 @@ protected:
virtual void uninit() {this->stop(); stop_listen(); force_shutdown();} //if you wanna graceful shutdown, call graceful_shutdown before service_pump::stop_service invocation.
virtual bool on_accept(typename Pool::object_ctype& socket_ptr) {return true;}
virtual void start_next_accept() {do_async_accept(create_object());}
virtual void start_next_accept() {std::lock_guard<std::mutex> lock(mutex); do_async_accept(create_object());}
//if you want to ignore this error and continue to accept new connections immediately, return true in this virtual function;
//if you want to ignore this error and continue to accept new connections after a specific delay, start a timer immediately and return false (don't call stop_listen()),
......@@ -216,6 +220,7 @@ private:
private:
asio::ip::tcp::endpoint server_addr;
asio::ip::tcp::acceptor acceptor;
std::mutex mutex;
};
}} //namespace
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册