[Cmake-commits] CMake branch, next, updated. v3.6.2-1318-gae55ba6

Brad King brad.king at kitware.com
Tue Oct 4 09:18:35 EDT 2016


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  ae55ba6c866b3b5ea76b3edaefa4226c1815b11d (commit)
       via  68277e16c474ca48e4aabd36603fd9ec4466fe28 (commit)
      from  f3f0ad74f30e540b6ab60840e63f33e1edd97508 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ae55ba6c866b3b5ea76b3edaefa4226c1815b11d
commit ae55ba6c866b3b5ea76b3edaefa4226c1815b11d
Merge: f3f0ad7 68277e1
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Oct 4 09:18:34 2016 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Tue Oct 4 09:18:34 2016 -0400

    Merge topic 'cmake-server-improve-shutdown' into next
    
    68277e16 server-mode: Improve shutdown behavior


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=68277e16c474ca48e4aabd36603fd9ec4466fe28
commit 68277e16c474ca48e4aabd36603fd9ec4466fe28
Author:     Tobias Hunger <tobias.hunger at qt.io>
AuthorDate: Tue Oct 4 13:28:38 2016 +0200
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Oct 4 09:15:32 2016 -0400

    server-mode: Improve shutdown behavior
    
    Add a signal handler to trigger shutdown and be more paranoid about
    libuv doing things asynchronously.  This should fix test cases not
    shutting down properly.

diff --git a/Source/cmFileMonitor.cxx b/Source/cmFileMonitor.cxx
index b97590b..41ec8b4 100644
--- a/Source/cmFileMonitor.cxx
+++ b/Source/cmFileMonitor.cxx
@@ -12,7 +12,7 @@
 namespace {
 void on_directory_change(uv_fs_event_t* handle, const char* filename,
                          int events, int status);
-void on_handle_close(uv_handle_t* handle);
+void on_fs_close(uv_handle_t* handle);
 } // namespace
 
 class cmIBaseWatcher
@@ -177,7 +177,7 @@ public:
   {
     if (this->Handle) {
       uv_fs_event_stop(this->Handle);
-      uv_close(reinterpret_cast<uv_handle_t*>(this->Handle), &on_handle_close);
+      uv_close(reinterpret_cast<uv_handle_t*>(this->Handle), &on_fs_close);
       this->Handle = nullptr;
     }
     cmVirtualDirectoryWatcher::StopWatching();
@@ -292,9 +292,9 @@ void on_directory_change(uv_fs_event_t* handle, const char* filename,
   watcher->Trigger(pathSegment, events, status);
 }
 
-void on_handle_close(uv_handle_t* handle)
+void on_fs_close(uv_handle_t* handle)
 {
-  delete (reinterpret_cast<uv_fs_event_t*>(handle));
+  delete reinterpret_cast<uv_fs_event_t*>(handle);
 }
 
 } // namespace
diff --git a/Source/cmServerConnection.cxx b/Source/cmServerConnection.cxx
index c9822d3..a814d16 100644
--- a/Source/cmServerConnection.cxx
+++ b/Source/cmServerConnection.cxx
@@ -30,7 +30,7 @@ void on_read(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf)
   if (nread >= 0) {
     conn->ReadData(std::string(buf->base, buf->base + nread));
   } else {
-    conn->HandleEof();
+    conn->TriggerShutdown();
   }
 
   delete[](buf->base);
@@ -56,6 +56,28 @@ void on_new_connection(uv_stream_t* stream, int status)
   conn->Connect(stream);
 }
 
+void on_signal(uv_signal_t* signal, int signum)
+{
+  auto conn = reinterpret_cast<cmServerConnection*>(signal->data);
+  (void)(signum);
+  conn->TriggerShutdown();
+}
+
+void on_signal_close(uv_handle_t* handle)
+{
+  delete reinterpret_cast<uv_signal_t*>(handle);
+}
+
+void on_pipe_close(uv_handle_t* handle)
+{
+  delete reinterpret_cast<uv_pipe_t*>(handle);
+}
+
+void on_tty_close(uv_handle_t* handle)
+{
+  delete reinterpret_cast<uv_tty_t*>(handle);
+}
+
 } // namespace
 
 class LoopGuard
@@ -64,19 +86,25 @@ public:
   LoopGuard(cmServerConnection* connection)
     : Connection(connection)
   {
-    Connection->mLoop = uv_default_loop();
-    if (Connection->mLoop) {
-      Connection->mFileMonitor = new cmFileMonitor(Connection->mLoop);
+    this->Connection->mLoop = uv_default_loop();
+    if (!this->Connection->mLoop) {
+      return;
     }
+    this->Connection->mFileMonitor =
+      new cmFileMonitor(this->Connection->mLoop);
   }
 
   ~LoopGuard()
   {
-    if (Connection->mFileMonitor) {
-      delete Connection->mFileMonitor;
+    if (!this->Connection->mLoop) {
+      return;
     }
-    uv_loop_close(Connection->mLoop);
-    Connection->mLoop = nullptr;
+
+    if (this->Connection->mFileMonitor) {
+      delete this->Connection->mFileMonitor;
+    }
+    uv_loop_close(this->Connection->mLoop);
+    this->Connection->mLoop = nullptr;
   }
 
 private:
@@ -111,6 +139,16 @@ bool cmServerConnection::ProcessEvents(std::string* errorMessage)
     return false;
   }
 
+  this->SIGINTHandler = new uv_signal_t;
+  uv_signal_init(this->mLoop, this->SIGINTHandler);
+  this->SIGINTHandler->data = static_cast<void*>(this);
+  uv_signal_start(this->SIGINTHandler, &on_signal, SIGINT);
+
+  this->SIGHUPHandler = new uv_signal_t;
+  uv_signal_init(this->mLoop, this->SIGHUPHandler);
+  this->SIGHUPHandler->data = static_cast<void*>(this);
+  uv_signal_start(this->SIGHUPHandler, &on_signal, SIGHUP);
+
   if (!DoSetup(errorMessage)) {
     return false;
   }
@@ -162,9 +200,21 @@ void cmServerConnection::ReadData(const std::string& data)
   }
 }
 
-void cmServerConnection::HandleEof()
+void cmServerConnection::TriggerShutdown()
 {
   this->FileMonitor()->StopMonitoring();
+
+  uv_signal_stop(this->SIGINTHandler);
+  uv_signal_stop(this->SIGHUPHandler);
+
+  uv_close(reinterpret_cast<uv_handle_t*>(this->SIGINTHandler),
+           &on_signal_close); // delete handle
+  uv_close(reinterpret_cast<uv_handle_t*>(this->SIGHUPHandler),
+           &on_signal_close); // delete handle
+
+  this->SIGINTHandler = nullptr;
+  this->SIGHUPHandler = nullptr;
+
   this->TearDown();
 }
 
@@ -194,30 +244,42 @@ void cmServerConnection::SendGreetings()
   Server->PrintHello();
 }
 
+cmServerStdIoConnection::cmServerStdIoConnection()
+{
+  this->Input.tty = nullptr;
+  this->Output.tty = nullptr;
+}
+
 bool cmServerStdIoConnection::DoSetup(std::string* errorMessage)
 {
   (void)(errorMessage);
 
   if (uv_guess_handle(1) == UV_TTY) {
-    uv_tty_init(this->Loop(), &this->Input.tty, 0, 1);
-    uv_tty_set_mode(&this->Input.tty, UV_TTY_MODE_NORMAL);
-    Input.tty.data = this;
-    this->ReadStream = reinterpret_cast<uv_stream_t*>(&this->Input.tty);
-
-    uv_tty_init(this->Loop(), &this->Output.tty, 1, 0);
-    uv_tty_set_mode(&this->Output.tty, UV_TTY_MODE_NORMAL);
-    Output.tty.data = this;
-    this->WriteStream = reinterpret_cast<uv_stream_t*>(&this->Output.tty);
+    usesTty = true;
+    this->Input.tty = new uv_tty_t;
+    uv_tty_init(this->Loop(), this->Input.tty, 0, 1);
+    uv_tty_set_mode(this->Input.tty, UV_TTY_MODE_NORMAL);
+    Input.tty->data = this;
+    this->ReadStream = reinterpret_cast<uv_stream_t*>(this->Input.tty);
+
+    this->Output.tty = new uv_tty_t;
+    uv_tty_init(this->Loop(), this->Output.tty, 1, 0);
+    uv_tty_set_mode(this->Output.tty, UV_TTY_MODE_NORMAL);
+    Output.tty->data = this;
+    this->WriteStream = reinterpret_cast<uv_stream_t*>(this->Output.tty);
   } else {
-    uv_pipe_init(this->Loop(), &this->Input.pipe, 0);
-    uv_pipe_open(&this->Input.pipe, 0);
-    Input.pipe.data = this;
-    this->ReadStream = reinterpret_cast<uv_stream_t*>(&this->Input.pipe);
-
-    uv_pipe_init(this->Loop(), &this->Output.pipe, 0);
-    uv_pipe_open(&this->Output.pipe, 1);
-    Output.pipe.data = this;
-    this->WriteStream = reinterpret_cast<uv_stream_t*>(&this->Output.pipe);
+    usesTty = false;
+    this->Input.pipe = new uv_pipe_t;
+    uv_pipe_init(this->Loop(), this->Input.pipe, 0);
+    uv_pipe_open(this->Input.pipe, 0);
+    Input.pipe->data = this;
+    this->ReadStream = reinterpret_cast<uv_stream_t*>(this->Input.pipe);
+
+    this->Output.pipe = new uv_pipe_t;
+    uv_pipe_init(this->Loop(), this->Output.pipe, 0);
+    uv_pipe_open(this->Output.pipe, 1);
+    Output.pipe->data = this;
+    this->WriteStream = reinterpret_cast<uv_stream_t*>(this->Output.pipe);
   }
 
   SendGreetings();
@@ -228,26 +290,35 @@ bool cmServerStdIoConnection::DoSetup(std::string* errorMessage)
 
 void cmServerStdIoConnection::TearDown()
 {
-  uv_close(reinterpret_cast<uv_handle_t*>(this->ReadStream), nullptr);
+  if (usesTty) {
+    uv_close(reinterpret_cast<uv_handle_t*>(this->Input.tty), &on_tty_close);
+    uv_close(reinterpret_cast<uv_handle_t*>(this->Output.tty), &on_tty_close);
+    this->Input.tty = nullptr;
+    this->Output.tty = nullptr;
+  } else {
+    uv_close(reinterpret_cast<uv_handle_t*>(this->Input.pipe), &on_pipe_close);
+    uv_close(reinterpret_cast<uv_handle_t*>(this->Output.pipe),
+             &on_pipe_close);
+    this->Input.pipe = nullptr;
+    this->Input.pipe = nullptr;
+  }
   this->ReadStream = nullptr;
-  uv_close(reinterpret_cast<uv_handle_t*>(this->WriteStream), nullptr);
   this->WriteStream = nullptr;
 }
 
 cmServerPipeConnection::cmServerPipeConnection(const std::string& name)
   : PipeName(name)
 {
-  this->ServerPipe.data = nullptr;
-  this->ClientPipe.data = nullptr;
 }
 
 bool cmServerPipeConnection::DoSetup(std::string* errorMessage)
 {
-  uv_pipe_init(this->Loop(), &this->ServerPipe, 0);
-  this->ServerPipe.data = this;
+  this->ServerPipe = new uv_pipe_t;
+  uv_pipe_init(this->Loop(), this->ServerPipe, 0);
+  this->ServerPipe->data = this;
 
   int r;
-  if ((r = uv_pipe_bind(&this->ServerPipe, this->PipeName.c_str())) != 0) {
+  if ((r = uv_pipe_bind(this->ServerPipe, this->PipeName.c_str())) != 0) {
     *errorMessage = std::string("Internal Error with ") + this->PipeName +
       ": " + uv_err_name(r);
     return false;
@@ -265,31 +336,34 @@ bool cmServerPipeConnection::DoSetup(std::string* errorMessage)
 
 void cmServerPipeConnection::TearDown()
 {
-  if (this->WriteStream->data) {
-    uv_close(reinterpret_cast<uv_handle_t*>(this->WriteStream), nullptr);
+  if (this->ClientPipe) {
+    uv_close(reinterpret_cast<uv_handle_t*>(this->ClientPipe), &on_pipe_close);
     this->WriteStream->data = nullptr;
   }
-  uv_close(reinterpret_cast<uv_handle_t*>(&this->ServerPipe), nullptr);
+  uv_close(reinterpret_cast<uv_handle_t*>(&this->ServerPipe), &on_pipe_close);
 
+  this->ClientPipe = nullptr;
+  this->ServerPipe = nullptr;
   this->WriteStream = nullptr;
   this->ReadStream = nullptr;
 }
 
 void cmServerPipeConnection::Connect(uv_stream_t* server)
 {
-  if (this->ClientPipe.data == this) {
+  if (this->ClientPipe) {
     // Accept and close all pipes but the first:
-    uv_pipe_t rejectPipe;
+    uv_pipe_t* rejectPipe = new uv_pipe_t;
 
-    uv_pipe_init(this->Loop(), &rejectPipe, 0);
-    auto rejecter = reinterpret_cast<uv_stream_t*>(&rejectPipe);
+    uv_pipe_init(this->Loop(), rejectPipe, 0);
+    auto rejecter = reinterpret_cast<uv_stream_t*>(rejectPipe);
     uv_accept(server, rejecter);
-    uv_close(reinterpret_cast<uv_handle_t*>(rejecter), nullptr);
+    uv_close(reinterpret_cast<uv_handle_t*>(rejecter), &on_pipe_close);
     return;
   }
 
-  uv_pipe_init(this->Loop(), &this->ClientPipe, 0);
-  this->ClientPipe.data = this;
+  this->ClientPipe = new uv_pipe_t;
+  uv_pipe_init(this->Loop(), this->ClientPipe, 0);
+  this->ClientPipe->data = this;
   auto client = reinterpret_cast<uv_stream_t*>(&this->ClientPipe);
   if (uv_accept(server, client) != 0) {
     uv_close(reinterpret_cast<uv_handle_t*>(client), nullptr);
diff --git a/Source/cmServerConnection.h b/Source/cmServerConnection.h
index 78842e7..3efe28d 100644
--- a/Source/cmServerConnection.h
+++ b/Source/cmServerConnection.h
@@ -24,7 +24,7 @@ public:
   bool ProcessEvents(std::string* errorMessage);
 
   void ReadData(const std::string& data);
-  void HandleEof();
+  void TriggerShutdown();
   void WriteData(const std::string& data);
   void ProcessNextRequest();
 
@@ -51,6 +51,8 @@ private:
   uv_loop_t* mLoop = nullptr;
   cmFileMonitor* mFileMonitor = nullptr;
   cmServer* Server = nullptr;
+  uv_signal_t* SIGINTHandler = nullptr;
+  uv_signal_t* SIGHUPHandler = nullptr;
 
   friend class LoopGuard;
 };
@@ -58,6 +60,7 @@ private:
 class cmServerStdIoConnection : public cmServerConnection
 {
 public:
+  cmServerStdIoConnection();
   bool DoSetup(std::string* errorMessage) override;
 
   void TearDown() override;
@@ -65,10 +68,12 @@ public:
 private:
   typedef union
   {
-    uv_tty_t tty;
-    uv_pipe_t pipe;
+    uv_tty_t* tty;
+    uv_pipe_t* pipe;
   } InOutUnion;
 
+  bool usesTty = false;
+
   InOutUnion Input;
   InOutUnion Output;
 };
@@ -85,6 +90,6 @@ public:
 
 private:
   const std::string PipeName;
-  uv_pipe_t ServerPipe;
-  uv_pipe_t ClientPipe;
+  uv_pipe_t* ServerPipe = nullptr;
+  uv_pipe_t* ClientPipe = nullptr;
 };

-----------------------------------------------------------------------

Summary of changes:
 Source/cmFileMonitor.cxx      |    8 +-
 Source/cmServerConnection.cxx |  162 ++++++++++++++++++++++++++++++-----------
 Source/cmServerConnection.h   |   15 ++--
 3 files changed, 132 insertions(+), 53 deletions(-)


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list