[Libreoffice-commits] online.git: loolwsd/ChildSession.cpp loolwsd/ChildSession.hpp loolwsd/LOOLKit.cpp
Ashod Nakashian
ashod.nakashian at collabora.co.uk
Mon Aug 22 05:44:48 UTC 2016
loolwsd/ChildSession.cpp | 7 ------
loolwsd/ChildSession.hpp | 4 ++-
loolwsd/LOOLKit.cpp | 52 ++++++++++++++++++-----------------------------
3 files changed, 25 insertions(+), 38 deletions(-)
New commits:
commit a28b832309e30ea609df85582956643c1db29385
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date: Sun Aug 21 11:12:12 2016 -0400
loolwsd: proper ChildSession cleanup
ChildSession cleanup is tricky because it needs
to be cleaned up when the connection is dropped.
The ChildSession itself needs to initiate this
cleanup from Document.
A new approach simplifies the design and correctly
broadcasts remview to all other connections so
they would be able to cleanup visual elements.
Change-Id: I78fd01fb42b801913534c858324c16dd7ad6451d
Reviewed-on: https://gerrit.libreoffice.org/28302
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
Tested-by: Ashod Nakashian <ashnakash at gmail.com>
diff --git a/loolwsd/ChildSession.cpp b/loolwsd/ChildSession.cpp
index 51b445f..d94b68b 100644
--- a/loolwsd/ChildSession.cpp
+++ b/loolwsd/ChildSession.cpp
@@ -58,14 +58,9 @@ void ChildSession::disconnect()
{
std::unique_lock<std::recursive_mutex> lock(Mutex);
- sendTextFrame("remview: " + std::to_string(_viewId));
-
if (_viewId >= 0)
{
- if (_multiView && _loKitDocument)
- _loKitDocument->setView(_viewId);
-
- _docManager.onUnload(getId());
+ _docManager.onUnload(*this);
}
else
{
diff --git a/loolwsd/ChildSession.hpp b/loolwsd/ChildSession.hpp
index e69c415..1f6d2eb 100644
--- a/loolwsd/ChildSession.hpp
+++ b/loolwsd/ChildSession.hpp
@@ -19,6 +19,8 @@
#include "LOOLSession.hpp"
#include "LibreOfficeKit.hpp"
+class ChildSession;
+
/// An abstract interface that defines the
/// DocumentManager interface and functionality.
class IDocumentManager
@@ -35,7 +37,7 @@ public:
/// Unload a client session, which unloads the document
/// if it is the last and only.
virtual
- void onUnload(const std::string& sessionId) = 0;
+ void onUnload(const ChildSession& session) = 0;
/// Get a list of all current view IDs.
virtual
diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp
index a1df19f..897f033 100644
--- a/loolwsd/LOOLKit.cpp
+++ b/loolwsd/LOOLKit.cpp
@@ -248,6 +248,7 @@ public:
join();
}
+ const std::string& getSessionId() const { return _sessionId; };
std::shared_ptr<WebSocket> getWebSocket() const { return _ws; }
std::shared_ptr<ChildSession> getSession() { return _session; }
@@ -325,8 +326,6 @@ public:
Log::error("Connection::run:: Unexpected exception");
}
- // Release the session and unload view.
- _session.reset();
Log::debug("Thread finished.");
}
@@ -882,55 +881,46 @@ private:
return _loKitDocument;
}
- void onUnload(const std::string& sessionId) override
+ void onUnload(const ChildSession& session) override
{
+ const auto sessionId = session.getId();
Log::info("Unloading [" + sessionId + "].");
- const unsigned intSessionId = Util::decodeId(sessionId);
- if (_loKitDocument == nullptr)
- {
- Log::error("Unloading session [" + sessionId + "] without loKitDocument.");
- return;
- }
-
- // Find this session connection.
- int sessionViewId = -1;
+ // Broadcast the demise and removal of session.
{
std::unique_lock<std::mutex> lock(_mutex);
- const auto it = _connections.find(intSessionId);
- if (it == _connections.end() || !it->second || !it->second->getSession())
+ // We should be removed by this point, otherwise
+ // our closed connection will throw, if not segfault.
+ for (const auto& pair : _connections)
{
- Log::error("Session [" + sessionId + "] not found to unload.");
- return;
+ assert(sessionId != pair.second->getSessionId() && "Unloading connection still lingering.");
+ pair.second->getSession()->sendTextFrame("remview: " + sessionId);
}
- sessionViewId = it->second->getSession()->getViewId();
+ if (_loKitDocument == nullptr)
+ {
+ Log::error("Unloading session [" + sessionId + "] without loKitDocument.");
+ return;
+ }
}
--_clientViews;
- Log::info("Session " + sessionId + " is unloading. " + std::to_string(_clientViews) +
- " view" + (_clientViews != 1 ? "s" : "") + " remain.");
+ Log::info() << "Document [" << _url << "] session ["
+ << sessionId << "] unloaded, " << _clientViews
+ << " view" << (_clientViews != 1 ? "s" : "")
+ << Log::end;
if (_multiView)
{
- Log::info() << "Document [" << _url << "] session ["
- << sessionId << "] unloaded, leaving "
- << _clientViews << " views." << Log::end;
-
std::unique_lock<std::mutex> lock(_loKitDocument->getLock());
- const auto viewId = _loKitDocument->getView();
- if (viewId != sessionViewId)
- {
- Log::error() << "Unloading view [" << sessionViewId
- << "] from view [" << viewId << "]." << Log::end;
- return;
- }
-
+ const auto viewId = session.getViewId();
_viewIdToCallbackDescr.erase(viewId);
+ _loKitDocument->setView(viewId);
_loKitDocument->registerCallback(nullptr, nullptr);
_loKitDocument->destroyView(viewId);
+ Log::debug("Destroyed view " + std::to_string(viewId));
}
}
More information about the Libreoffice-commits
mailing list