From 21e289aca72dc73576248cdabb4b421aa2b60536 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sun, 28 Oct 2018 15:49:46 +0000 Subject: [PATCH] fixed a race condition issue in TcpServer::stop() --- qse/lib/si/App.cpp | 2 +- qse/lib/si/TcpServer.cpp | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/qse/lib/si/App.cpp b/qse/lib/si/App.cpp index 59951080..36d29895 100644 --- a/qse/lib/si/App.cpp +++ b/qse/lib/si/App.cpp @@ -344,7 +344,7 @@ int App::unset_signal_handler_no_mutex(int sig, int ignore) if (sl._state == App::SIGNAL_ACCEPTED) { // the actual signal handler is called with the mutex locked. - // it must not call acceptSingal()/discardSignal()neglectSingal() + // it must not call acceptSingal()/discardSignal()/neglectSingal() // from within the handler. if (app->_guarded_child_pid >= 0) app->on_guard_signal (sig); app->on_signal (sig); diff --git a/qse/lib/si/TcpServer.cpp b/qse/lib/si/TcpServer.cpp index 419684f4..dba1c203 100644 --- a/qse/lib/si/TcpServer.cpp +++ b/qse/lib/si/TcpServer.cpp @@ -436,13 +436,20 @@ int TcpServer::stop () QSE_CPP_NOEXCEPT { if (this->server_serving) { + // set stop request before writing "Q" to avoid race condition. + // after qse_mux_poll() detects activity for "Q" written, + // it loops over to another qse_mux_poll(). the stop request + // test is done in between. if this looping is faster than + // setting stop request after "Q" writing, the second qse_mux_poll() + // doesn't see it set to true yet. + this->setStopRequested (true); + this->listener_list.mux_pipe_spl.lock (); if (this->listener_list.mux_pipe[1] >= 0) { ::write (this->listener_list.mux_pipe[1], "Q", 1); } this->listener_list.mux_pipe_spl.unlock (); - this->setStopRequested (true); } return 0; }