[Libreoffice-commits] online.git: loolwsd/Admin.cpp loolwsd/DocumentBroker.hpp loolwsd/LOOLForKit.cpp loolwsd/Util.cpp loolwsd/Util.hpp
Ashod Nakashian
ashod.nakashian at collabora.co.uk
Mon Nov 14 05:29:42 UTC 2016
loolwsd/Admin.cpp | 11 ++++-------
loolwsd/DocumentBroker.hpp | 17 ++++++++---------
loolwsd/LOOLForKit.cpp | 2 +-
loolwsd/Util.cpp | 29 +++++++++++++++++++++++++++++
loolwsd/Util.hpp | 5 +++++
5 files changed, 47 insertions(+), 17 deletions(-)
New commits:
commit 6ad3b64d30a1398a9d355a7b9b9ab7ece1658c3f
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date: Sun Nov 13 16:12:01 2016 -0500
loolwsd: kill children using SIGTERM from via a helper function
Change-Id: I901183fc59725681208a5c0f23f0916e158e5654
Reviewed-on: https://gerrit.libreoffice.org/30825
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
Tested-by: Ashod Nakashian <ashnakash at gmail.com>
diff --git a/loolwsd/Admin.cpp b/loolwsd/Admin.cpp
index e8d9d3a..9fc3535 100644
--- a/loolwsd/Admin.cpp
+++ b/loolwsd/Admin.cpp
@@ -123,15 +123,12 @@ bool AdminRequestHandler::adminCommandHandler(const std::vector<char>& payload)
try
{
const auto pid = std::stoi(tokens[1]);
- if (kill(pid, SIGINT) != 0 && kill(pid, 0) !=0)
- {
- LOG_SYS("Cannot terminate PID: " << tokens[0]);
- }
+ LOG_INF("Admin request to kill PID: " << pid);
+ Util::killChild(pid);
}
- catch(std::invalid_argument& exc)
+ catch (std::invalid_argument& exc)
{
- Log::warn() << "Invalid PID to kill: " << tokens[0] << Log::end;
- return false;
+ LOG_WRN("Invalid PID to kill: " << tokens[1]);
}
}
else if (tokens[0] == "settings")
diff --git a/loolwsd/DocumentBroker.hpp b/loolwsd/DocumentBroker.hpp
index 6906391..2184925 100644
--- a/loolwsd/DocumentBroker.hpp
+++ b/loolwsd/DocumentBroker.hpp
@@ -96,24 +96,21 @@ public:
}
_ws.reset();
- if (_pid != -1 && kill(_pid, 0) != 0)
+ if (_pid != -1 && rude && kill(_pid, 0) != 0 && errno != ESRCH)
{
- if (errno != ESRCH && rude)
+ LOG_INF("Killing child [" << _pid << "].");
+ if (Util::killChild(_pid))
{
- LOG_INF("Killing child [" << _pid << "].");
- if (kill(_pid, SIGINT) != 0 && kill(_pid, 0) != 0 && errno != ESRCH)
- {
- LOG_SYS("Cannot terminate lokit [" << _pid << "]. Abandoning.");
- }
+ LOG_ERR("Cannot terminate lokit [" << _pid << "]. Abandoning.");
}
}
-
- _pid = -1;
}
catch (const std::exception& ex)
{
LOG_ERR("Error while closing child process: " << ex.what());
}
+
+ _pid = -1;
}
Poco::Process::PID getPid() const { return _pid; }
@@ -142,6 +139,8 @@ public:
}
/// Check whether this child is alive and able to respond.
+ /// Note: zombies will show as alive, and sockets have waiting
+ /// time after the other end-point closes. So this isn't accurate.
bool isAlive() const
{
try
diff --git a/loolwsd/LOOLForKit.cpp b/loolwsd/LOOLForKit.cpp
index f234405..75156a0 100644
--- a/loolwsd/LOOLForKit.cpp
+++ b/loolwsd/LOOLForKit.cpp
@@ -77,7 +77,7 @@ public:
}
else if (ready < 0)
{
- // Termination is done via SIGINT, which breaks the wait.
+ // Termination is done via SIGTERM, which breaks the wait.
if (!TerminationFlag)
{
Log::error("Error reading from pipe [" + getName() + "].");
diff --git a/loolwsd/Util.cpp b/loolwsd/Util.cpp
index e3a2b02..b5c26a7 100644
--- a/loolwsd/Util.cpp
+++ b/loolwsd/Util.cpp
@@ -32,6 +32,7 @@
#include <random>
#include <sstream>
#include <string>
+#include <thread>
#include <Poco/Base64Encoder.h>
#include <Poco/ConsoleChannel.h>
@@ -397,6 +398,34 @@ namespace Util
static std::atomic_int counter(0);
return std::to_string(Poco::Process::id()) + "/" + std::to_string(counter++);
}
+
+ bool killChild(const int pid)
+ {
+ LOG_DBG("Killing PID: " << pid);
+ if (kill(pid, SIGTERM) == 0 || errno == ESRCH)
+ {
+ // Killed or doesn't exist.
+ return true;
+ }
+
+ LOG_SYS("Error when trying to kill PID: " << pid << ". Will wait for termination.");
+
+ const auto sleepMs = 50;
+ const auto count = std::max(CHILD_REBALANCE_INTERVAL_MS / sleepMs, 2);
+ for (int i = 0; i < count; ++i)
+ {
+ if (kill(pid, 0) == 0 || errno == ESRCH)
+ {
+ // Doesn't exist.
+ return true;
+ }
+
+ std::this_thread::sleep_for(std::chrono::milliseconds(sleepMs));
+ }
+
+ LOG_WRN("Cannot terminate PID: " << pid);
+ return false;
+ }
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/loolwsd/Util.hpp b/loolwsd/Util.hpp
index 7e4170f..93c95f7 100644
--- a/loolwsd/Util.hpp
+++ b/loolwsd/Util.hpp
@@ -88,6 +88,11 @@ namespace Util
void requestTermination(const Poco::Process::PID& pid);
+ /// Kills a child process and returns true when
+ /// child pid is removed from the process table
+ /// after a certain (short) timeout.
+ bool killChild(const int pid);
+
int getMemoryUsage(const Poco::Process::PID nPid);
std::string replace(const std::string& s, const std::string& a, const std::string& b);
More information about the Libreoffice-commits
mailing list