Merge branch 'cmake-server-improve-shutdown' into release
This commit is contained in:
commit
5ffeb9bc13
|
@ -12,7 +12,7 @@
|
||||||
namespace {
|
namespace {
|
||||||
void on_directory_change(uv_fs_event_t* handle, const char* filename,
|
void on_directory_change(uv_fs_event_t* handle, const char* filename,
|
||||||
int events, int status);
|
int events, int status);
|
||||||
void on_handle_close(uv_handle_t* handle);
|
void on_fs_close(uv_handle_t* handle);
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class cmIBaseWatcher
|
class cmIBaseWatcher
|
||||||
|
@ -177,7 +177,7 @@ public:
|
||||||
{
|
{
|
||||||
if (this->Handle) {
|
if (this->Handle) {
|
||||||
uv_fs_event_stop(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;
|
this->Handle = nullptr;
|
||||||
}
|
}
|
||||||
cmVirtualDirectoryWatcher::StopWatching();
|
cmVirtualDirectoryWatcher::StopWatching();
|
||||||
|
@ -292,9 +292,9 @@ void on_directory_change(uv_fs_event_t* handle, const char* filename,
|
||||||
watcher->Trigger(pathSegment, events, status);
|
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
|
} // namespace
|
||||||
|
|
|
@ -30,7 +30,7 @@ void on_read(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf)
|
||||||
if (nread >= 0) {
|
if (nread >= 0) {
|
||||||
conn->ReadData(std::string(buf->base, buf->base + nread));
|
conn->ReadData(std::string(buf->base, buf->base + nread));
|
||||||
} else {
|
} else {
|
||||||
conn->HandleEof();
|
conn->TriggerShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[](buf->base);
|
delete[](buf->base);
|
||||||
|
@ -56,6 +56,28 @@ void on_new_connection(uv_stream_t* stream, int status)
|
||||||
conn->Connect(stream);
|
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
|
} // namespace
|
||||||
|
|
||||||
class LoopGuard
|
class LoopGuard
|
||||||
|
@ -64,19 +86,25 @@ public:
|
||||||
LoopGuard(cmServerConnection* connection)
|
LoopGuard(cmServerConnection* connection)
|
||||||
: Connection(connection)
|
: Connection(connection)
|
||||||
{
|
{
|
||||||
Connection->mLoop = uv_default_loop();
|
this->Connection->mLoop = uv_default_loop();
|
||||||
if (Connection->mLoop) {
|
if (!this->Connection->mLoop) {
|
||||||
Connection->mFileMonitor = new cmFileMonitor(Connection->mLoop);
|
return;
|
||||||
}
|
}
|
||||||
|
this->Connection->mFileMonitor =
|
||||||
|
new cmFileMonitor(this->Connection->mLoop);
|
||||||
}
|
}
|
||||||
|
|
||||||
~LoopGuard()
|
~LoopGuard()
|
||||||
{
|
{
|
||||||
if (Connection->mFileMonitor) {
|
if (!this->Connection->mLoop) {
|
||||||
delete Connection->mFileMonitor;
|
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:
|
private:
|
||||||
|
@ -111,6 +139,16 @@ bool cmServerConnection::ProcessEvents(std::string* errorMessage)
|
||||||
return false;
|
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)) {
|
if (!DoSetup(errorMessage)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -162,9 +200,21 @@ void cmServerConnection::ReadData(const std::string& data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmServerConnection::HandleEof()
|
void cmServerConnection::TriggerShutdown()
|
||||||
{
|
{
|
||||||
this->FileMonitor()->StopMonitoring();
|
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();
|
this->TearDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,30 +244,42 @@ void cmServerConnection::SendGreetings()
|
||||||
Server->PrintHello();
|
Server->PrintHello();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmServerStdIoConnection::cmServerStdIoConnection()
|
||||||
|
{
|
||||||
|
this->Input.tty = nullptr;
|
||||||
|
this->Output.tty = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool cmServerStdIoConnection::DoSetup(std::string* errorMessage)
|
bool cmServerStdIoConnection::DoSetup(std::string* errorMessage)
|
||||||
{
|
{
|
||||||
(void)(errorMessage);
|
(void)(errorMessage);
|
||||||
|
|
||||||
if (uv_guess_handle(1) == UV_TTY) {
|
if (uv_guess_handle(1) == UV_TTY) {
|
||||||
uv_tty_init(this->Loop(), &this->Input.tty, 0, 1);
|
usesTty = true;
|
||||||
uv_tty_set_mode(&this->Input.tty, UV_TTY_MODE_NORMAL);
|
this->Input.tty = new uv_tty_t;
|
||||||
Input.tty.data = this;
|
uv_tty_init(this->Loop(), this->Input.tty, 0, 1);
|
||||||
this->ReadStream = reinterpret_cast<uv_stream_t*>(&this->Input.tty);
|
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);
|
this->Output.tty = new uv_tty_t;
|
||||||
uv_tty_set_mode(&this->Output.tty, UV_TTY_MODE_NORMAL);
|
uv_tty_init(this->Loop(), this->Output.tty, 1, 0);
|
||||||
Output.tty.data = this;
|
uv_tty_set_mode(this->Output.tty, UV_TTY_MODE_NORMAL);
|
||||||
this->WriteStream = reinterpret_cast<uv_stream_t*>(&this->Output.tty);
|
Output.tty->data = this;
|
||||||
|
this->WriteStream = reinterpret_cast<uv_stream_t*>(this->Output.tty);
|
||||||
} else {
|
} else {
|
||||||
uv_pipe_init(this->Loop(), &this->Input.pipe, 0);
|
usesTty = false;
|
||||||
uv_pipe_open(&this->Input.pipe, 0);
|
this->Input.pipe = new uv_pipe_t;
|
||||||
Input.pipe.data = this;
|
uv_pipe_init(this->Loop(), this->Input.pipe, 0);
|
||||||
this->ReadStream = reinterpret_cast<uv_stream_t*>(&this->Input.pipe);
|
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);
|
this->Output.pipe = new uv_pipe_t;
|
||||||
uv_pipe_open(&this->Output.pipe, 1);
|
uv_pipe_init(this->Loop(), this->Output.pipe, 0);
|
||||||
Output.pipe.data = this;
|
uv_pipe_open(this->Output.pipe, 1);
|
||||||
this->WriteStream = reinterpret_cast<uv_stream_t*>(&this->Output.pipe);
|
Output.pipe->data = this;
|
||||||
|
this->WriteStream = reinterpret_cast<uv_stream_t*>(this->Output.pipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
SendGreetings();
|
SendGreetings();
|
||||||
|
@ -228,26 +290,35 @@ bool cmServerStdIoConnection::DoSetup(std::string* errorMessage)
|
||||||
|
|
||||||
void cmServerStdIoConnection::TearDown()
|
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;
|
this->ReadStream = nullptr;
|
||||||
uv_close(reinterpret_cast<uv_handle_t*>(this->WriteStream), nullptr);
|
|
||||||
this->WriteStream = nullptr;
|
this->WriteStream = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmServerPipeConnection::cmServerPipeConnection(const std::string& name)
|
cmServerPipeConnection::cmServerPipeConnection(const std::string& name)
|
||||||
: PipeName(name)
|
: PipeName(name)
|
||||||
{
|
{
|
||||||
this->ServerPipe.data = nullptr;
|
|
||||||
this->ClientPipe.data = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cmServerPipeConnection::DoSetup(std::string* errorMessage)
|
bool cmServerPipeConnection::DoSetup(std::string* errorMessage)
|
||||||
{
|
{
|
||||||
uv_pipe_init(this->Loop(), &this->ServerPipe, 0);
|
this->ServerPipe = new uv_pipe_t;
|
||||||
this->ServerPipe.data = this;
|
uv_pipe_init(this->Loop(), this->ServerPipe, 0);
|
||||||
|
this->ServerPipe->data = this;
|
||||||
|
|
||||||
int r;
|
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 +
|
*errorMessage = std::string("Internal Error with ") + this->PipeName +
|
||||||
": " + uv_err_name(r);
|
": " + uv_err_name(r);
|
||||||
return false;
|
return false;
|
||||||
|
@ -265,31 +336,34 @@ bool cmServerPipeConnection::DoSetup(std::string* errorMessage)
|
||||||
|
|
||||||
void cmServerPipeConnection::TearDown()
|
void cmServerPipeConnection::TearDown()
|
||||||
{
|
{
|
||||||
if (this->WriteStream->data) {
|
if (this->ClientPipe) {
|
||||||
uv_close(reinterpret_cast<uv_handle_t*>(this->WriteStream), nullptr);
|
uv_close(reinterpret_cast<uv_handle_t*>(this->ClientPipe), &on_pipe_close);
|
||||||
this->WriteStream->data = nullptr;
|
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->WriteStream = nullptr;
|
||||||
this->ReadStream = nullptr;
|
this->ReadStream = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmServerPipeConnection::Connect(uv_stream_t* server)
|
void cmServerPipeConnection::Connect(uv_stream_t* server)
|
||||||
{
|
{
|
||||||
if (this->ClientPipe.data == this) {
|
if (this->ClientPipe) {
|
||||||
// Accept and close all pipes but the first:
|
// 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);
|
uv_pipe_init(this->Loop(), rejectPipe, 0);
|
||||||
auto rejecter = reinterpret_cast<uv_stream_t*>(&rejectPipe);
|
auto rejecter = reinterpret_cast<uv_stream_t*>(rejectPipe);
|
||||||
uv_accept(server, rejecter);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_pipe_init(this->Loop(), &this->ClientPipe, 0);
|
this->ClientPipe = new uv_pipe_t;
|
||||||
this->ClientPipe.data = this;
|
uv_pipe_init(this->Loop(), this->ClientPipe, 0);
|
||||||
|
this->ClientPipe->data = this;
|
||||||
auto client = reinterpret_cast<uv_stream_t*>(&this->ClientPipe);
|
auto client = reinterpret_cast<uv_stream_t*>(&this->ClientPipe);
|
||||||
if (uv_accept(server, client) != 0) {
|
if (uv_accept(server, client) != 0) {
|
||||||
uv_close(reinterpret_cast<uv_handle_t*>(client), nullptr);
|
uv_close(reinterpret_cast<uv_handle_t*>(client), nullptr);
|
||||||
|
|
|
@ -24,7 +24,7 @@ public:
|
||||||
bool ProcessEvents(std::string* errorMessage);
|
bool ProcessEvents(std::string* errorMessage);
|
||||||
|
|
||||||
void ReadData(const std::string& data);
|
void ReadData(const std::string& data);
|
||||||
void HandleEof();
|
void TriggerShutdown();
|
||||||
void WriteData(const std::string& data);
|
void WriteData(const std::string& data);
|
||||||
void ProcessNextRequest();
|
void ProcessNextRequest();
|
||||||
|
|
||||||
|
@ -51,6 +51,8 @@ private:
|
||||||
uv_loop_t* mLoop = nullptr;
|
uv_loop_t* mLoop = nullptr;
|
||||||
cmFileMonitor* mFileMonitor = nullptr;
|
cmFileMonitor* mFileMonitor = nullptr;
|
||||||
cmServer* Server = nullptr;
|
cmServer* Server = nullptr;
|
||||||
|
uv_signal_t* SIGINTHandler = nullptr;
|
||||||
|
uv_signal_t* SIGHUPHandler = nullptr;
|
||||||
|
|
||||||
friend class LoopGuard;
|
friend class LoopGuard;
|
||||||
};
|
};
|
||||||
|
@ -58,6 +60,7 @@ private:
|
||||||
class cmServerStdIoConnection : public cmServerConnection
|
class cmServerStdIoConnection : public cmServerConnection
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
cmServerStdIoConnection();
|
||||||
bool DoSetup(std::string* errorMessage) override;
|
bool DoSetup(std::string* errorMessage) override;
|
||||||
|
|
||||||
void TearDown() override;
|
void TearDown() override;
|
||||||
|
@ -65,10 +68,12 @@ public:
|
||||||
private:
|
private:
|
||||||
typedef union
|
typedef union
|
||||||
{
|
{
|
||||||
uv_tty_t tty;
|
uv_tty_t* tty;
|
||||||
uv_pipe_t pipe;
|
uv_pipe_t* pipe;
|
||||||
} InOutUnion;
|
} InOutUnion;
|
||||||
|
|
||||||
|
bool usesTty = false;
|
||||||
|
|
||||||
InOutUnion Input;
|
InOutUnion Input;
|
||||||
InOutUnion Output;
|
InOutUnion Output;
|
||||||
};
|
};
|
||||||
|
@ -85,6 +90,6 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::string PipeName;
|
const std::string PipeName;
|
||||||
uv_pipe_t ServerPipe;
|
uv_pipe_t* ServerPipe = nullptr;
|
||||||
uv_pipe_t ClientPipe;
|
uv_pipe_t* ClientPipe = nullptr;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue