[Libreoffice-commits] online.git: common/Session.cpp common/Session.hpp kit/Kit.cpp wsd/ClientSession.cpp wsd/ClientSession.hpp wsd/DocumentBroker.cpp wsd/DocumentBroker.hpp
Michael Meeks (via logerrit)
logerrit at kemper.freedesktop.org
Mon Jan 6 12:52:48 UTC 2020
common/Session.cpp | 17 ----------------
common/Session.hpp | 51 ++++++++++++++++++++++++++++++++++++++++---------
kit/Kit.cpp | 32 +++++++++++++++---------------
wsd/ClientSession.cpp | 20 +++++++++----------
wsd/ClientSession.hpp | 2 -
wsd/DocumentBroker.cpp | 5 ----
wsd/DocumentBroker.hpp | 3 +-
7 files changed, 72 insertions(+), 58 deletions(-)
New commits:
commit 9cef0f385df831c6958bed475ff7ab4919fcb49a
Author: Michael Meeks <michael.meeks at collabora.com>
AuthorDate: Thu Jan 2 21:11:54 2020 +0000
Commit: Jan Holesovsky <kendy at collabora.com>
CommitDate: Mon Jan 6 13:52:29 2020 +0100
watermarking: create SessionMap template to canonicalize views.
Use a fully reliable uniqueness check, rather than a hash, and get
simpler ids as a bonus. Fetch view data from the session itself
rather than passing it in too.
Change-Id: Ibcd625156b5a98eb280e35d6537b5c8c026d0197
Reviewed-on: https://gerrit.libreoffice.org/c/online/+/86150
Reviewed-by: Mert Tümer <mert.tumer at collabora.com>
Tested-by: Mert Tümer <mert.tumer at collabora.com>
diff --git a/common/Session.cpp b/common/Session.cpp
index 1e4c76573..37f3a5952 100644
--- a/common/Session.cpp
+++ b/common/Session.cpp
@@ -255,23 +255,6 @@ void Session::getIOStats(uint64_t &sent, uint64_t &recv)
}
}
-void Session::setHash(const std::string& text)
- {
- unsigned int hash = 0x811C9DC5;
- unsigned int prime = 0x1000193;
-
- if (!text.empty())
- {
- for (unsigned int i = 0; i < text.length(); ++i)
- {
- hash += hash ^ text[i];
- hash *= prime;
- }
- }
- _hash = abs(static_cast<int>(hash));
- }
-
-
void Session::dumpState(std::ostream& os)
{
WebSocketHandler::dumpState(os);
diff --git a/common/Session.hpp b/common/Session.hpp
index d06d18a44..6a3f7cfea 100644
--- a/common/Session.hpp
+++ b/common/Session.hpp
@@ -14,7 +14,9 @@
#include <cassert>
#include <memory>
#include <mutex>
+#include <map>
#include <ostream>
+#include <type_traits>
#include <Poco/Buffer.h>
#include <Poco/Path.h>
@@ -28,6 +30,39 @@
#include "TileCache.hpp"
#include "WebSocketHandler.hpp"
+class Session;
+
+template<class T>
+class SessionMap : public std::map<std::string, std::shared_ptr<T> >
+{
+ std::map<std::string, int> _canonicalIds;
+public:
+ SessionMap() {
+ static_assert(std::is_base_of<Session, T>::value, "sessions must have base of Session");
+ }
+ /// Generate a unique key for this set of view properties
+ int getCanonicalId(const std::string &viewProps)
+ {
+ if (viewProps.empty())
+ return 0;
+ for (auto &it : _canonicalIds) {
+ if (it.first == viewProps)
+ return it.second;
+ }
+ size_t id = _canonicalIds.size() + 1;
+ _canonicalIds[viewProps] = id;
+ return id;
+ }
+ std::shared_ptr<T> findByCanonicalId(int id)
+ {
+ for (auto &it : *this) {
+ if (it.second->getCanonicalViewId() == id)
+ return it.second;
+ }
+ return std::shared_ptr<T>();
+ }
+};
+
/// Base class of a WebSocket session.
class Session : public WebSocketHandler
{
@@ -121,11 +156,11 @@ public:
const std::string& getJailedFilePathAnonym() const { return _jailedFilePathAnonym; }
- int getHash() { return _hash; }
-
- void setHash(const std::string& text);
-
- void setHash(const int hash) { _hash = hash; };
+ int getCanonicalViewId() { return _canonicalViewId; }
+ template<class T> void recalcCanonicalViewId(SessionMap<T> &map)
+ {
+ _canonicalViewId = map.getCanonicalId(_watermarkText);
+ }
protected:
Session(const std::string& name, const std::string& id, bool readonly);
@@ -218,10 +253,8 @@ private:
/// Language for the document based on what the user has in the UI.
std::string _lang;
- /// Hash for normalizedViewId which is basically an identity for the tile to
- /// choose what to render on and send it to its subscribers
- /// it is the close-to-unique integer representation of a string like Watermarks etc.
- int _hash;
+ /// the canonical id unique to the set of rendering properties of this session
+ int _canonicalViewId;
};
#endif
diff --git a/kit/Kit.cpp b/kit/Kit.cpp
index 4ad74b258..f2930d923 100644
--- a/kit/Kit.cpp
+++ b/kit/Kit.cpp
@@ -948,6 +948,20 @@ public:
return;
}
+ // Find a session matching our view / render settings.
+ const auto session = _sessions.findByCanonicalId(tileCombined.getNormalizedViewId());
+ if (!session)
+ {
+ LOG_ERR("Session is not found. Maybe exited after rendering request.");
+ return;
+ }
+
+#ifdef FIXME_RENDER_SETTINGS
+ // if necessary select a suitable rendering view eg. with 'show non-printing chars'
+ if (tileCombined.getNormalizedViewId())
+ _loKitDocument->setView(session->getViewId());
+#endif
+
// Render the whole area
const double area = pixmapWidth * pixmapHeight;
auto start = std::chrono::system_clock::now();
@@ -972,16 +986,6 @@ public:
const int pixelWidth = tileCombined.getWidth();
const int pixelHeight = tileCombined.getHeight();
- int nViewId = tileCombined.getNormalizedViewId();
- const auto it = std::find_if(_sessions.begin(), _sessions.end(), [nViewId](const std::pair<std::string, std::shared_ptr<ChildSession>>& val){ return (val.second)->getHash() == nViewId; });
- const auto& session = it->second;
-
- if (it == _sessions.end())
- {
- LOG_ERR("Session is not found. Maybe exited after rendering request.");
- return;
- }
-
std::vector<TileDesc> renderedTiles;
std::vector<TileDesc> duplicateTiles;
std::vector<TileBinaryHash> duplicateHashes;
@@ -1717,12 +1721,8 @@ private:
viewCount << " view" << (viewCount != 1 ? "s." : "."));
if (session->hasWatermark())
- {
session->_docWatermark.reset(new Watermark(_loKitDocument, session));
- session->setHash(session->getWatermarkText());
- }
- else
- session->setHash(0);
+ session->recalcCanonicalViewId(_sessions);
return _loKitDocument;
}
@@ -2046,7 +2046,7 @@ private:
int _editorId;
bool _editorChangeWarning;
std::map<int, std::unique_ptr<CallbackDescriptor>> _viewIdToCallbackDescr;
- std::map<std::string, std::shared_ptr<ChildSession>> _sessions;
+ SessionMap<ChildSession> _sessions;
std::map<int, std::chrono::steady_clock::time_point> _lastUpdatedAt;
std::map<int, int> _speedCount;
diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp
index 43bc0ecbb..beed136e5 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -35,8 +35,8 @@ using namespace LOOLProtocol;
using Poco::Path;
-static std::mutex SessionMapMutex;
-static std::unordered_map<std::string, std::weak_ptr<ClientSession>> SessionMap;
+static std::mutex GlobalSessionMapMutex;
+static std::unordered_map<std::string, std::weak_ptr<ClientSession>> GlobalSessionMap;
ClientSession::ClientSession(const std::string& id,
const std::shared_ptr<DocumentBroker>& docBroker,
@@ -73,8 +73,8 @@ ClientSession::ClientSession(const std::string& id,
// Can't take a reference in the constructor.
void ClientSession::construct()
{
- std::unique_lock<std::mutex> lock(SessionMapMutex);
- SessionMap[getId()] = shared_from_this();
+ std::unique_lock<std::mutex> lock(GlobalSessionMapMutex);
+ GlobalSessionMap[getId()] = shared_from_this();
}
ClientSession::~ClientSession()
@@ -82,8 +82,8 @@ ClientSession::~ClientSession()
const size_t curConnections = --LOOLWSD::NumConnections;
LOG_INF("~ClientSession dtor [" << getName() << "], current number of connections: " << curConnections);
- std::unique_lock<std::mutex> lock(SessionMapMutex);
- SessionMap.erase(getId());
+ std::unique_lock<std::mutex> lock(GlobalSessionMapMutex);
+ GlobalSessionMap.erase(getId());
}
static const char *stateToString(ClientSession::SessionState s)
@@ -878,7 +878,7 @@ bool ClientSession::sendTile(const char * /*buffer*/, int /*length*/, const std:
try
{
TileDesc tileDesc = TileDesc::parse(tokens);
- tileDesc.setNormalizedViewId(getHash());
+ tileDesc.setNormalizedViewId(getCanonicalViewId());
docBroker->handleTileRequest(tileDesc, shared_from_this());
}
catch (const std::exception& exc)
@@ -896,7 +896,7 @@ bool ClientSession::sendCombinedTiles(const char* /*buffer*/, int /*length*/, co
try
{
TileCombined tileCombined = TileCombined::parse(tokens);
- tileCombined.setNormalizedViewId(getHash());
+ tileCombined.setNormalizedViewId(getCanonicalViewId());
docBroker->handleTileCombinedRequest(tileCombined, shared_from_this());
}
catch (const std::exception& exc)
@@ -1719,7 +1719,7 @@ void ClientSession::dumpState(std::ostream& os)
void ClientSession::handleTileInvalidation(const std::string& message,
const std::shared_ptr<DocumentBroker>& docBroker)
{
- docBroker->invalidateTiles(message, getHash());
+ docBroker->invalidateTiles(message, getCanonicalViewId());
// Skip requesting new tiles if we don't have client visible area data yet.
if(!_clientVisibleArea.hasSurface() ||
@@ -1744,7 +1744,7 @@ void ClientSession::handleTileInvalidation(const std::string& message,
if( part == -1 ) // If no part is specified we use the part used by the client
part = _clientSelectedPart;
- int normalizedViewId = getHash();
+ int normalizedViewId = getCanonicalViewId();
std::vector<TileDesc> invalidTiles;
if(part == _clientSelectedPart || _isTextDocument)
diff --git a/wsd/ClientSession.hpp b/wsd/ClientSession.hpp
index 770371df0..8ee184687 100644
--- a/wsd/ClientSession.hpp
+++ b/wsd/ClientSession.hpp
@@ -261,7 +261,7 @@ private:
/// Client is using a text document?
bool _isTextDocument;
- /// Rotating clipboard remote access identifiers - protected by SessionMapMutex
+ /// Rotating clipboard remote access identifiers - protected by GlobalSessionMapMutex
std::string _clipboardKeys[2];
/// TileID's of the sent tiles. Push by sending and pop by tileprocessed message from the client.
diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp
index 7e163e769..9bf7088c6 100644
--- a/wsd/DocumentBroker.cpp
+++ b/wsd/DocumentBroker.cpp
@@ -710,10 +710,7 @@ bool DocumentBroker::load(const std::shared_ptr<ClientSession>& session, const s
session->setUserName(username);
session->setUserExtraInfo(userExtraInfo);
session->setWatermarkText(watermarkText);
- if(!watermarkText.empty())
- session->setHash(watermarkText);
- else
- session->setHash(0);
+ session->recalcCanonicalViewId(_sessions);
// Basic file information was stored by the above getWOPIFileInfo() or getLocalFileInfo() calls
const StorageBase::FileInfo fileInfo = _storage->getFileInfo();
diff --git a/wsd/DocumentBroker.hpp b/wsd/DocumentBroker.hpp
index 07f967579..890e89e38 100644
--- a/wsd/DocumentBroker.hpp
+++ b/wsd/DocumentBroker.hpp
@@ -32,6 +32,7 @@
#include "net/WebSocketHandler.hpp"
#include "common/SigUtil.hpp"
+#include "common/Session.hpp"
#if !MOBILEAPP
#include "Admin.hpp"
@@ -481,7 +482,7 @@ private:
std::chrono::system_clock::time_point _lastFileModifiedTime;
/// All session of this DocBroker by ID.
- std::map<std::string, std::shared_ptr<ClientSession> > _sessions;
+ SessionMap<ClientSession> _sessions;
/// If we set the user-requested inital (on load) settings to be forced.
std::set<std::string> _isInitialStateSet;
More information about the Libreoffice-commits
mailing list