loolwsd/LOOLSession.hpp | 2 loolwsd/MasterProcessSession.cpp | 73 +++--------------------------------- loolwsd/TileCache.cpp | 79 ++++++++++++++++++++++++++++++++++----- loolwsd/TileCache.hpp | 13 ++++-- 4 files changed, 89 insertions(+), 78 deletions(-)
New commits: commit 8f7eed639cdb358354b5157d7f2c5b0e2202cafd Author: Michael Meeks <[email protected]> Date: Sat Apr 23 17:11:11 2016 +0100 Re-factor tile subscription logic. Move the logic into the TileCache, simplify the API, and internalize the lock. This should be a plain re-factor. diff --git a/loolwsd/LOOLSession.hpp b/loolwsd/LOOLSession.hpp index 86d398d..95d1fc8 100644 --- a/loolwsd/LOOLSession.hpp +++ b/loolwsd/LOOLSession.hpp @@ -68,6 +68,8 @@ public: void closeFrame() { _isCloseFrame = true; }; bool isCloseFrame() const { return _isCloseFrame; } + Kind getKind() const { return _kind; } + protected: LOOLSession(const std::string& id, const Kind kind, std::shared_ptr<Poco::Net::WebSocket> ws); diff --git a/loolwsd/MasterProcessSession.cpp b/loolwsd/MasterProcessSession.cpp index cae00ce..58e1910 100644 --- a/loolwsd/MasterProcessSession.cpp +++ b/loolwsd/MasterProcessSession.cpp @@ -195,45 +195,8 @@ bool MasterProcessSession::_handleInput(const char *buffer, int length) assert(_kind == Kind::ToPrisoner); assert(firstLine.size() < static_cast<std::string::size_type>(length)); _docBroker->tileCache().saveTile(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight, buffer + firstLine.size() + 1, length - firstLine.size() - 1); - auto lock = _docBroker->tileCache().getTilesBeingRenderedLock(); - std::shared_ptr<TileBeingRendered> tileBeingRendered = _docBroker->tileCache().findTileBeingRendered(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight); - if (tileBeingRendered) - { - for (auto i: tileBeingRendered->getSubscribers()) - { - auto subscriber = i.lock(); - if (subscriber) - { - if (subscriber.get() == this) - { - Log::debug("Refusing to queue new tile message for ourselves"); - continue; - } - - Log::debug("Sending tile message also to subscriber " + subscriber->getName() + " line: '" + firstLine + "'"); - std::shared_ptr<BasicTileQueue> queue; - queue = subscriber->getQueue(); - // Re-emit the tile command in the other thread(s) to re-check and hit - // the cache. Construct the message from scratch to contain only the - // mandatory parts of the message. - if (queue) - { - const std::string message("tile " - " part=" + std::to_string(part) + - " width=" + std::to_string(width) + - " height=" + std::to_string(height) + - " tileposx=" + std::to_string(tilePosX) + - " tileposy=" + std::to_string(tilePosY) + - " tilewidth=" + std::to_string(tileWidth) + - " tileheight=" + std::to_string(tileHeight) + - "\n"); - queue->put(message); - } - } - } - _docBroker->tileCache().forgetTileBeingRendered(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight); - } - lock.unlock(); + + _docBroker->tileCache().notifyAndRemoveSubscribers(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight, this); } else if (tokens[0] == "status:") { @@ -595,17 +558,10 @@ void MasterProcessSession::sendTile(const char *buffer, int length, StringTokeni return; } - auto lock = _docBroker->tileCache().getTilesBeingRenderedLock(); - std::shared_ptr<TileBeingRendered> tileBeingRendered = _docBroker->tileCache().findTileBeingRendered(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight); - if (tileBeingRendered) - { - Log::debug("Tile is already being rendered, subscribing"); - assert(_kind == Kind::ToClient); - tileBeingRendered->subscribe(shared_from_this()); + if (_docBroker->tileCache().isTileBeingRenderedIfSoSubscribe( + part, width, height, tilePosX, tilePosY, tileWidth, + tileHeight, shared_from_this())) return; - } - _docBroker->tileCache().rememberTileAsBeingRendered(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight); - lock.unlock(); if (_peer.expired()) dispatchChild(); @@ -713,22 +669,9 @@ void MasterProcessSession::sendCombinedTiles(const char* /*buffer*/, int /*lengt } else { - // FIXME: rip out into a helper method [!?] ... - auto lock = _docBroker->tileCache().getTilesBeingRenderedLock(); - std::shared_ptr<TileBeingRendered> tileBeingRendered = _docBroker->tileCache().findTileBeingRendered(part, pixelWidth, pixelHeight, x, y, tileWidth, tileHeight); - bool subscribed = false; - if (tileBeingRendered) - { - Log::debug("Tile (combined) is already being rendered, subscribing"); - assert(_kind == Kind::ToClient); - tileBeingRendered->subscribe(shared_from_this()); - subscribed = true; - } - else - _docBroker->tileCache().rememberTileAsBeingRendered(part, pixelWidth, pixelHeight, x, y, tileWidth, tileHeight); - lock.unlock(); - - if (!subscribed) + if (!_docBroker->tileCache().isTileBeingRenderedIfSoSubscribe( + part, pixelWidth, pixelHeight, x, y, tileWidth, + tileHeight, shared_from_this())) { if (!forwardTileX.empty()) forwardTileX += ","; diff --git a/loolwsd/TileCache.cpp b/loolwsd/TileCache.cpp index 033eb44..383bb87 100644 --- a/loolwsd/TileCache.cpp +++ b/loolwsd/TileCache.cpp @@ -33,6 +33,7 @@ #include "LOOLProtocol.hpp" #include "TileCache.hpp" #include "Util.hpp" +#include "MasterProcessSession.hpp" using Poco::DirectoryIterator; using Poco::File; @@ -93,15 +94,6 @@ TileCache::TileCache(const std::string& docURL, TileCache::~TileCache() { Log::info("~TileCache dtor for uri [" + _docURL + "]."); -#if 0 - auto lock = getTilesBeingRenderedLock(); - _tilesBeingRendered.clear(); -#endif -} - -std::unique_lock<std::mutex> TileCache::getTilesBeingRenderedLock() -{ - return std::unique_lock<std::mutex>(_tilesBeingRenderedMutex); } void TileCache::rememberTileAsBeingRendered(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight) @@ -357,4 +349,68 @@ void TileCache::saveLastModified(const Timestamp& timestamp) modTimeFile.close(); } +void TileCache::notifyAndRemoveSubscribers(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight, MasterProcessSession *emitter) +{ + std::unique_lock<std::mutex> lock(_tilesBeingRenderedMutex); + + std::shared_ptr<TileBeingRendered> tileBeingRendered = findTileBeingRendered(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight); + if (!tileBeingRendered) + return; + + Log::debug("Sending tile message also to subscribers"); + + for (auto i: tileBeingRendered->getSubscribers()) + { + auto subscriber = i.lock(); + if (subscriber) + { + if (subscriber.get() == emitter) + { + Log::error("Refusing to queue new tile message for ourselves"); + continue; + } + + std::shared_ptr<BasicTileQueue> queue; + queue = subscriber->getQueue(); + // Re-emit the tile command in the other thread(s) to re-check and hit + // the cache. Construct the message from scratch to contain only the + // mandatory parts of the message. + if (queue) + { + const std::string message("tile " + " part=" + std::to_string(part) + + " width=" + std::to_string(width) + + " height=" + std::to_string(height) + + " tileposx=" + std::to_string(tilePosX) + + " tileposy=" + std::to_string(tilePosY) + + " tilewidth=" + std::to_string(tileWidth) + + " tileheight=" + std::to_string(tileHeight) + + "\n"); + queue->put(message); + } + } + } + forgetTileBeingRendered(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight); + + lock.unlock(); +} + +bool TileCache::isTileBeingRenderedIfSoSubscribe(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight, const std::shared_ptr<MasterProcessSession> &subscriber) +{ + std::unique_lock<std::mutex> lock(_tilesBeingRenderedMutex); + + std::shared_ptr<TileBeingRendered> tileBeingRendered = findTileBeingRendered(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight); + if (tileBeingRendered) + { + Log::debug("Tile is already being rendered, subscribing"); + assert(subscriber->getKind() == LOOLSession::Kind::ToClient); + tileBeingRendered->subscribe(subscriber); + return true; + } + rememberTileAsBeingRendered(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight); + lock.unlock(); + + return false; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/loolwsd/TileCache.hpp b/loolwsd/TileCache.hpp index f4911b4..f52533d 100644 --- a/loolwsd/TileCache.hpp +++ b/loolwsd/TileCache.hpp @@ -44,17 +44,21 @@ public: TileCache(const TileCache&) = delete; - std::unique_lock<std::mutex> getTilesBeingRenderedLock(); - void rememberTileAsBeingRendered(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight); - std::shared_ptr<TileBeingRendered> findTileBeingRendered(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight); + std::shared_ptr<TileBeingRendered> findTileBeingRendered(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight) +; + + bool isTileBeingRenderedIfSoSubscribe(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight, const std::shared_ptr<MasterProcessSession> &subscriber); void forgetTileBeingRendered(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight); std::unique_ptr<std::fstream> lookupTile(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight); void saveTile(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight, const char *data, size_t size); + + void notifyAndRemoveSubscribers(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight, MasterProcessSession *emitter); + std::string getTextFile(const std::string& fileName); // Save some text into a file in the cache directory commit 2c2504a07341a55f565ddae80a758a02b0776447 Author: Michael Meeks <[email protected]> Date: Sat Apr 23 16:53:03 2016 +0100 Time stamp subscriptions to tile rendering. diff --git a/loolwsd/TileCache.cpp b/loolwsd/TileCache.cpp index 6fbdc63..033eb44 100644 --- a/loolwsd/TileCache.cpp +++ b/loolwsd/TileCache.cpp @@ -44,6 +44,11 @@ using Poco::URI; using namespace LOOLProtocol; +TileBeingRendered::TileBeingRendered() +{ + _startTime.update(); +} + void TileBeingRendered::subscribe(const std::weak_ptr<MasterProcessSession>& session) { std::shared_ptr<MasterProcessSession> cmp = session.lock(); diff --git a/loolwsd/TileCache.hpp b/loolwsd/TileCache.hpp index 7c6c279..f4911b4 100644 --- a/loolwsd/TileCache.hpp +++ b/loolwsd/TileCache.hpp @@ -25,9 +25,10 @@ class MasterProcessSession; class TileBeingRendered { + Poco::Timestamp _startTime; std::vector<std::weak_ptr<MasterProcessSession>> _subscribers; - public: + TileBeingRendered(); void subscribe(const std::weak_ptr<MasterProcessSession>& session); std::vector<std::weak_ptr<MasterProcessSession>> getSubscribers(); }; _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
