loolwsd/DocumentBroker.cpp | 87 +++++++++++---------------------------- loolwsd/DocumentBroker.hpp | 3 - loolwsd/MasterProcessSession.cpp | 39 +++-------------- loolwsd/TileCache.cpp | 62 ++++++++++++--------------- loolwsd/TileCache.hpp | 14 +++--- loolwsd/test/TileCacheTests.cpp | 9 ++-- 6 files changed, 73 insertions(+), 141 deletions(-)
New commits: commit d18bca992c2774c2c7b41ae0999a7d5d30a8822c Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> Date: Sun May 15 18:47:08 2016 -0400 loolwsd: use TileDesc instead of explicit values Change-Id: I56ba6c4e63a495500093e7353477175d40152d11 Reviewed-on: https://gerrit.libreoffice.org/25020 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 fe09607..35af2c3 100644 --- a/loolwsd/DocumentBroker.cpp +++ b/loolwsd/DocumentBroker.cpp @@ -399,32 +399,15 @@ bool DocumentBroker::handleInput(const std::vector<char>& payload) return true; } -void DocumentBroker::handleTileRequest(int part, int width, int height, int tilePosX, - int tilePosY, int tileWidth, int tileHeight, int id, +void DocumentBroker::handleTileRequest(const TileDesc& tile, const std::shared_ptr<MasterProcessSession>& session) { - Log::trace() << "Tile request for part: " << part << ", width: " << width << ", height: " << height - << ", tilePosX: " << tilePosX << ", tilePosY: " << tilePosY << ", tileWidth: " << tileWidth - << ", tileHeight: " << tileHeight << ", id: " << id << Log::end; - - std::ostringstream oss; - oss << " part=" << part - << " width=" << width - << " height=" << height - << " tileposx=" << tilePosX - << " tileposy=" << tilePosY - << " tilewidth=" << tileWidth - << " tileheight=" << tileHeight; - if (id >= 0) - { - oss << " id=" << id; - } - - const std::string tileMsg = oss.str(); + const auto tileMsg = tile.serialize(); + Log::trace() << "Tile request for " << tileMsg << Log::end; std::unique_lock<std::mutex> lock(_mutex); - std::unique_ptr<std::fstream> cachedTile = _tileCache->lookupTile(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight); + std::unique_ptr<std::fstream> cachedTile = _tileCache->lookupTile(tile); if (cachedTile) { @@ -435,7 +418,7 @@ void DocumentBroker::handleTileRequest(int part, int width, int height, int tile #endif std::vector<char> output; - output.reserve(4 * width * height); + output.reserve(4 * tile.getWidth() * tile.getHeight()); output.resize(response.size()); std::memcpy(output.data(), response.data(), response.size()); @@ -452,12 +435,10 @@ void DocumentBroker::handleTileRequest(int part, int width, int height, int tile return; } - if (tileCache().isTileBeingRenderedIfSoSubscribe( - part, width, height, tilePosX, tilePosY, tileWidth, - tileHeight, session)) + if (tileCache().isTileBeingRenderedIfSoSubscribe(tile, session)) return; - Log::debug() << "Sending render request for tile (" << part << ',' << tilePosX << ',' << tilePosY << ")." << Log::end; + Log::debug() << "Sending render request for tile (" << tile.getPart() << ',' << tile.getTilePosX() << ',' << tile.getTilePosY() << ")." << Log::end; // Forward to child to render. const std::string request = "tile " + tileMsg; @@ -467,45 +448,29 @@ void DocumentBroker::handleTileRequest(int part, int width, int height, int tile void DocumentBroker::handleTileResponse(const std::vector<char>& payload) { const std::string firstLine = getFirstLine(payload); - Poco::StringTokenizer tokens(firstLine, " ", Poco::StringTokenizer::TOK_IGNORE_EMPTY | Poco::StringTokenizer::TOK_TRIM); - - int part, width, height, tilePosX, tilePosY, tileWidth, tileHeight; - if (tokens.count() < 8 || - !getTokenInteger(tokens[1], "part", part) || - !getTokenInteger(tokens[2], "width", width) || - !getTokenInteger(tokens[3], "height", height) || - !getTokenInteger(tokens[4], "tileposx", tilePosX) || - !getTokenInteger(tokens[5], "tileposy", tilePosY) || - !getTokenInteger(tokens[6], "tilewidth", tileWidth) || - !getTokenInteger(tokens[7], "tileheight", tileHeight)) - { - //FIXME: Return error. - //sendTextFrame("error: cmd=tile kind=syntax"); - Log::error("Invalid tile request [" + firstLine + "]."); - return; - } - - size_t index = 8; - int id = -1; - if (tokens.count() > index && tokens[index].find("id") == 0) + try { - getTokenInteger(tokens[index], "id", id); - ++index; - } - - const auto buffer = payload.data(); - const auto length = payload.size(); + auto tile = TileDesc::parse(firstLine); + const auto buffer = payload.data(); + const auto length = payload.size(); - if(firstLine.size() < static_cast<std::string::size_type>(length) - 1) - { - tileCache().saveTile(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight, buffer + firstLine.size() + 1, length - firstLine.size() - 1); - tileCache().notifyAndRemoveSubscribers(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight, id); + 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); + } + else + { + Log::debug() << "Render request declined for " << firstLine << Log::end; + std::unique_lock<std::mutex> tileBeingRenderedLock(tileCache().getTilesBeingRenderedLock()); + tileCache().forgetTileBeingRendered(tile); + } } - else + catch (const std::exception& exc) { - Log::debug() << "Render request declined for " << firstLine << Log::end; - std::unique_lock<std::mutex> tileBeingRenderedLock(tileCache().getTilesBeingRenderedLock()); - tileCache().forgetTileBeingRendered(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight); + Log::error("Failed to process tile response [" + firstLine + "]: " + exc.what() + "."); + //FIXME: Return error. + //sendTextFrame("error: cmd=tile kind=syntax"); } } diff --git a/loolwsd/DocumentBroker.hpp b/loolwsd/DocumentBroker.hpp index ca22419..89b1036 100644 --- a/loolwsd/DocumentBroker.hpp +++ b/loolwsd/DocumentBroker.hpp @@ -197,8 +197,7 @@ public: /// Removes a session by ID. Returns the new number of sessions. size_t removeSession(const std::string& id); - void handleTileRequest(int part, int width, int height, int tilePosX, - int tilePosY, int tileWidth, int tileHeight, int id, + void handleTileRequest(const TileDesc& tile, const std::shared_ptr<MasterProcessSession>& session); void handleTileResponse(const std::vector<char>& payload); diff --git a/loolwsd/MasterProcessSession.cpp b/loolwsd/MasterProcessSession.cpp index c62ef32..afc864d 100644 --- a/loolwsd/MasterProcessSession.cpp +++ b/loolwsd/MasterProcessSession.cpp @@ -499,41 +499,16 @@ void MasterProcessSession::sendFontRendering(const char *buffer, int length, Str void MasterProcessSession::sendTile(const char * /*buffer*/, int /*length*/, StringTokenizer& tokens) { - int part, width, height, tilePosX, tilePosY, tileWidth, tileHeight, id = -1; - if (tokens.count() < 8 || - !getTokenInteger(tokens[1], "part", part) || - !getTokenInteger(tokens[2], "width", width) || - !getTokenInteger(tokens[3], "height", height) || - !getTokenInteger(tokens[4], "tileposx", tilePosX) || - !getTokenInteger(tokens[5], "tileposy", tilePosY) || - !getTokenInteger(tokens[6], "tilewidth", tileWidth) || - !getTokenInteger(tokens[7], "tileheight", tileHeight)) + try { - sendTextFrame("error: cmd=tile kind=syntax"); - return; + auto tileDesc = TileDesc::parse(tokens); + _docBroker->handleTileRequest(tileDesc, shared_from_this()); } - - if (part < 0 || - width <= 0 || - height <= 0 || - tilePosX < 0 || - tilePosY < 0 || - tileWidth <= 0 || - tileHeight <= 0) + catch (const std::exception& exc) { + Log::error(std::string("Failed to process tile command: ") + exc.what() + "."); sendTextFrame("error: cmd=tile kind=invalid"); - return; } - - size_t index = 8; - if (tokens.count() > index && tokens[index].find("id") == 0) - { - getTokenInteger(tokens[index], "id", id); - ++index; - } - - _docBroker->handleTileRequest(part, width, height, tilePosX, tilePosY, - tileWidth, tileHeight, id, shared_from_this()); } void MasterProcessSession::sendCombinedTiles(const char* /*buffer*/, int /*length*/, StringTokenizer& tokens) @@ -604,8 +579,8 @@ void MasterProcessSession::sendCombinedTiles(const char* /*buffer*/, int /*lengt return; } - _docBroker->handleTileRequest(part, pixelWidth, pixelHeight, x, y, - tileWidth, tileHeight, id, shared_from_this()); + const TileDesc tile(part, pixelWidth, pixelHeight, x, y, tileWidth, tileHeight); + _docBroker->handleTileRequest(tile, shared_from_this()); } } diff --git a/loolwsd/TileCache.cpp b/loolwsd/TileCache.cpp index a139490..44213e6 100644 --- a/loolwsd/TileCache.cpp +++ b/loolwsd/TileCache.cpp @@ -141,9 +141,9 @@ private: std::chrono::steady_clock::time_point _startTime; }; -std::shared_ptr<TileCache::TileBeingRendered> TileCache::findTileBeingRendered(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight) +std::shared_ptr<TileCache::TileBeingRendered> TileCache::findTileBeingRendered(const TileDesc& tileDesc) { - const std::string cachedName = cacheFileName(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight); + const std::string cachedName = cacheFileName(tileDesc); Util::assertIsLocked(_tilesBeingRenderedMutex); @@ -151,9 +151,9 @@ std::shared_ptr<TileCache::TileBeingRendered> TileCache::findTileBeingRendered(i return (tile != _tilesBeingRendered.end() ? tile->second : nullptr); } -void TileCache::forgetTileBeingRendered(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight) +void TileCache::forgetTileBeingRendered(const TileDesc& tile) { - const std::string cachedName = cacheFileName(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight); + const std::string cachedName = cacheFileName(tile); Util::assertIsLocked(_tilesBeingRenderedMutex); @@ -161,12 +161,14 @@ void TileCache::forgetTileBeingRendered(int part, int width, int height, int til _tilesBeingRendered.erase(cachedName); } -std::unique_ptr<std::fstream> TileCache::lookupTile(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight) +std::unique_ptr<std::fstream> TileCache::lookupTile(const TileDesc& tile) { - const std::string fileName = _cacheDir + "/" + cacheFileName(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight); + const std::string fileName = _cacheDir + "/" + cacheFileName(tile); std::unique_ptr<std::fstream> result(new std::fstream(fileName, std::ios::in)); - UnitWSD::get().lookupTile(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight, result); + UnitWSD::get().lookupTile(tile.getPart(), tile.getWidth(), tile.getHeight(), + tile.getTilePosX(), tile.getTilePosY(), + tile.getTileWidth(), tile.getTileHeight(), result); if (result && result->is_open()) { @@ -177,9 +179,9 @@ std::unique_ptr<std::fstream> TileCache::lookupTile(int part, int width, int hei return nullptr; } -void TileCache::saveTile(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight, const char *data, size_t size) +void TileCache::saveTile(const TileDesc& tile, const char *data, size_t size) { - const std::string fileName = _cacheDir + "/" + cacheFileName(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight); + const std::string fileName = _cacheDir + "/" + cacheFileName(tile); Log::trace() << "Saving cache tile: " << fileName << Log::end; @@ -331,12 +333,12 @@ void TileCache::removeFile(const std::string& fileName) Log::info("Removed file: " + fullFileName); } -std::string TileCache::cacheFileName(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight) +std::string TileCache::cacheFileName(const TileDesc& tile) { std::ostringstream oss; - oss << part << '_' << width << 'x' << height << '.' - << tilePosX << ',' << tilePosY << '.' - << tileWidth << 'x' << tileHeight << ".png"; + oss << tile.getPart() << '_' << tile.getWidth() << 'x' << tile.getHeight() << '.' + << tile.getTilePosX() << ',' << tile.getTilePosY() << '.' + << tile.getTileWidth() << 'x' << tile.getTileHeight() << ".png"; return oss.str(); } @@ -386,28 +388,15 @@ 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, int id) +void TileCache::notifyAndRemoveSubscribers(const TileDesc& tile) { std::unique_lock<std::mutex> lock(_tilesBeingRenderedMutex); - std::shared_ptr<TileBeingRendered> tileBeingRendered = findTileBeingRendered(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight); + std::shared_ptr<TileBeingRendered> tileBeingRendered = findTileBeingRendered(tile); if (!tileBeingRendered) return; - std::ostringstream oss; - oss << "tile part=" << part - << " width=" << width - << " height=" << height - << " tileposx=" << tilePosX - << " tileposy=" << tilePosY - << " tilewidth=" << tileWidth - << " tileheight=" << tileHeight; - if (id >= 0) - { - oss << " id=" << id; - } - - const std::string message = oss.str(); + const std::string message = tile.serialize("tile"); Log::debug("Sending tile message to subscribers: " + message); for (const auto& i: tileBeingRendered->_subscribers) @@ -427,19 +416,21 @@ void TileCache::notifyAndRemoveSubscribers(int part, int width, int height, int } } } - forgetTileBeingRendered(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight); + + forgetTileBeingRendered(tile); } // FIXME: to be further simplified when we centralize tile messages. -bool TileCache::isTileBeingRenderedIfSoSubscribe(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight, const std::shared_ptr<MasterProcessSession> &subscriber) +bool TileCache::isTileBeingRenderedIfSoSubscribe(const TileDesc& tile, 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); + std::shared_ptr<TileBeingRendered> tileBeingRendered = findTileBeingRendered(tile); if (tileBeingRendered) { - Log::debug() << "Tile (" << part << ',' << tilePosX << ',' << tilePosY << ") is already being rendered, subscribing." << Log::end; + Log::debug() << "Tile (" << tile.getPart() << ',' << tile.getTilePosX() << ',' + << tile.getTilePosY() << ") is already being rendered, subscribing." << Log::end; assert(subscriber->getKind() == LOOLSession::Kind::ToClient); for (const auto &s : tileBeingRendered->_subscribers) @@ -463,9 +454,10 @@ bool TileCache::isTileBeingRenderedIfSoSubscribe(int part, int width, int height } else { - Log::debug() << "Tile (" << part << ',' << tilePosX << ',' << tilePosY << ") needs rendering, subscribing." << Log::end; + Log::debug() << "Tile (" << tile.getPart() << ',' << tile.getTilePosX() << ',' + << tile.getTilePosY() << ") needs rendering, subscribing." << Log::end; - const std::string cachedName = cacheFileName(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight); + const std::string cachedName = cacheFileName(tile); assert(_tilesBeingRendered.find(cachedName) == _tilesBeingRendered.end()); diff --git a/loolwsd/TileCache.hpp b/loolwsd/TileCache.hpp index 9afe4c6..8b102e8 100644 --- a/loolwsd/TileCache.hpp +++ b/loolwsd/TileCache.hpp @@ -83,7 +83,7 @@ class TileCache { struct TileBeingRendered; - std::shared_ptr<TileBeingRendered> findTileBeingRendered(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight); + std::shared_ptr<TileBeingRendered> findTileBeingRendered(const TileDesc& tile); public: /// When the docURL is a non-file:// url, the timestamp has to be provided by the caller. @@ -94,13 +94,13 @@ public: TileCache(const TileCache&) = delete; - bool isTileBeingRenderedIfSoSubscribe(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight, const std::shared_ptr<MasterProcessSession> &subscriber); + bool isTileBeingRenderedIfSoSubscribe(const TileDesc& tile, const std::shared_ptr<MasterProcessSession> &subscriber); - std::unique_ptr<std::fstream> lookupTile(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight); + std::unique_ptr<std::fstream> lookupTile(const TileDesc& tile); - void saveTile(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight, const char *data, size_t size); + void saveTile(const TileDesc& tile, const char *data, size_t size); - void notifyAndRemoveSubscribers(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight, int id); + void notifyAndRemoveSubscribers(const TileDesc& tile); std::string getTextFile(const std::string& fileName); @@ -124,7 +124,7 @@ public: std::unique_lock<std::mutex> getTilesBeingRenderedLock() { return std::unique_lock<std::mutex>(_tilesBeingRenderedMutex); } - void forgetTileBeingRendered(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight); + void forgetTileBeingRendered(const TileDesc& tile); private: void invalidateTiles(int part, int x, int y, int width, int height); @@ -132,7 +132,7 @@ private: // Removes the given file from the cache void removeFile(const std::string& fileName); - std::string cacheFileName(int part, int width, int height, int tilePosX, int tilePosY, int tileWidth, int tileHeight); + std::string cacheFileName(const TileDesc& tile); bool parseCacheFileName(const std::string& fileName, int& part, int& width, int& height, int& tilePosX, int& tilePosY, int& tileWidth, int& tileHeight); /// Extract location from fileName, and check if it intersects with [x, y, width, height]. diff --git a/loolwsd/test/TileCacheTests.cpp b/loolwsd/test/TileCacheTests.cpp index abd8865..8906cda 100644 --- a/loolwsd/test/TileCacheTests.cpp +++ b/loolwsd/test/TileCacheTests.cpp @@ -125,18 +125,19 @@ void TileCacheTests::testSimple() int tilePosY = 0; int tileWidth = 3840; int tileHeight = 3840; + TileDesc tile(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight); // No Cache - auto file = tc.lookupTile(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight); + auto file = tc.lookupTile(tile); CPPUNIT_ASSERT_MESSAGE("found tile when none was expected", !file); // Cache Tile const auto size = 1024; const auto data = genRandomData(size); - tc.saveTile(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight, data.data(), size); + tc.saveTile(tile, data.data(), size); // Find Tile - file = tc.lookupTile(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight); + file = tc.lookupTile(tile); CPPUNIT_ASSERT_MESSAGE("tile not found when expected", file && file->is_open()); const auto tileData = readDataFromFile(file); CPPUNIT_ASSERT_MESSAGE("cached tile corrupted", data == tileData); @@ -145,7 +146,7 @@ void TileCacheTests::testSimple() tc.invalidateTiles("invalidatetiles: EMPTY"); // No Cache - file = tc.lookupTile(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight); + file = tc.lookupTile(tile); CPPUNIT_ASSERT_MESSAGE("found tile when none was expected", !file); } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits