loolwsd/DocumentBroker.cpp | 6 -- loolwsd/TileCache.cpp | 95 +++++++++++++++++++++------------------- loolwsd/TileCache.hpp | 4 - loolwsd/test/TileCacheTests.cpp | 2 4 files changed, 54 insertions(+), 53 deletions(-)
New commits: commit 6e54fd05f91547d7abda8336fcda248688be71ff Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> Date: Sun May 22 15:20:24 2016 -0400 loolwsd: merge saveTile and notifyAndRemoveSubscribers Change-Id: I8282604c02a9fd1a7a1e2a5df29e2f84fca151a6 Reviewed-on: https://gerrit.libreoffice.org/25344 Reviewed-by: Ashod Nakashian <ashnak...@gmail.com> Tested-by: Ashod Nakashian <ashnak...@gmail.com> diff --git a/loolwsd/DocumentBroker.cpp b/loolwsd/DocumentBroker.cpp index c555298..10600da 100644 --- a/loolwsd/DocumentBroker.cpp +++ b/loolwsd/DocumentBroker.cpp @@ -538,8 +538,7 @@ void DocumentBroker::handleTileResponse(const std::vector<char>& payload) if(firstLine.size() < static_cast<std::string::size_type>(length) - 1) { - tileCache().saveTile(tile, buffer + firstLine.size() + 1, length - firstLine.size() - 1); - tileCache().notifyAndRemoveSubscribers(tile); + tileCache().saveTileAndNotify(tile, buffer + firstLine.size() + 1, length - firstLine.size() - 1); } else { @@ -572,8 +571,7 @@ void DocumentBroker::handleTileCombinedResponse(const std::vector<char>& payload { for (const auto& tile : tileCombined.getTiles()) { - tileCache().saveTile(tile, buffer + offset, tile.getImgSize()); - tileCache().notifyAndRemoveSubscribers(tile); + tileCache().saveTileAndNotify(tile, buffer + offset, tile.getImgSize()); offset += tile.getImgSize(); } } diff --git a/loolwsd/TileCache.cpp b/loolwsd/TileCache.cpp index 48721d2..c006bc1 100644 --- a/loolwsd/TileCache.cpp +++ b/loolwsd/TileCache.cpp @@ -75,12 +75,14 @@ TileCache::~TileCache() struct TileCache::TileBeingRendered { std::vector<std::weak_ptr<ClientSession>> _subscribers; - TileBeingRendered(const int version) + TileBeingRendered(const std::string& cachedName, const int version) : _startTime(std::chrono::steady_clock::now()), + _cachedName(cachedName), _ver(version) { } + const std::string& getCacheName() const { return _cachedName; } int getVersion() const { return _ver; } std::chrono::steady_clock::time_point getStartTime() const { return _startTime; } @@ -91,6 +93,7 @@ struct TileCache::TileBeingRendered private: std::chrono::steady_clock::time_point _startTime; + std::string _cachedName; int _ver; }; @@ -132,15 +135,52 @@ std::unique_ptr<std::fstream> TileCache::lookupTile(const TileDesc& tile) return nullptr; } -void TileCache::saveTile(const TileDesc& tile, const char *data, size_t size) +void TileCache::saveTileAndNotify(const TileDesc& tile, const char *data, size_t size) { - const std::string fileName = _cacheDir + "/" + cacheFileName(tile); + std::unique_lock<std::mutex> lock(_tilesBeingRenderedMutex); - Log::trace() << "Saving cache tile: " << fileName << Log::end; + std::shared_ptr<TileBeingRendered> tileBeingRendered = findTileBeingRendered(tile); + if (tileBeingRendered && tileBeingRendered->getVersion() != tile.getVersion()) + { + Log::trace() << "Skipping unexpected tile ver: " << tile.getVersion() + << ", waiting for ver " << tileBeingRendered->getVersion() << Log::end; + return; + } + // Save to disk. + const auto cachedName = (tileBeingRendered ? tileBeingRendered->getCacheName() + : cacheFileName(tile)); + const auto fileName = _cacheDir + "/" + cachedName; + Log::trace() << "Saving cache tile: " << fileName << Log::end; std::fstream outStream(fileName, std::ios::out); outStream.write(data, size); outStream.close(); + + // Notify subscribers, if any. + if (tileBeingRendered) + { + if (!tileBeingRendered->_subscribers.empty()) + { + const std::string message = tile.serialize("tile"); + Log::debug("Sending tile message to subscribers: " + message); + + for (const auto& i: tileBeingRendered->_subscribers) + { + auto subscriber = i.lock(); + if (subscriber) + { + //FIXME: This is inefficient; should just send directly to each client (although that is risky as well! + // 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. + subscriber->sendToInputQueue(message); + } + } + } + + // Remove subscriptions. + _tilesBeingRendered.erase(cachedName); + } } std::string TileCache::getTextFile(const std::string& fileName) @@ -255,10 +295,10 @@ void TileCache::invalidateTiles(int part, int x, int y, int width, int height) // Forget this tile as it will have to be rendered again. for (auto it = _tilesBeingRendered.begin(); it != _tilesBeingRendered.end(); ) { - const std::string cacheName = it->first; - if (intersectsTile(cacheName, part, x, y, width, height)) + const std::string cachedName = it->first; + if (intersectsTile(cachedName, part, x, y, width, height)) { - Log::debug("Removing subscriptions for: " + cacheName); + Log::debug("Removing subscriptions for: " + cachedName); it = _tilesBeingRendered.erase(it); } else @@ -359,42 +399,6 @@ void TileCache::saveLastModified(const Timestamp& timestamp) modTimeFile.close(); } -void TileCache::notifyAndRemoveSubscribers(const TileDesc& tile) -{ - std::unique_lock<std::mutex> lock(_tilesBeingRenderedMutex); - - std::shared_ptr<TileBeingRendered> tileBeingRendered = findTileBeingRendered(tile); - if (!tileBeingRendered) - { - // We don't have anything to send back. - return; - } - - if (tileBeingRendered->getVersion() != tile.getVersion()) - { - Log::trace() << "Skipping unexpected tile ver: " << tile.getVersion() << ", waiting for " << tileBeingRendered->getVersion() << Log::end; - return; - } - - const std::string message = tile.serialize("tile"); - Log::debug("Sending tile message to subscribers: " + message); - - for (const auto& i: tileBeingRendered->_subscribers) - { - auto subscriber = i.lock(); - if (subscriber) - { - //FIXME: This is inefficient; should just send directly to each client (although that is risky as well! - // 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. - subscriber->sendToInputQueue(message); - } - } - - forgetTileBeingRendered(tile); -} - // FIXME: to be further simplified when we centralize tile messages. int TileCache::isTileBeingRenderedIfSoSubscribe(const TileDesc& tile, const std::shared_ptr<ClientSession> &subscriber) { @@ -430,13 +434,14 @@ int TileCache::isTileBeingRenderedIfSoSubscribe(const TileDesc& tile, const std: else { Log::debug() << "Tile (" << tile.getPart() << ',' << tile.getTilePosX() << ',' - << tile.getTilePosY() << ") needs rendering, subscribing." << Log::end; + << tile.getTilePosY() << ") needs rendering, subscribing for ver: " + << tile.getVersion() << "." << Log::end; const std::string cachedName = cacheFileName(tile); assert(_tilesBeingRendered.find(cachedName) == _tilesBeingRendered.end()); - tileBeingRendered = std::make_shared<TileBeingRendered>(tile.getVersion()); + tileBeingRendered = std::make_shared<TileBeingRendered>(cachedName, tile.getVersion()); tileBeingRendered->_subscribers.push_back(subscriber); _tilesBeingRendered[cachedName] = tileBeingRendered; diff --git a/loolwsd/TileCache.hpp b/loolwsd/TileCache.hpp index f776b51..0867d96 100644 --- a/loolwsd/TileCache.hpp +++ b/loolwsd/TileCache.hpp @@ -44,9 +44,7 @@ public: std::unique_ptr<std::fstream> lookupTile(const TileDesc& tile); - void saveTile(const TileDesc& tile, const char *data, size_t size); - - void notifyAndRemoveSubscribers(const TileDesc& tile); + void saveTileAndNotify(const TileDesc& tile, const char *data, size_t size); std::string getTextFile(const std::string& fileName); diff --git a/loolwsd/test/TileCacheTests.cpp b/loolwsd/test/TileCacheTests.cpp index a40b0db..6a7adca 100644 --- a/loolwsd/test/TileCacheTests.cpp +++ b/loolwsd/test/TileCacheTests.cpp @@ -145,7 +145,7 @@ void TileCacheTests::testSimple() // Cache Tile const auto size = 1024; const auto data = genRandomData(size); - tc.saveTile(tile, data.data(), size); + tc.saveTileAndNotify(tile, data.data(), size); // Find Tile file = tc.lookupTile(tile); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits