[Libreoffice-commits] online.git: wsd/Admin.cpp wsd/Admin.hpp wsd/AdminModel.cpp wsd/AdminModel.hpp
Michael Meeks (via logerrit)
logerrit at kemper.freedesktop.org
Sat Apr 25 07:11:31 UTC 2020
wsd/Admin.cpp | 2
wsd/Admin.hpp | 2
wsd/AdminModel.cpp | 115 ++++++++++++++++++++++++++---------------------------
wsd/AdminModel.hpp | 11 +++--
4 files changed, 69 insertions(+), 61 deletions(-)
New commits:
commit b0f7cf992fb0abb153698a505922e9ed3ed24bcc
Author: Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Sat Apr 25 07:45:43 2020 +0100
Commit: Michael Meeks <michael.meeks at collabora.com>
CommitDate: Sat Apr 25 09:11:13 2020 +0200
Admin: cleanup lifecycle of Document.
When moving items across to _expiredDocuments we could end up
default copy constructors and destructors instead of swapping,
which can cause grief when extended. Switch to unique_ptr to
protect us in the future & clean.
Change-Id: I5bcdb95786c783eaacde972bbed4e5e7efc67f02
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/92888
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
diff --git a/wsd/Admin.cpp b/wsd/Admin.cpp
index 8f98cce64..f5a3d80a4 100644
--- a/wsd/Admin.cpp
+++ b/wsd/Admin.cpp
@@ -45,6 +45,7 @@ using Poco::Util::Application;
const int Admin::MinStatsIntervalMs = 50;
const int Admin::DefStatsIntervalMs = 1000;
+
/// Process incoming websocket messages
void AdminSocketHandler::handleMessage(const std::vector<char> &payload)
{
@@ -362,7 +363,6 @@ bool AdminSocketHandler::handleInitialRequest(
/// An admin command processor.
Admin::Admin() :
SocketPoll("admin"),
- _model(AdminModel()),
_forKitPid(-1),
_lastTotalMemory(0),
_lastJiffies(0),
diff --git a/wsd/Admin.hpp b/wsd/Admin.hpp
index 701cf2e9d..32b2ebeab 100644
--- a/wsd/Admin.hpp
+++ b/wsd/Admin.hpp
@@ -56,6 +56,8 @@ class MemoryStatsTask;
/// An admin command processor.
class Admin : public SocketPoll
{
+ Admin(const Admin &) = delete;
+ Admin& operator = (const Admin &) = delete;
Admin();
public:
virtual ~Admin();
diff --git a/wsd/AdminModel.cpp b/wsd/AdminModel.cpp
index 0d507e33e..0a69e9891 100644
--- a/wsd/AdminModel.cpp
+++ b/wsd/AdminModel.cpp
@@ -201,7 +201,7 @@ std::string AdminModel::getAllHistory() const
for (const auto& d : _documents)
{
oss << separator1;
- oss << d.second.getHistory();
+ oss << d.second->getHistory();
separator1 = ",";
}
oss << "], \"expiredDocuments\" : [";
@@ -209,7 +209,7 @@ std::string AdminModel::getAllHistory() const
for (const auto& ed : _expiredDocuments)
{
oss << separator1;
- oss << ed.second.getHistory();
+ oss << ed.second->getHistory();
separator1 = ",";
}
oss << "]}";
@@ -274,9 +274,9 @@ unsigned AdminModel::getKitsMemoryUsage()
unsigned docs = 0;
for (const auto& it : _documents)
{
- if (!it.second.isExpired())
+ if (!it.second->isExpired())
{
- const int bytes = it.second.getMemoryDirty();
+ const int bytes = it.second->getMemoryDirty();
if (bytes > 0)
{
totalMem += bytes;
@@ -301,17 +301,17 @@ size_t AdminModel::getKitsJiffies()
size_t totalJ = 0;
for (auto& it : _documents)
{
- if (!it.second.isExpired())
+ if (!it.second->isExpired())
{
- const int pid = it.second.getPid();
+ const int pid = it.second->getPid();
if (pid > 0)
{
unsigned newJ = Util::getCpuUsage(pid);
- unsigned prevJ = it.second.getLastJiffies();
+ unsigned prevJ = it.second->getLastJiffies();
if(newJ >= prevJ)
{
totalJ += (newJ - prevJ);
- it.second.setLastJiffies(newJ);
+ it.second->setLastJiffies(newJ);
}
}
}
@@ -459,7 +459,7 @@ void AdminModel::addBytes(const std::string& docKey, uint64_t sent, uint64_t rec
auto doc = _documents.find(docKey);
if(doc != _documents.end())
- doc->second.addBytes(sent, recv);
+ doc->second->addBytes(sent, recv);
_sentBytesTotal += sent;
_recvBytesTotal += recv;
@@ -471,7 +471,7 @@ void AdminModel::modificationAlert(const std::string& docKey, Poco::Process::PID
auto doc = _documents.find(docKey);
if (doc != _documents.end())
- doc->second.setModified(value);
+ doc->second->setModified(value);
std::ostringstream oss;
oss << "modifications "
@@ -487,9 +487,9 @@ void AdminModel::addDocument(const std::string& docKey, Poco::Process::PID pid,
{
assertCorrectThread();
- const auto ret = _documents.emplace(docKey, Document(docKey, pid, filename));
- ret.first->second.takeSnapshot();
- ret.first->second.addView(sessionId, userName, userId);
+ const auto ret = _documents.emplace(docKey, std::unique_ptr<Document>(new Document(docKey, pid, filename)));
+ ret.first->second->takeSnapshot();
+ ret.first->second->addView(sessionId, userName, userId);
LOG_DBG("Added admin document [" << docKey << "].");
std::string encodedUsername;
@@ -524,7 +524,7 @@ void AdminModel::addDocument(const std::string& docKey, Poco::Process::PID pid,
}
else
{
- oss << _documents.begin()->second.getMemoryDirty();
+ oss << _documents.begin()->second->getMemoryDirty();
}
notify(oss.str());
@@ -535,22 +535,24 @@ void AdminModel::removeDocument(const std::string& docKey, const std::string& se
assertCorrectThread();
auto docIt = _documents.find(docKey);
- if (docIt != _documents.end() && !docIt->second.isExpired())
+ if (docIt != _documents.end() && !docIt->second->isExpired())
{
// Notify the subscribers
std::ostringstream oss;
oss << "rmdoc "
- << docIt->second.getPid() << ' '
+ << docIt->second->getPid() << ' '
<< sessionId;
notify(oss.str());
// The idea is to only expire the document and keep the history
// of documents open and close, to be able to give a detailed summary
// to the admin console with views.
- if (docIt->second.expireView(sessionId) == 0)
+ if (docIt->second->expireView(sessionId) == 0)
{
- _expiredDocuments.emplace(docIt->first + std::to_string(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch()).count()), docIt->second);
+ std::unique_ptr<Document> doc;
+ std::swap(doc, docIt->second);
_documents.erase(docIt);
+ _expiredDocuments.emplace(docIt->first + std::to_string(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch()).count()), std::move(doc));
}
}
}
@@ -564,19 +566,21 @@ void AdminModel::removeDocument(const std::string& docKey)
{
std::ostringstream oss;
oss << "rmdoc "
- << docIt->second.getPid() << ' ';
+ << docIt->second->getPid() << ' ';
const std::string msg = oss.str();
- for (const auto& pair : docIt->second.getViews())
+ for (const auto& pair : docIt->second->getViews())
{
// Notify the subscribers
notify(msg + pair.first);
- docIt->second.expireView(pair.first);
+ docIt->second->expireView(pair.first);
}
LOG_DBG("Removed admin document [" << docKey << "].");
- _expiredDocuments.emplace(docIt->first + std::to_string(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch()).count()), docIt->second);
+ std::unique_ptr<Document> doc;
+ std::swap(doc, docIt->second);
_documents.erase(docIt);
+ _expiredDocuments.emplace(docIt->first + std::to_string(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch()).count()), std::move(doc));
}
}
@@ -639,9 +643,9 @@ unsigned AdminModel::getTotalActiveViews()
unsigned numTotalViews = 0;
for (const auto& it: _documents)
{
- if (!it.second.isExpired())
+ if (!it.second->isExpired())
{
- numTotalViews += it.second.getActiveViews();
+ numTotalViews += it.second->getActiveViews();
}
}
@@ -654,10 +658,10 @@ std::vector<DocBasicInfo> AdminModel::getDocumentsSortedByIdle() const
docs.reserve(_documents.size());
for (const auto& it: _documents)
{
- docs.emplace_back(it.second.getDocKey(),
- it.second.getIdleTime(),
- it.second.getMemoryDirty(),
- !it.second.getModifiedStatus());
+ docs.emplace_back(it.second->getDocKey(),
+ it.second->getIdleTime(),
+ it.second->getMemoryDirty(),
+ !it.second->getModifiedStatus());
}
// Sort the list by idle times;
@@ -680,21 +684,21 @@ std::string AdminModel::getDocuments() const
std::string separator1;
for (const auto& it: _documents)
{
- if (!it.second.isExpired())
+ if (!it.second->isExpired())
{
std::string encodedFilename;
- Poco::URI::encode(it.second.getFilename(), " ", encodedFilename);
+ Poco::URI::encode(it.second->getFilename(), " ", encodedFilename);
oss << separator1 << '{' << ' '
- << "\"pid\"" << ':' << it.second.getPid() << ','
- << "\"docKey\"" << ':' << '"' << it.second.getDocKey() << '"' << ','
+ << "\"pid\"" << ':' << it.second->getPid() << ','
+ << "\"docKey\"" << ':' << '"' << it.second->getDocKey() << '"' << ','
<< "\"fileName\"" << ':' << '"' << encodedFilename << '"' << ','
- << "\"activeViews\"" << ':' << it.second.getActiveViews() << ','
- << "\"memory\"" << ':' << it.second.getMemoryDirty() << ','
- << "\"elapsedTime\"" << ':' << it.second.getElapsedTime() << ','
- << "\"idleTime\"" << ':' << it.second.getIdleTime() << ','
- << "\"modified\"" << ':' << '"' << (it.second.getModifiedStatus() ? "Yes" : "No") << '"' << ','
+ << "\"activeViews\"" << ':' << it.second->getActiveViews() << ','
+ << "\"memory\"" << ':' << it.second->getMemoryDirty() << ','
+ << "\"elapsedTime\"" << ':' << it.second->getElapsedTime() << ','
+ << "\"idleTime\"" << ':' << it.second->getIdleTime() << ','
+ << "\"modified\"" << ':' << '"' << (it.second->getModifiedStatus() ? "Yes" : "No") << '"' << ','
<< "\"views\"" << ':' << '[';
- viewers = it.second.getViews();
+ viewers = it.second->getViews();
std::string separator;
for(const auto& viewIt: viewers)
{
@@ -723,11 +727,11 @@ void AdminModel::updateLastActivityTime(const std::string& docKey)
auto docIt = _documents.find(docKey);
if (docIt != _documents.end())
{
- if (docIt->second.getIdleTime() >= 10)
+ if (docIt->second->getIdleTime() >= 10)
{
- docIt->second.takeSnapshot(); // I would like to keep the idle time
- docIt->second.updateLastActivityTime();
- notify("resetidle " + std::to_string(docIt->second.getPid()));
+ docIt->second->takeSnapshot(); // I would like to keep the idle time
+ docIt->second->updateLastActivityTime();
+ notify("resetidle " + std::to_string(docIt->second->getPid()));
}
}
}
@@ -746,9 +750,9 @@ void AdminModel::updateMemoryDirty(const std::string& docKey, int dirty)
auto docIt = _documents.find(docKey);
if (docIt != _documents.end() &&
- docIt->second.updateMemoryDirty(dirty))
+ docIt->second->updateMemoryDirty(dirty))
{
- notify("propchange " + std::to_string(docIt->second.getPid()) +
+ notify("propchange " + std::to_string(docIt->second->getPid()) +
" mem " + std::to_string(dirty));
}
}
@@ -762,23 +766,23 @@ double AdminModel::getServerUptime()
void AdminModel::setViewLoadDuration(const std::string& docKey, const std::string& sessionId, std::chrono::milliseconds viewLoadDuration)
{
- std::map<std::string, Document>::iterator it = _documents.find(docKey);
+ auto it = _documents.find(docKey);
if (it != _documents.end())
- it->second.setViewLoadDuration(sessionId, viewLoadDuration);
+ it->second->setViewLoadDuration(sessionId, viewLoadDuration);
}
void AdminModel::setDocWopiDownloadDuration(const std::string& docKey, std::chrono::milliseconds wopiDownloadDuration)
{
- std::map<std::string, Document>::iterator it = _documents.find(docKey);
+ auto it = _documents.find(docKey);
if (it != _documents.end())
- it->second.setWopiDownloadDuration(wopiDownloadDuration);
+ it->second->setWopiDownloadDuration(wopiDownloadDuration);
}
void AdminModel::setDocWopiUploadDuration(const std::string& docKey, const std::chrono::milliseconds wopiUploadDuration)
{
- std::map<std::string, Document>::iterator it = _documents.find(docKey);
+ auto it = _documents.find(docKey);
if (it != _documents.end())
- it->second.setWopiUploadDuration(wopiUploadDuration);
+ it->second->setWopiUploadDuration(wopiUploadDuration);
}
void AdminModel::addSegFaultCount(unsigned segFaultCount)
@@ -927,7 +931,7 @@ struct DocumentAggregateStats
for (const auto& v : d.getViews())
_viewLoadDuration.Update(v.second.getLoadDuration().count(), active);
}
-
+
ActiveExpiredStats _kitUsedMemory;
ActiveExpiredStats _viewsCount;
ActiveExpiredStats _activeViewsCount;
@@ -957,10 +961,10 @@ struct KitProcStats
void AdminModel::CalcDocAggregateStats(DocumentAggregateStats& stats)
{
for (auto& d : _documents)
- stats.Update(d.second, true);
+ stats.Update(*d.second.get(), true);
for (auto& d : _expiredDocuments)
- stats.Update(d.second, false);
+ stats.Update(*d.second.get(), false);
}
void CalcKitStats(KitProcStats& stats)
@@ -1037,10 +1041,7 @@ std::set<pid_t> AdminModel::getDocumentPids() const
std::set<pid_t> pids;
for (const auto& it : _documents)
- {
- const Document& document = it.second;
- pids.insert(document.getPid());
- }
+ pids.insert(it.second->getPid());
return pids;
}
diff --git a/wsd/AdminModel.hpp b/wsd/AdminModel.hpp
index f5420747d..30f00e843 100644
--- a/wsd/AdminModel.hpp
+++ b/wsd/AdminModel.hpp
@@ -100,6 +100,10 @@ public:
/// A document in Admin controller.
class Document
{
+ // cf. FILE* member.
+ Document(const Document &) = delete;
+ Document& operator = (const Document &) = delete;
+
public:
Document(const std::string& docKey,
Poco::Process::PID pid,
@@ -245,8 +249,9 @@ private:
/// The Admin controller implementation.
class AdminModel
{
+ AdminModel(const AdminModel &) = delete;
+ AdminModel& operator = (const AdminModel &) = delete;
public:
-
AdminModel() :
_segFaultCount(0),
_owner(std::this_thread::get_id())
@@ -342,8 +347,8 @@ private:
private:
std::map<int, Subscriber> _subscribers;
- std::map<std::string, Document> _documents;
- std::map<std::string, Document> _expiredDocuments;
+ std::map<std::string, std::unique_ptr<Document>> _documents;
+ std::map<std::string, std::unique_ptr<Document>> _expiredDocuments;
/// The last N total memory Dirty size.
std::list<unsigned> _memStats;
More information about the Libreoffice-commits
mailing list