From b3d06869f59d9a2ac4a5aae65e414c7ac7287cd8 Mon Sep 17 00:00:00 2001 From: Ashod Nakashian Date: Fri, 8 Jan 2016 21:53:28 -0500 Subject: [PATCH] loolwsd: centralized document loading in Document Change-Id: I1ff7e0a53cc415958e46aea74c775d7f265b8b8e Reviewed-on: https://gerrit.libreoffice.org/21319 Reviewed-by: Ashod Nakashian Tested-by: Ashod Nakashian --- loolwsd/ChildProcessSession.cpp | 39 ++-------------- loolwsd/ChildProcessSession.hpp | 4 +- loolwsd/LOOLKit.cpp | 82 +++++++++++++++++++++++---------- 3 files changed, 63 insertions(+), 62 deletions(-) diff --git a/loolwsd/ChildProcessSession.cpp b/loolwsd/ChildProcessSession.cpp index 66e658774..f3ef86d69 100644 --- a/loolwsd/ChildProcessSession.cpp +++ b/loolwsd/ChildProcessSession.cpp @@ -46,7 +46,7 @@ ChildProcessSession::ChildProcessSession(const std::string& id, LibreOfficeKit *loKit, LibreOfficeKitDocument * loKitDocument, const std::string& jailId, - std::function onLoad, + std::function onLoad, std::function onUnload) : LOOLSession(id, Kind::ToMaster, ws), _loKitDocument(loKitDocument), @@ -230,15 +230,6 @@ bool ChildProcessSession::_handleInput(const char *buffer, int length) return true; } -extern "C" -{ - static void myCallback(int nType, const char* pPayload, void* pData) - { - auto pNotif = new CallBackNotification(nType, pPayload ? pPayload : "(nil)", pData); - ChildProcessSession::_callbackQueue.enqueueNotification(pNotif); - } -} - bool ChildProcessSession::loadDocument(const char * /*buffer*/, int /*length*/, StringTokenizer& tokens) { int part = -1; @@ -256,29 +247,10 @@ bool ChildProcessSession::loadDocument(const char * /*buffer*/, int /*length*/, Poco::Mutex::ScopedLock lock(_mutex); - if (_loKitDocument != nullptr) - { - Log::info("Loading view to document from URI: [" + _jailedFilePath + "]."); - - _viewId = _loKitDocument->pClass->createView(_loKitDocument); - } - else - { - Log::info("Loading new document from URI: [" + _jailedFilePath + "]."); - - if ( LIBREOFFICEKIT_HAS(_loKit, registerCallback)) - _loKit->pClass->registerCallback(_loKit, myCallback, this); - - if ((_loKitDocument = _loKit->pClass->documentLoad(_loKit, _jailedFilePath.c_str())) == nullptr) - { - Log::error("Failed to load: " + _jailedFilePath + ", error: " + _loKit->pClass->getError(_loKit)); - sendTextFrame("error: cmd=load kind=failed"); - return false; - } - } + _loKitDocument = _onLoad(this, _jailedFilePath); if (_multiView) - _loKitDocument->pClass->setView(_loKitDocument, _viewId); + _viewId = _loKitDocument->pClass->getView(_loKitDocument); std::string renderingOptions; if (!_docOptions.empty()) @@ -297,14 +269,11 @@ bool ChildProcessSession::loadDocument(const char * /*buffer*/, int /*length*/, _loKitDocument->pClass->setPart(_loKitDocument, part); } - _loKitDocument->pClass->registerCallback(_loKitDocument, myCallback, this); - // Respond by the document status, whih has no arguments. + // Respond by the document status, which has no arguments. if (!getStatus(nullptr, 0)) return false; - _onLoad(_loKitDocument, _viewId); - return true; } diff --git a/loolwsd/ChildProcessSession.hpp b/loolwsd/ChildProcessSession.hpp index e6b66003d..de3bc8480 100644 --- a/loolwsd/ChildProcessSession.hpp +++ b/loolwsd/ChildProcessSession.hpp @@ -34,7 +34,7 @@ public: LibreOfficeKit *loKit, LibreOfficeKitDocument * loKitDocument, const std::string& jailId, - std::function onLoad, + std::function onLoad, std::function onUnload); virtual ~ChildProcessSession(); @@ -89,7 +89,7 @@ private: /// View ID, returned by createView() or 0 by default. int _viewId; int _clientPart; - std::function _onLoad; + std::function _onLoad; std::function _onUnload; }; diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp index 990ed7414..06a52d470 100644 --- a/loolwsd/LOOLKit.cpp +++ b/loolwsd/LOOLKit.cpp @@ -324,7 +324,7 @@ class Connection: public Runnable public: Connection(LibreOfficeKit *loKit, LibreOfficeKitDocument *loKitDocument, const std::string& jailId, const std::string& sessionId, - std::function onLoad, + std::function onLoad, std::function onUnload) : _loKit(loKit), _loKitDocument(loKitDocument), @@ -346,6 +346,8 @@ public: const std::string& getSessionId() const { return _sessionId; } std::shared_ptr getWebSocket() const { return _ws; } + std::shared_ptr getSession() { return _session; } + void start() { _thread.start(*this); @@ -455,7 +457,7 @@ private: Thread _thread; std::shared_ptr _session; volatile bool _stop; - std::function _onLoad; + std::function _onLoad; std::function _onUnload; std::shared_ptr _ws; }; @@ -545,7 +547,7 @@ public: << " on child: " << _jailId << Log::end; auto thread = std::make_shared(_loKit, _loKitDocument, _jailId, sessionId, - [this](LibreOfficeKitDocument *loKitDocument, const int viewId) { onLoad(loKitDocument, viewId); }, + [this](ChildProcessSession* session, const std::string& jailedFilePath) { return onLoad(session, jailedFilePath); }, [this](const int viewId) { onUnload(viewId); }); const auto aInserted = _connections.emplace(sessionId, thread); @@ -578,35 +580,65 @@ public: private: - void onLoad(LibreOfficeKitDocument *loKitDocument, const int viewId) + static void DocumentCallback(int nType, const char* pPayload, void* pData) { - ++_clientViews; - Log::info() << "Document [" << _url << "] view [" - << viewId << "] loaded, leaving " - << _clientViews << " views." << Log::end; - - assert(loKitDocument != nullptr); - - // Check that the document instance doesn't change. - if (_loKitDocument != nullptr) - assert(_loKitDocument == loKitDocument); - - std::unique_lock lock(_mutex); - - if (_loKitDocument == nullptr) + Document* self = reinterpret_cast(pData); + if (self) { - _loKitDocument = loKitDocument; - - if (_multiView) + for (auto& it: self->_connections) { - // Create a view so we retain the document in memory - // when all clients are disconnected. - _mainViewId = _loKitDocument->pClass->createView(loKitDocument); - Log::info("Created main view [" + std::to_string(_mainViewId) + "]."); + if (it.second->isRunning()) + { + auto pNotif = new CallBackNotification(nType, pPayload ? pPayload : "(nil)", it.second->getSession().get()); + ChildProcessSession::_callbackQueue.enqueueNotification(pNotif); + } } } } + static void ViewCallback(int nType, const char* pPayload, void* pData) + { + auto pNotif = new CallBackNotification(nType, pPayload ? pPayload : "(nil)", pData); + ChildProcessSession::_callbackQueue.enqueueNotification(pNotif); + } + + /// Load a document (or view) and register callbacks. + LibreOfficeKitDocument* onLoad(ChildProcessSession* session, const std::string& jailedFilePath) + { + if (_loKitDocument == nullptr) + { + Log::info("Loading new document from URI: [" + jailedFilePath + "]."); + + if ( LIBREOFFICEKIT_HAS(_loKit, registerCallback)) + _loKit->pClass->registerCallback(_loKit, DocumentCallback, this); + + if ((_loKitDocument = _loKit->pClass->documentLoad(_loKit, jailedFilePath.c_str())) == nullptr) + { + Log::error("Failed to load: " + jailedFilePath + ", error: " + _loKit->pClass->getError(_loKit)); + return nullptr; + } + } + + if (_multiView) + { + Log::info("Loading view to document from URI: [" + jailedFilePath + "]."); + const auto viewId = _loKitDocument->pClass->createView(_loKitDocument); + + _loKitDocument->pClass->registerCallback(_loKitDocument, ViewCallback, session); + + ++_clientViews; + Log::info() << "Document [" << _url << "] view [" + << viewId << "] loaded, leaving " + << _clientViews << " views." << Log::end; + } + else + { + _loKitDocument->pClass->registerCallback(_loKitDocument, DocumentCallback, this); + } + + return _loKitDocument; + } + void onUnload(const int viewId) { --_clientViews;