loleaflet/src/admin/AdminSocketOverview.js | 119 +++++++++++++++-------------- loolwsd/Admin.cpp | 42 ++++------ loolwsd/Admin.hpp | 10 +- loolwsd/AdminModel.cpp | 98 ++++++++++------------- loolwsd/AdminModel.hpp | 46 ++++------- loolwsd/DocumentBroker.cpp | 2 loolwsd/DocumentBroker.hpp | 1 loolwsd/LOOLWSD.cpp | 47 +++++------ 8 files changed, 175 insertions(+), 190 deletions(-)
New commits: commit 61914208bce83fcb5f7c306a9959e4cab93344b8 Author: Pranav Kant <[email protected]> Date: Fri Apr 15 02:20:05 2016 +0530 loleaflet: Adapt to new changes in admin console Change-Id: I0761bd6c5b3650795a318a077eb50d0a8bd161da diff --git a/loleaflet/src/admin/AdminSocketOverview.js b/loleaflet/src/admin/AdminSocketOverview.js index 5bcb54e..a930415 100644 --- a/loleaflet/src/admin/AdminSocketOverview.js +++ b/loleaflet/src/admin/AdminSocketOverview.js @@ -20,7 +20,7 @@ var AdminSocketOverview = AdminSocketBase.extend({ onSocketOpen: function() { this.socket.send('documents'); - this.socket.send('subscribe document addview rmview rmdoc'); + this.socket.send('subscribe adddoc rmdoc'); this._getBasicStats(); var socketOverview = this; @@ -78,9 +78,9 @@ var AdminSocketOverview = AdminSocketBase.extend({ var tableContainer = document.getElementById('doclist'); var rowContainer; - var pidEle, urlEle, viewsEle, memEle, sDocTimeEle, docEle; + var pidEle, nameEle, viewsEle, memEle, sDocTimeEle, docEle, aEle; var nViews, nTotalViews; - var docProps, sPid, sUrl, sViews, sMem, sDocTime; + var docProps, sPid, sName, sViews, sMem, sDocTime; if (textMsg.startsWith('documents')) { var documents = textMsg.substring('documents'.length); documents = documents.trim().split('\n'); @@ -90,11 +90,11 @@ var AdminSocketOverview = AdminSocketBase.extend({ } docProps = documents[i].trim().split(' '); sPid = docProps[0]; - sUrl = docProps[1]; + sName = docProps[1]; sViews = docProps[2]; sMem = docProps[3]; sDocTime = docProps[4]; - if (sUrl === '0') { + if (sName === '0') { continue; } rowContainer = document.createElement('tr'); @@ -105,9 +105,9 @@ var AdminSocketOverview = AdminSocketBase.extend({ pidEle.innerHTML = sPid; rowContainer.appendChild(pidEle); - urlEle = document.createElement('td'); - urlEle.innerHTML = sUrl; - rowContainer.appendChild(urlEle); + nameEle = document.createElement('td'); + nameEle.innerHTML = sName; + rowContainer.appendChild(nameEle); viewsEle = document.createElement('td'); viewsEle.id = 'docview' + sPid; @@ -125,64 +125,60 @@ var AdminSocketOverview = AdminSocketBase.extend({ rowContainer.appendChild(sDocTimeEle); } } - else if (textMsg.startsWith('addview')) { - sPid = textMsg.substring('addview'.length).trim().split(' ')[0]; - nViews = parseInt(document.getElementById('docview' + sPid).innerHTML); - document.getElementById('docview' + sPid).innerHTML = nViews + 1; - nTotalViews = parseInt(document.getElementById('active_users_count').innerHTML); - document.getElementById('active_users_count').innerHTML = nTotalViews + 1; - } - else if (textMsg.startsWith('rmview')) { - sPid = textMsg.substring('addview'.length).trim().split(' ')[0]; - nViews = parseInt(document.getElementById('docview' + sPid).innerHTML); - document.getElementById('docview' + sPid).innerHTML = nViews - 1; - nTotalViews = parseInt(document.getElementById('active_users_count').innerHTML); - document.getElementById('active_users_count').innerHTML = nTotalViews - 1; - } - else if (textMsg.startsWith('document')) { - textMsg = textMsg.substring('document'.length); + else if (textMsg.startsWith('adddoc')) { + textMsg = textMsg.substring('adddoc'.length); docProps = textMsg.trim().split(' '); sPid = docProps[0]; - sUrl = docProps[1]; - sMem = docProps[2]; + sName = docProps[1]; + // docProps[2] == sessionid + sMem = docProps[3]; docEle = document.getElementById('doc' + sPid); - if (docEle) { - tableContainer.removeChild(docEle); - } - if (sUrl === '0') { - return; - } + if (!docEle) { - rowContainer = document.createElement('tr'); - rowContainer.id = 'doc' + docProps[0]; - tableContainer.appendChild(rowContainer); + if (sName === '0') { + return; + } - pidEle = document.createElement('td'); - pidEle.innerHTML = docProps[0]; - rowContainer.appendChild(pidEle); + rowContainer = document.createElement('tr'); + rowContainer.id = 'doc' + sPid; + tableContainer.appendChild(rowContainer); - urlEle = document.createElement('td'); - urlEle.innerHTML = docProps[1]; - rowContainer.appendChild(urlEle); + pidEle = document.createElement('td'); + pidEle.innerHTML = sPid; + rowContainer.appendChild(pidEle); - viewsEle = document.createElement('td'); - viewsEle.innerHTML = 0; - viewsEle.id = 'docview' + docProps[0]; - rowContainer.appendChild(viewsEle); + nameEle = document.createElement('td'); + nameEle.innerHTML = sName; + rowContainer.appendChild(nameEle); - memEle = document.createElement('td'); - memEle.innerHTML = Util.humanizeMem(parseInt(sMem)); - rowContainer.appendChild(memEle); + viewsEle = document.createElement('td'); + viewsEle.innerHTML = 0; + viewsEle.id = 'docview' + sPid; + rowContainer.appendChild(viewsEle); - sDocTimeEle = document.createElement('td'); - sDocTimeEle.className = 'elapsed_time'; - sDocTimeEle.value = 0; - sDocTimeEle.innerHTML = Util.humanizeSecs(0); - rowContainer.appendChild(sDocTimeEle); + memEle = document.createElement('td'); + memEle.innerHTML = Util.humanizeMem(parseInt(sMem)); + rowContainer.appendChild(memEle); + + sDocTimeEle = document.createElement('td'); + sDocTimeEle.className = 'elapsed_time'; + sDocTimeEle.value = 0; + sDocTimeEle.innerHTML = Util.humanizeSecs(0); + rowContainer.appendChild(sDocTimeEle); - var totalUsersEle = document.getElementById('active_docs_count'); - totalUsersEle.innerHTML = parseInt(totalUsersEle.innerHTML) + 1; + var totalUsersEle = document.getElementById('active_docs_count'); + totalUsersEle.innerHTML = parseInt(totalUsersEle.innerHTML) + 1; + + } + + viewsEle = document.getElementById('docview' + sPid); + nViews = parseInt(viewsEle.innerHTML); + viewsEle.innerHTML = nViews + 1; + + aEle = document.getElementById('active_users_count'); + nTotalViews = parseInt(aEle.innerHTML); + aEle.innerHTML = nTotalViews + 1; } else if (textMsg.startsWith('total_mem') || textMsg.startsWith('active_docs_count') || @@ -201,9 +197,20 @@ var AdminSocketOverview = AdminSocketBase.extend({ textMsg = textMsg.substring('rmdoc'.length); docProps = textMsg.trim().split(' '); sPid = docProps[0]; + // docProps[1] == sessionid + docEle = document.getElementById('doc' + sPid); if (docEle) { - tableContainer.removeChild(docEle); + viewsEle = document.getElementById('docview' + sPid); + nViews = parseInt(viewsEle.innerHTML) - 1; + viewsEle.innerHTML = nViews; + if (!nViews) { + tableContainer.removeChild(docEle); + } + + aEle = document.getElementById('active_users_count'); + nTotalViews = parseInt(aEle.innerHTML); + aEle.innerHTML = nTotalViews - 1; } } }, commit 7bf5e84a90ac5b106b49bb07add3f4e509dc15f6 Author: Pranav Kant <[email protected]> Date: Fri Apr 15 01:59:31 2016 +0530 loolwsd: Make admin console work (again) Change-Id: Ib51f33c60b5e42e154795357a7a787cb8691ad51 diff --git a/loolwsd/Admin.cpp b/loolwsd/Admin.cpp index f2eee9c..1202e95 100644 --- a/loolwsd/Admin.cpp +++ b/loolwsd/Admin.cpp @@ -384,10 +384,16 @@ Admin::~Admin() _cpuStatsTask->cancel(); } -void Admin::update(const std::string& message) +void Admin::addDoc(Poco::Process::PID pid, const std::string& filename, const int sessionId) { std::unique_lock<std::mutex> modelLock(_modelMutex); - _model.update(message); + _model.addDocument(pid, filename, sessionId); +} + +void Admin::rmDoc(Poco::Process::PID pid, const int sessionId) +{ + std::unique_lock<std::mutex> modelLock(_modelMutex); + _model.removeDocument(pid, sessionId); } void MemoryStats::run() @@ -396,7 +402,7 @@ void MemoryStats::run() AdminModel& model = _admin->getModel(); unsigned totalMem = _admin->getTotalMemoryUsage(model); - Log::trace() << "Total memory used: " << std::to_string(totalMem); + Log::info("Total memory used: " + std::to_string(totalMem)); model.addMemStats(totalMem); } diff --git a/loolwsd/Admin.hpp b/loolwsd/Admin.hpp index b3fedf5..9f4d838 100644 --- a/loolwsd/Admin.hpp +++ b/loolwsd/Admin.hpp @@ -53,6 +53,12 @@ public: /// Update the Admin Model. void update(const std::string& message); + /// Calls with same pid will increment view count, if pid already exists + void addDoc(Poco::Process::PID pid, const std::string& filename, const int sessionId); + + /// Decrement view count till becomes zero after which doc is removed + void rmDoc(Poco::Process::PID pid, const int nSessionId); + /// Set the forkit process id. void setForKitPid(const int forKitPid) { _forKitPid = forKitPid; } diff --git a/loolwsd/AdminModel.cpp b/loolwsd/AdminModel.cpp index 709f74b..3ff9477 100644 --- a/loolwsd/AdminModel.cpp +++ b/loolwsd/AdminModel.cpp @@ -24,12 +24,12 @@ using Poco::StringTokenizer; ///////////////// // Document Impl //////////////// -void Document::addView(int nSessionId) +void Document::addView(int sessionId) { - const auto ret = _views.emplace(nSessionId, View(nSessionId)); + const auto ret = _views.emplace(sessionId, View(sessionId)); if (!ret.second) { - Log::warn() << "View with SessionID [" + std::to_string(nSessionId) + "] already exists." << Log::end; + Log::warn() << "View with SessionID [" + std::to_string(sessionId) + "] already exists." << Log::end; } else { @@ -37,14 +37,19 @@ void Document::addView(int nSessionId) } } -void Document::removeView(int nSessionId) +int Document::expireView(int sessionId) { - auto it = _views.find(nSessionId); + auto it = _views.find(sessionId); if (it != _views.end()) { it->second.expire(); - _nActiveViews--; + + // If last view, expire the Document also + if (--_nActiveViews == 0) + _end = std::time(nullptr); } + + return _nActiveViews; } /////////////////// @@ -84,46 +89,6 @@ void Subscriber::unsubscribe(const std::string& command) // AdminModel Impl ////////////////// -void AdminModel::update(const std::string& data) -{ - StringTokenizer tokens(data, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM); - - Log::info("AdminModel Recv: " + data); - - if (tokens[0] == "document") - { - addDocument(std::stoi(tokens[1]), tokens[2]); - unsigned mem = Util::getMemoryUsage(std::stoi(tokens[1])); - std::string response = data + std::to_string(mem); - notify(response); - return; - } - else if (tokens[0] == "addview") - { - auto it = _documents.find(std::stoi(tokens[1])); - if (it != _documents.end()) - { - const unsigned nSessionId = Util::decodeId(tokens[2]); - it->second.addView(nSessionId); - } - } - else if (tokens[0] == "rmview") - { - auto it = _documents.find(std::stoi(tokens[1])); - if (it != _documents.end()) - { - const unsigned nSessionId = Util::decodeId(tokens[2]); - it->second.removeView(nSessionId); - } - } - else if (tokens[0] == "rmdoc") - { - removeDocument(std::stoi(tokens[1])); - } - - notify(data); -} - std::string AdminModel::query(const std::string& command) { StringTokenizer tokens(command, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM); @@ -278,21 +243,43 @@ void AdminModel::notify(const std::string& message) } } -void AdminModel::addDocument(Poco::Process::PID pid, const std::string& url) +void AdminModel::addDocument(Poco::Process::PID pid, const std::string& filename, const int sessionId) { - _documents.emplace(pid, Document(pid, url)); + const auto ret = _documents.emplace(pid, Document(pid, filename)); + ret.first->second.addView(sessionId); + + // Notify the subscribers + unsigned memUsage = Util::getMemoryUsage(pid); + std::ostringstream oss; + oss << "adddoc" << " " + << pid << " " + << filename << " " + << sessionId << " " + << std::to_string(memUsage); + Log::info("Message to admin console: " + oss.str()); + notify(oss.str()); } -void AdminModel::removeDocument(Poco::Process::PID pid) +void AdminModel::removeDocument(Poco::Process::PID pid, const int sessionId) { - auto it = _documents.find(pid); - if (it != _documents.end() && !it->second.isExpired()) + auto docIt = _documents.find(pid); + if (docIt != _documents.end() && !docIt->second.isExpired()) { + // Notify the subscribers + std::ostringstream oss; + oss << "rmdoc" << " " + << pid << " " + << sessionId; + Log::info("Message to admin console: " + oss.str()); + notify(oss.str()); + // TODO: 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. For now, just remove the document. - it->second.expire(); - _documents.erase(it); + if (docIt->second.expireView(sessionId) == 0) + { + _documents.erase(docIt); + } } } @@ -341,13 +328,14 @@ std::string AdminModel::getDocuments() continue; std::string sPid = std::to_string(it.second.getPid()); - std::string sUrl = it.second.getUrl(); + // TODO: URI encode the filename + std::string sFilename = it.second.getFilename(); std::string sViews = std::to_string(it.second.getActiveViews()); std::string sMem = std::to_string(Util::getMemoryUsage(it.second.getPid())); std::string sElapsed = std::to_string(it.second.getElapsedTime()); oss << sPid << " " - << sUrl << " " + << sFilename << " " << sViews << " " << sMem << " " << sElapsed << " \n "; diff --git a/loolwsd/AdminModel.hpp b/loolwsd/AdminModel.hpp index 639dd43..843320d 100644 --- a/loolwsd/AdminModel.hpp +++ b/loolwsd/AdminModel.hpp @@ -22,8 +22,8 @@ class View { public: - View(int nSessionId) - : _nSessionId(nSessionId), + View(int sessionId) + : _nSessionId(sessionId), _start(std::time(nullptr)) { } @@ -41,9 +41,9 @@ private: class Document { public: - Document(Poco::Process::PID nPid, std::string sUrl) - : _nPid(nPid), - _sUrl(sUrl), + Document(Poco::Process::PID pid, std::string filename) + : _nPid(pid), + _sFilename(filename), _start(std::time(nullptr)) { Log::info("Document " + std::to_string(_nPid) + " ctor."); @@ -56,17 +56,15 @@ public: Poco::Process::PID getPid() const { return _nPid; } - std::string getUrl() const { return _sUrl; } - - void expire() { _end = std::time(nullptr); } + std::string getFilename() const { return _sFilename; } bool isExpired() const { return _end != 0 && std::time(nullptr) >= _end; } std::time_t getElapsedTime() const { return std::time(nullptr) - _start; } - void addView(int nSessionId); + void addView(int sessionId); - void removeView(int nSessionId); + int expireView(int sessionId); unsigned getActiveViews() const { return _nActiveViews; } @@ -76,8 +74,8 @@ private: std::map<int, View> _views; /// Total number of active views unsigned _nActiveViews = 0; - /// Hosted URL - std::string _sUrl; + /// Hosted filename + std::string _sFilename; std::time_t _start; std::time_t _end = 0; @@ -86,8 +84,8 @@ private: class Subscriber { public: - Subscriber(int nSessionId, std::shared_ptr<Poco::Net::WebSocket>& ws) - : _nSessionId(nSessionId), + Subscriber(int sessionId, std::shared_ptr<Poco::Net::WebSocket>& ws) + : _nSessionId(sessionId), _ws(ws), _start(std::time(nullptr)) { @@ -119,11 +117,6 @@ private: std::time_t _start; std::time_t _end = 0; - - /// In case of huge number of documents, - /// client can tell us the specific page it is - /// interested in getting live notifications - unsigned _currentPage; }; class AdminModel @@ -139,17 +132,15 @@ public: Log::info("AdminModel dtor."); } - void update(const std::string& data); - std::string query(const std::string& command); /// Returns memory consumed by all active loolkit processes unsigned getTotalMemoryUsage(); - void subscribe(int nSessionId, std::shared_ptr<Poco::Net::WebSocket>& ws); - void subscribe(int nSessionId, const std::string& command); + void subscribe(int sessionId, std::shared_ptr<Poco::Net::WebSocket>& ws); + void subscribe(int sessionId, const std::string& command); - void unsubscribe(int nSessionId, const std::string& command); + void unsubscribe(int sessionId, const std::string& command); void clearMemStats() { _memStats.clear(); } @@ -165,10 +156,11 @@ public: void notify(const std::string& message); -private: - void addDocument(Poco::Process::PID pid, const std::string& url); + void addDocument(Poco::Process::PID pid, const std::string& filename, const int sessionId); + + void removeDocument(Poco::Process::PID pid, const int sessionId); - void removeDocument(Poco::Process::PID pid); +private: std::string getMemStats(); diff --git a/loolwsd/DocumentBroker.cpp b/loolwsd/DocumentBroker.cpp index 0ec21ea..0274cf0 100644 --- a/loolwsd/DocumentBroker.cpp +++ b/loolwsd/DocumentBroker.cpp @@ -116,7 +116,7 @@ bool DocumentBroker::load(const std::string& jailId) { const auto fileInfo = storage->getFileInfo(_uriPublic); _tileCache.reset(new TileCache(_uriPublic.toString(), fileInfo.ModifiedTime, _cacheRoot)); - + _filename = fileInfo.Filename; _storage = StorageBase::create(jailRoot, jailPath.toString(), _uriPublic); const auto localPath = _storage->loadStorageFileToLocal(); diff --git a/loolwsd/DocumentBroker.hpp b/loolwsd/DocumentBroker.hpp index 6e260d9..998ea91 100644 --- a/loolwsd/DocumentBroker.hpp +++ b/loolwsd/DocumentBroker.hpp @@ -145,6 +145,7 @@ public: Poco::URI getJailedUri() const { return _uriJailed; } const std::string& getJailId() const { return _jailId; } const std::string& getDocKey() const { return _docKey; } + const std::string& getFilename() const { return _filename; }; TileCache& tileCache() { return *_tileCache; } unsigned getSessionsCount() const { diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp index f8eff17..0cf254d 100644 --- a/loolwsd/LOOLWSD.cpp +++ b/loolwsd/LOOLWSD.cpp @@ -390,12 +390,6 @@ private: { Log::debug("Removing DocumentBroker for docKey [" + docKey + "]."); docBrokers.erase(docKey); - - std::ostringstream message; - message << "rmdoc" << " " - << docBroker->getJailId() << " " - << "\n"; - Admin::instance().update(message.str()); } } @@ -879,18 +873,18 @@ public: AvailableChildSessionCV.notify_one(); const auto uri = request.getURI(); - std::ostringstream message; - message << "document" << " " - << jailId << " " - << uri.substr(uri.find_last_of("/") + 1) << " " - << "\n"; - Admin::instance().update(message.str()); - - message << "addview" << " " - << jailId << " " - << sessionId << " " - << "\n"; - Admin::instance().update(message.str()); + + // Jail id should be the PID, beacuse Admin need it to calculate the memory + try + { + Log::info("Adding doc " + jailId + " to Admin"); + Admin::instance().addDoc(std::stoi(jailId), docBroker->getFilename(), std::stoi(sessionId)); + } + catch (std::invalid_argument& exc) + { + assert(false); + } + if (waitBridgeCompleted(session)) { @@ -925,12 +919,15 @@ public: if (!jailId.empty()) { - std::ostringstream message; - message << "rmview" << " " - << jailId << " " - << sessionId << " " - << "\n"; - Admin::instance().update(message.str()); + try + { + Log::info("Removing doc " + jailId + " from Admin"); + Admin::instance().rmDoc(std::stoi(jailId), std::stoi(sessionId)); + } + catch (std::invalid_argument& exc) + { + assert(false); + } } Log::debug("Thread finished."); commit 4f9eef93245c9a796729fdd509d0cee653af6eca Author: Pranav Kant <[email protected]> Date: Wed Apr 13 13:46:57 2016 +0530 loolwsd: Be consistent, and use unique_lock Change-Id: Idfc14bb7dd82827493865241f6d04cf9ae4a88fc diff --git a/loolwsd/Admin.cpp b/loolwsd/Admin.cpp index 47b7ef6..f2eee9c 100644 --- a/loolwsd/Admin.cpp +++ b/loolwsd/Admin.cpp @@ -386,7 +386,7 @@ Admin::~Admin() void Admin::update(const std::string& message) { - std::lock_guard<std::mutex> modelLock(_modelMutex); + std::unique_lock<std::mutex> modelLock(_modelMutex); _model.update(message); } commit 9669470d091fd0e4d60cce469109d6e735671a58 Author: Pranav Kant <[email protected]> Date: Wed Apr 13 13:44:54 2016 +0530 loolwsd: Admin doesn't need its own thread now The timers are cancelled upon destruction of the static Admin instance. Change-Id: Ie43dc9d3ec96b002e12685ec997ad83c29b684d0 diff --git a/loolwsd/Admin.cpp b/loolwsd/Admin.cpp index 899e902..47b7ef6 100644 --- a/loolwsd/Admin.cpp +++ b/loolwsd/Admin.cpp @@ -367,11 +367,21 @@ void AdminRequestHandler::handleRequest(HTTPServerRequest& request, HTTPServerRe Admin::Admin() : _model(AdminModel()) { + Log::info("Admin ctor."); + + _memStatsTask = new MemoryStats(this); + _memStatsTimer.schedule(_memStatsTask, _memStatsTaskInterval, _memStatsTaskInterval); + + _cpuStatsTask = new CpuStats(this); + _cpuStatsTimer.schedule(_cpuStatsTask, _cpuStatsTaskInterval, _cpuStatsTaskInterval); } Admin::~Admin() { Log::info("~Admin dtor."); + + _memStatsTask->cancel(); + _cpuStatsTask->cancel(); } void Admin::update(const std::string& message) @@ -434,24 +444,6 @@ unsigned Admin::getCpuStatsInterval() return _cpuStatsTaskInterval; } -void Admin::run() -{ - _memStatsTask = new MemoryStats(this); - _memStatsTimer.schedule(_memStatsTask, _memStatsTaskInterval, _memStatsTaskInterval); - - _cpuStatsTask = new CpuStats(this); - _cpuStatsTimer.schedule(_cpuStatsTask, _cpuStatsTaskInterval, _cpuStatsTaskInterval); - - Util::setThreadName("admin_thread"); - - Log::debug("Thread started."); - - _memStatsTimer.cancel(); - _cpuStatsTimer.cancel(); - - Log::debug("Thread finished."); -} - AdminModel& Admin::getModel() { return _model; diff --git a/loolwsd/Admin.hpp b/loolwsd/Admin.hpp index c5a6258..b3fedf5 100644 --- a/loolwsd/Admin.hpp +++ b/loolwsd/Admin.hpp @@ -37,7 +37,7 @@ private: }; /// An admin command processor. -class Admin : public Poco::Runnable +class Admin { public: virtual ~Admin(); @@ -50,8 +50,6 @@ public: unsigned getTotalMemoryUsage(AdminModel&); - void run() override; - /// Update the Admin Model. void update(const std::string& message); diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp index 6c1d790..f8eff17 100644 --- a/loolwsd/LOOLWSD.cpp +++ b/loolwsd/LOOLWSD.cpp @@ -1438,8 +1438,6 @@ int LOOLWSD::main(const std::vector<std::string>& /*args*/) } Log::debug("open(" + pipeLoolwsd + ", WRONLY) = " + std::to_string(ForKitWritePipe)); - threadPool.start(Admin::instance()); - preForkChildren(); time_t last30SecCheck = time(NULL); _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
