From: Pierre Ossman Date: Sat, 29 Sep 2018 09:24:19 +0000 (+0200) Subject: Properly terminate server on timeouts X-Git-Tag: v1.9.90~65^2~2 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=10688efcf759f24e83814f9e12a1275296b07a4c;p=tigervnc.git Properly terminate server on timeouts Do a proper cleanup when one of the termination timeouts trigger rather than just exiting on the spot. This makes sure we don't leave stray stuff around, e.g. unix socket files. --- diff --git a/common/rfb/SDesktop.h b/common/rfb/SDesktop.h index 61182469..0060aa23 100644 --- a/common/rfb/SDesktop.h +++ b/common/rfb/SDesktop.h @@ -75,6 +75,12 @@ namespace rfb { virtual void queryConnection(network::Socket* sock, const char* userName) = 0; + // terminate() is called by the server when it wishes to terminate + // itself, e.g. because it was configured to terminate when no one is + // using it. + + virtual void terminate() = 0; + // setScreenLayout() requests to reconfigure the framebuffer and/or // the layout of screens. virtual unsigned int setScreenLayout(int __unused_attr fb_width, diff --git a/common/rfb/VNCServerST.cxx b/common/rfb/VNCServerST.cxx index 352b80f2..601e6367 100644 --- a/common/rfb/VNCServerST.cxx +++ b/common/rfb/VNCServerST.cxx @@ -574,13 +574,13 @@ bool VNCServerST::handleTimeout(Timer* t) return true; } else if (t == &idleTimer) { slog.info("MaxIdleTime reached, exiting"); - exit(0); + desktop->terminate(); } else if (t == &disconnectTimer) { slog.info("MaxDisconnectionTime reached, exiting"); - exit(0); + desktop->terminate(); } else if (t == &connectTimer) { slog.info("MaxConnectionTime reached, exiting"); - exit(0); + desktop->terminate(); } return false; diff --git a/unix/x0vncserver/XDesktop.cxx b/unix/x0vncserver/XDesktop.cxx index 9a047c8e..3e67fad0 100644 --- a/unix/x0vncserver/XDesktop.cxx +++ b/unix/x0vncserver/XDesktop.cxx @@ -19,6 +19,8 @@ */ #include +#include +#include #include @@ -273,6 +275,10 @@ void XDesktop::stop() { pb = 0; } +void XDesktop::terminate() { + kill(getpid(), SIGTERM); +} + bool XDesktop::isRunning() { return running; } diff --git a/unix/x0vncserver/XDesktop.h b/unix/x0vncserver/XDesktop.h index 7d060613..3e85aac3 100644 --- a/unix/x0vncserver/XDesktop.h +++ b/unix/x0vncserver/XDesktop.h @@ -49,6 +49,7 @@ public: // -=- SDesktop interface virtual void start(rfb::VNCServer* vs); virtual void stop(); + virtual void terminate(); bool isRunning(); virtual void queryConnection(network::Socket* sock, const char* userName); diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc index e61472b3..d4891c3a 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.cc +++ b/unix/xserver/hw/vnc/XserverDesktop.cc @@ -22,6 +22,7 @@ // #include +#include #include #include #include @@ -423,6 +424,11 @@ void XserverDesktop::approveConnection(uint32_t opaqueId, bool accept, // SDesktop callbacks +void XserverDesktop::terminate() +{ + kill(getpid(), SIGTERM); +} + void XserverDesktop::pointerEvent(const Point& pos, int buttonMask) { vncPointerMove(pos.x + vncGetScreenX(screenIndex), diff --git a/unix/xserver/hw/vnc/XserverDesktop.h b/unix/xserver/hw/vnc/XserverDesktop.h index ff36b3b5..1253935f 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.h +++ b/unix/xserver/hw/vnc/XserverDesktop.h @@ -87,6 +87,7 @@ public: // rfb::SDesktop callbacks virtual void start(rfb::VNCServer* vs); virtual void stop(); + virtual void terminate(); virtual void queryConnection(network::Socket* sock, const char* userName); virtual void pointerEvent(const rfb::Point& pos, int buttonMask); diff --git a/win/rfb_win32/SDisplay.cxx b/win/rfb_win32/SDisplay.cxx index afb72ad7..2cedc4a8 100644 --- a/win/rfb_win32/SDisplay.cxx +++ b/win/rfb_win32/SDisplay.cxx @@ -71,6 +71,7 @@ SDisplay::SDisplay() statusLocation(0), queryConnectionHandler(0), ledState(0) { updateEvent.h = CreateEvent(0, TRUE, FALSE, 0); + terminateEvent.h = CreateEvent(0, TRUE, FALSE, 0); } SDisplay::~SDisplay() @@ -140,6 +141,11 @@ void SDisplay::stop() if (statusLocation) *statusLocation = false; } +void SDisplay::terminate() +{ + SetEvent(terminateEvent); +} + void SDisplay::queryConnection(network::Socket* sock, const char* userName) diff --git a/win/rfb_win32/SDisplay.h b/win/rfb_win32/SDisplay.h index 76ddf50b..6dbfabbc 100644 --- a/win/rfb_win32/SDisplay.h +++ b/win/rfb_win32/SDisplay.h @@ -72,6 +72,7 @@ namespace rfb { virtual void start(VNCServer* vs); virtual void stop(); + virtual void terminate(); virtual void queryConnection(network::Socket* sock, const char* userName); virtual void pointerEvent(const Point& pos, int buttonmask); @@ -89,6 +90,7 @@ namespace rfb { // -=- EventHandler interface HANDLE getUpdateEvent() {return updateEvent;} + HANDLE getTerminateEvent() {return terminateEvent;} virtual void processEvent(HANDLE event); // -=- Notification of whether or not SDisplay is started @@ -161,6 +163,8 @@ namespace rfb { // -=- Event signalled to trigger an update to be flushed Handle updateEvent; + // -=- Event signalled to terminate the server + Handle terminateEvent; // -=- Where to write the active/inactive indicator to bool* statusLocation; diff --git a/win/winvnc/VNCServerWin32.cxx b/win/winvnc/VNCServerWin32.cxx index 03b1bca7..e0014495 100644 --- a/win/winvnc/VNCServerWin32.cxx +++ b/win/winvnc/VNCServerWin32.cxx @@ -76,6 +76,7 @@ VNCServerWin32::VNCServerWin32() // Register the desktop's event to be handled sockMgr.addEvent(desktop.getUpdateEvent(), &desktop); + sockMgr.addEvent(desktop.getTerminateEvent(), this); // Register the queued command event to be handled sockMgr.addEvent(commandEvent, this); @@ -335,7 +336,8 @@ void VNCServerWin32::processEvent(HANDLE event_) { command = NoCommand; commandSig->signal(); } - } else if (event_ == sessionEvent.h) { + } else if ((event_ == sessionEvent.h) || + (event_ == desktop.getTerminateEvent())) { stop(); } }