[Libreoffice-commits] online.git: loolwsd/LOOLKit.cpp
Ashod Nakashian
ashod.nakashian at collabora.co.uk
Sun Jan 3 07:18:42 PST 2016
loolwsd/LOOLKit.cpp | 193 ++++++++++++++++++++++++++++++++--------------------
1 file changed, 121 insertions(+), 72 deletions(-)
New commits:
commit 17333608bc5809aea605b820be163eadf60c4f2e
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date: Tue Dec 29 22:17:24 2015 -0500
loolwsd: new Document class to manage the lifecycle of a document
Change-Id: I7390c05ce42668694efbf1d8cdce499a9aca579c
Reviewed-on: https://gerrit.libreoffice.org/21061
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
Tested-by: Ashod Nakashian <ashnakash at gmail.com>
diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp
index f54c8a2..a5795a9 100644
--- a/loolwsd/LOOLKit.cpp
+++ b/loolwsd/LOOLKit.cpp
@@ -485,6 +485,109 @@ private:
std::shared_ptr<ChildProcessSession> _session;
};
+// A document container.
+// Owns LOKitDocument instance and connections.
+// Manages the lifetime of a document.
+// Technically, we can host multiple documents
+// per process. But for security reasons don't.
+// However, we could have a loolkit instance
+// per user or group of users (a trusted circle).
+class Document
+{
+public:
+ Document(LibreOfficeKit *loKit, const std::string& childId,
+ const std::string& url)
+ : _loKit(loKit),
+ _childId(childId),
+ _url(url)
+ {
+ }
+
+ ~Document()
+ {
+ // Destroy all connections and views.
+ // wait until loolwsd close all websockets
+ for (auto aIterator : _connections)
+ {
+ if (aIterator.second->isRunning())
+ aIterator.second->join();
+ }
+
+ // Get the document to destroy later.
+ auto loKitDocument = _connections.size() > 0
+ ? _connections.begin()->second->getLOKitDocument()
+ : nullptr;
+
+ // Destroy all connections and views.
+ _connections.clear();
+
+ // TODO. check what is happening when destroying lokit document
+ // Destroy the document.
+ if (loKitDocument != nullptr)
+ {
+ loKitDocument->pClass->destroy(loKitDocument);
+ }
+ }
+
+ void createSession(const std::string& sessionId)
+ {
+ const auto& aItem = _connections.find(sessionId);
+ if (aItem != _connections.end())
+ {
+ // found item, check if still running
+ Log::debug("Found thread for [" + sessionId + "] " +
+ (aItem->second->isRunning() ? "Running" : "Stopped"));
+
+ if (!aItem->second->isRunning())
+ {
+ // Restore thread.
+ Log::warn("Thread [" + sessionId + "] is not running. Restoring.");
+ _connections.erase(sessionId);
+
+ auto thread = std::make_shared<Connection>(_loKit, aItem->second->getLOKitDocument(), _childId, sessionId);
+ _connections.emplace(sessionId, thread);
+ thread->start();
+ }
+ }
+ else
+ {
+ // new thread id
+ Log::debug("Starting new thread for request [" + sessionId + "]");
+ std::shared_ptr<Connection> thread;
+ if ( _connections.empty() )
+ {
+ Log::info("Creating main thread for child: " + _childId + ", thread: " + sessionId);
+ thread = std::make_shared<Connection>(_loKit, nullptr, _childId, sessionId);
+ }
+ else
+ {
+ Log::info("Creating view thread for child: " + _childId + ", thread: " + sessionId);
+ auto aConnection = _connections.begin();
+ thread = std::make_shared<Connection>(_loKit, aConnection->second->getLOKitDocument(), _childId, sessionId);
+ }
+
+ auto aInserted = _connections.emplace(sessionId, thread);
+
+ if ( aInserted.second )
+ thread->start();
+ else
+ Log::error("Connection already exists for child: " + _childId + ", thread: " + sessionId);
+
+ Log::debug("Connections: " + std::to_string(_connections.size()));
+ }
+ }
+
+private:
+
+ LibreOfficeKit *_loKit;
+ const std::string _childId;
+ const std::string _url;
+
+ LibreOfficeKitDocument *_loKitDocument;
+
+ std::map<std::string, std::shared_ptr<Connection>> _connections;
+};
+
void run_lok_main(const std::string &loSubPath, const std::string& childId, const std::string& pipe)
{
struct pollfd aPoll;
@@ -494,7 +597,7 @@ void run_lok_main(const std::string &loSubPath, const std::string& childId, cons
char* pEnd = nullptr;
std::string aURL;
- std::map<std::string, std::shared_ptr<Connection>> _connections;
+ std::map<std::string, std::shared_ptr<Document>> _documents;
assert(!childId.empty());
assert(!loSubPath.empty());
@@ -597,70 +700,36 @@ void run_lok_main(const std::string &loSubPath, const std::string& childId, cons
if (tokens[0] == "search")
{
- if ( !_connections.empty() )
+ aResponse = std::to_string(Process::id()) + " ";
+ if (_documents.empty())
{
- aResponse = std::to_string(Process::id()) + ( aURL == tokens[1] ? " ok \r\n" : " no \r\n");
- Util::writeFIFO(writerBroker, aResponse.c_str(), aResponse.length() );
+ aResponse += "empty \r\n";
}
else
{
- aURL.clear();
- aResponse = std::to_string(Process::id()) + " empty \r\n";
- Util::writeFIFO(writerBroker, aResponse.c_str(), aResponse.length() );
+ const auto& it = _documents.find(tokens[1]);
+ aResponse += (it != _documents.end() ? "ok \r\n" : "no \r\n");
}
+
+ Util::writeFIFO(writerBroker, aResponse.c_str(), aResponse.length());
}
else if (tokens[0] == "thread")
{
const std::string& sessionId = tokens[1];
Log::debug("Thread request for [" + sessionId + "]");
- const auto& aItem = _connections.find(sessionId);
- if (aItem != _connections.end())
- {
- // found item, check if still running
- Log::debug("Found thread for [" + sessionId + "] " +
- (aItem->second->isRunning() ? "Running" : "Stopped"));
-
- if (!aItem->second->isRunning())
- {
- // Restore thread.
- Log::warn("Thread [" + sessionId + "] is not running. Restoring.");
- _connections.erase(sessionId);
-
- auto thread = std::make_shared<Connection>(loKit.get(), aItem->second->getLOKitDocument(), childId, sessionId);
- _connections.emplace(sessionId, thread);
- thread->start();
- }
- }
- else
- {
- // new thread id
- Log::debug("Starting new thread for request [" + sessionId + "]");
- std::shared_ptr<Connection> thread;
- if ( _connections.empty() )
- {
- Log::info("Creating main thread for child: " + childId + ", thread: " + sessionId);
- thread = std::make_shared<Connection>(loKit.get(), nullptr, childId, sessionId);
- }
- else
- {
- Log::info("Creating view thread for child: " + childId + ", thread: " + sessionId);
- auto aConnection = _connections.begin();
- thread = std::make_shared<Connection>(loKit.get(), aConnection->second->getLOKitDocument(), childId, sessionId);
- }
-
- auto aInserted = _connections.emplace(sessionId, thread);
-
- if ( aInserted.second )
- thread->start();
- else
- Log::error("Connection already exists for child: " + childId + ", thread: " + sessionId);
-
- Log::debug("Connections: " + std::to_string(_connections.size()));
- }
+
+ //FIXME: for now we expect only one document per process.
+ assert(_documents.size() == 1);
+ assert(_documents[aURL]);
+
+ _documents[aURL]->createSession(sessionId);
}
else if (tokens[0] == "url")
{
+ // When multi-documents per-process is supported
+ // this will need to move to search or thread.
aURL = tokens[1];
+ _documents.emplace(aURL, std::make_shared<Document>(loKit.get(), childId, aURL));
}
else
{
@@ -690,27 +759,7 @@ void run_lok_main(const std::string &loSubPath, const std::string& childId, cons
Log::error(std::string("Exception: ") + exc.what());
}
- // wait until loolwsd close all websockets
- for (auto aIterator : _connections)
- {
- if (aIterator.second->isRunning())
- aIterator.second->join();
- }
-
- // Get the document to destroy later.
- auto loKitDocument = _connections.size() > 0
- ? _connections.begin()->second->getLOKitDocument()
- : nullptr;
-
- // Destroy all connections and views.
- _connections.clear();
-
- // TODO. check what is happening when destroying lokit document
- // Destroy the document.
- if (loKitDocument != nullptr)
- {
- loKitDocument->pClass->destroy(loKitDocument);
- }
+ _documents.clear();
// Destroy LibreOfficeKit
loKit->pClass->destroy(loKit.get());
More information about the Libreoffice-commits
mailing list