[Libreoffice-commits] online.git: 7 commits - loolwsd/ChildProcessSession.cpp loolwsd/Connect.cpp loolwsd/LOOLProtocol.cpp loolwsd/LOOLProtocol.hpp loolwsd/MasterProcessSession.cpp loolwsd/protocol.txt loolwsd/Util.cpp loolwsd/Util.hpp
Tor Lillqvist
tml at collabora.com
Wed Apr 20 15:55:21 UTC 2016
loolwsd/ChildProcessSession.cpp | 11 ++++++++++-
loolwsd/Connect.cpp | 34 ++++++++++++++++++++++++++++------
loolwsd/LOOLProtocol.cpp | 30 ++++++++++++++++++++++++++++++
loolwsd/LOOLProtocol.hpp | 6 ++++++
loolwsd/MasterProcessSession.cpp | 28 ++++++++++++++++++++--------
loolwsd/Util.cpp | 12 +++++++++---
loolwsd/Util.hpp | 3 +++
loolwsd/protocol.txt | 9 +++++++--
8 files changed, 113 insertions(+), 20 deletions(-)
New commits:
commit 5a509f9211a5b24dc0a8c0008d3c24e0448e41d0
Author: Tor Lillqvist <tml at collabora.com>
Date: Wed Apr 20 18:44:25 2016 +0300
In a debug build, say in the tile: reponse also whether it was found in cache
Also, do the construction of the response string in
MasterProcessSession::sendTile() only when it is actually going to be
used.
diff --git a/loolwsd/MasterProcessSession.cpp b/loolwsd/MasterProcessSession.cpp
index 0320de1..0dee495 100644
--- a/loolwsd/MasterProcessSession.cpp
+++ b/loolwsd/MasterProcessSession.cpp
@@ -7,6 +7,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
+#include "config.h"
+
#include <Poco/FileStream.h>
#include <Poco/JSON/Object.h>
#include <Poco/JSON/Parser.h>
@@ -572,16 +574,22 @@ void MasterProcessSession::sendTile(const char *buffer, int length, StringTokeni
return;
}
- const std::string response = "tile: " + Poco::cat(std::string(" "), tokens.begin() + 1, tokens.end()) + "\n";
-
- std::vector<char> output;
- output.reserve(4 * width * height);
- output.resize(response.size());
- std::memcpy(output.data(), response.data(), response.size());
-
std::unique_ptr<std::fstream> cachedTile = _docBroker->tileCache().lookupTile(part, width, height, tilePosX, tilePosY, tileWidth, tileHeight);
+
if (cachedTile)
{
+ std::string response = "tile: " + Poco::cat(std::string(" "), tokens.begin() + 1, tokens.end());
+
+#if ENABLE_DEBUG
+ response += " renderid=cached";
+#endif
+ response += "\n";
+
+ std::vector<char> output;
+ output.reserve(4 * width * height);
+ output.resize(response.size());
+ std::memcpy(output.data(), response.data(), response.size());
+
assert(cachedTile->is_open());
cachedTile->seekg(0, std::ios_base::end);
size_t pos = output.size();
@@ -691,6 +699,10 @@ void MasterProcessSession::sendCombinedTiles(const char* /*buffer*/, int /*lengt
oss << " timestamp=" << reqTimestamp;
}
+#if ENABLE_DEBUG
+ oss << " renderid=cached";
+#endif
+
oss << "\n";
const std::string response = oss.str();
diff --git a/loolwsd/protocol.txt b/loolwsd/protocol.txt
index 2c79445..1d2324d 100644
--- a/loolwsd/protocol.txt
+++ b/loolwsd/protocol.txt
@@ -237,9 +237,10 @@ tile: part=<partNumber> width=<width> height=<height> tileposx=<xpos> tileposy=<
The parameters from the corresponding 'tile' command.
- Additionally, in a debug build, the renderid is a unique
+ Additionally, in a debug build, the renderid is either a unique
identifier, different for each actual call to LibreOfficeKit to
- render a tile.
+ render a tile, or the string 'cached' if the tile was found in the
+ cache.
Each LOK_CALLBACK_FOO_BAR callback causes a corresponding message to
the client, consisting of the FOO_BAR part in lowercase, without
commit 842525c25cb74bfd1fc62b5e4a65cacf811b590b
Author: Tor Lillqvist <tml at collabora.com>
Date: Wed Apr 20 18:31:16 2016 +0300
Guard against mixing up cout output from separate threads
diff --git a/loolwsd/Connect.cpp b/loolwsd/Connect.cpp
index 8f64ff3..8c10f27 100644
--- a/loolwsd/Connect.cpp
+++ b/loolwsd/Connect.cpp
@@ -13,6 +13,7 @@
#include <cstring>
#include <fstream>
#include <iostream>
+#include <mutex>
#include <Poco/Version.h>
#include <Poco/Net/AcceptCertificateHandler.h>
@@ -68,6 +69,7 @@ using Poco::URI;
using Poco::Util::Application;
static bool closeExpected = false;
+static std::mutex coutMutex;
class Output: public Runnable
{
@@ -89,7 +91,10 @@ public:
n = _ws.receiveFrame(buffer, sizeof(buffer), flags);
if (n > 0 && (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE)
{
- std::cout << "Got " << n << " bytes: " << getAbbreviatedMessage(buffer, n) << std::endl;
+ {
+ std::unique_lock<std::mutex> lock(coutMutex);
+ std::cout << "Got " << n << " bytes: " << getAbbreviatedMessage(buffer, n) << std::endl;
+ }
std::string firstLine = getFirstLine(buffer, n);
StringTokenizer tokens(firstLine, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
@@ -109,12 +114,17 @@ public:
}
}
while (n > 0 && (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE);
- std::cout << "CLOSE frame received" << std::endl;
+
+ {
+ std::unique_lock<std::mutex> lock(coutMutex);
+ std::cout << "CLOSE frame received" << std::endl;
+ }
if (!closeExpected)
std::_Exit(Application::EXIT_SOFTWARE);
}
catch (WebSocketException& exc)
{
+ std::unique_lock<std::mutex> lock(coutMutex);
std::cout << "Got exception " << exc.message() << std::endl;
}
}
@@ -184,7 +194,10 @@ protected:
{
// Accept an input line "sleep <n>" that makes us sleep a number of seconds.
long sleepTime = std::stol(line.substr(std::string("sleep").length()));
- std::cout << "Sleeping " << sleepTime << " seconds" << std::endl;
+ {
+ std::unique_lock<std::mutex> lock(coutMutex);
+ std::cout << "Sleeping " << sleepTime << " seconds" << std::endl;
+ }
Thread::sleep(sleepTime * 1000);
}
else if (line == "exit")
@@ -192,7 +205,10 @@ protected:
// While hacking on LOOL and editing input files for this program back and forth it
// is a good idea to be able to add an enforced exit in the middle of the input
// file.
- std::cout << "Exiting" << std::endl;
+ {
+ std::unique_lock<std::mutex> lock(coutMutex);
+ std::cout << "Exiting" << std::endl;
+ }
break;
}
else if (line.find("#") == 0)
@@ -201,12 +217,18 @@ protected:
}
else
{
- std::cout << "Sending: '" << line << "'" << std::endl;
+ {
+ std::unique_lock<std::mutex> lock(coutMutex);
+ std::cout << "Sending: '" << line << "'" << std::endl;
+ }
ws.sendFrame(line.c_str(), line.size());
}
}
- std::cout << "Shutting down websocket" << std::endl;
+ {
+ std::unique_lock<std::mutex> lock(coutMutex);
+ std::cout << "Shutting down websocket" << std::endl;
+ }
closeExpected = true;
ws.shutdown();
thread.join();
commit 77a91c4b2e1fe1ea74f8a1e60c45cd3f4e1fd5c2
Author: Tor Lillqvist <tml at collabora.com>
Date: Wed Apr 20 17:06:08 2016 +0300
In debug builds append a renderid=<unique-id> token to tile: responses
Will be used in unit test to verify that several clients of the same
document asking for the same tile simultaneously indeed do cause just
one tile rendering to take place.
diff --git a/loolwsd/ChildProcessSession.cpp b/loolwsd/ChildProcessSession.cpp
index 0bdf33e..7fbebcf 100644
--- a/loolwsd/ChildProcessSession.cpp
+++ b/loolwsd/ChildProcessSession.cpp
@@ -700,7 +700,12 @@ void ChildProcessSession::sendTile(const char* /*buffer*/, int /*length*/, Strin
if (_multiView)
_loKitDocument->pClass->setView(_loKitDocument, _viewId);
- const std::string response = "tile: " + Poco::cat(std::string(" "), tokens.begin() + 1, tokens.end()) + "\n";
+ std::string response = "tile: " + Poco::cat(std::string(" "), tokens.begin() + 1, tokens.end());
+
+#if ENABLE_DEBUG
+ response += " renderid=" + Util::UniqueId();
+#endif
+ response += "\n";
std::vector<char> output;
output.reserve(response.size() + (4 * width * height));
@@ -853,6 +858,10 @@ void ChildProcessSession::sendCombinedTiles(const char* /*buffer*/, int /*length
if (reqTimestamp != "")
response += " timestamp=" + reqTimestamp;
+#if ENABLE_DEBUG
+ response += " renderid=" + Util::UniqueId();
+#endif
+
response += "\n";
std::vector<char> output;
diff --git a/loolwsd/protocol.txt b/loolwsd/protocol.txt
index 989dc13..2c79445 100644
--- a/loolwsd/protocol.txt
+++ b/loolwsd/protocol.txt
@@ -232,11 +232,15 @@ textselectioncontent: <content>
Current selection's content
-tile: part=<partNumber> width=<width> height=<height> tileposx=<xpos> tileposy=<ypos> tilewidth=<tileWidth> tileheight=<tileHeight> [timestamp=<time>]
+tile: part=<partNumber> width=<width> height=<height> tileposx=<xpos> tileposy=<ypos> tilewidth=<tileWidth> tileheight=<tileHeight> [timestamp=<time>] [renderid=<id>]
<binaryPngImage>
The parameters from the corresponding 'tile' command.
+ Additionally, in a debug build, the renderid is a unique
+ identifier, different for each actual call to LibreOfficeKit to
+ render a tile.
+
Each LOK_CALLBACK_FOO_BAR callback causes a corresponding message to
the client, consisting of the FOO_BAR part in lowercase, without
underscore, followed by a colon, space and the callback payload. For
commit 7b47548020ee23b5f8191e464ec72ed6dd39b2a9
Author: Tor Lillqvist <tml at collabora.com>
Date: Wed Apr 20 16:44:12 2016 +0300
Add getToken* variants that iterate over a StringTokenizer
If any of the tokens in the string matches name=<value> for the name
in question, store that value and return true. Otherwise return false.
diff --git a/loolwsd/LOOLProtocol.cpp b/loolwsd/LOOLProtocol.cpp
index ab87c22..eac5c71 100644
--- a/loolwsd/LOOLProtocol.cpp
+++ b/loolwsd/LOOLProtocol.cpp
@@ -117,6 +117,36 @@ namespace LOOLProtocol
return true;
}
+ bool getTokenInteger(const Poco::StringTokenizer& tokens, const std::string& name, int& value)
+ {
+ for (int i = 0; i < tokens.count(); i++)
+ {
+ if (getTokenInteger(tokens[i], name, value))
+ return true;
+ }
+ return false;
+ }
+
+ bool getTokenString(const Poco::StringTokenizer& tokens, const std::string& name, std::string& value)
+ {
+ for (int i = 0; i < tokens.count(); i++)
+ {
+ if (getTokenString(tokens[i], name, value))
+ return true;
+ }
+ return false;
+ }
+
+ bool getTokenKeyword(const Poco::StringTokenizer& tokens, const std::string& name, const std::map<std::string, int>& map, int& value)
+ {
+ for (int i = 0; i < tokens.count(); i++)
+ {
+ if (getTokenKeyword(tokens[i], name, map, value))
+ return true;
+ }
+ return false;
+ }
+
bool parseStatus(const std::string& message, LibreOfficeKitDocumentType& type, int& nParts, int& currentPart, int& width, int& height)
{
StringTokenizer tokens(message, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
diff --git a/loolwsd/LOOLProtocol.hpp b/loolwsd/LOOLProtocol.hpp
index 0ed166a..673e75f 100644
--- a/loolwsd/LOOLProtocol.hpp
+++ b/loolwsd/LOOLProtocol.hpp
@@ -13,6 +13,8 @@
#include <map>
#include <string>
+#include <Poco/StringTokenizer.h>
+
#define LOK_USE_UNSTABLE_API
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
@@ -40,6 +42,10 @@ namespace LOOLProtocol
bool getTokenString(const std::string& token, const std::string& name, std::string& value);
bool getTokenKeyword(const std::string& token, const std::string& name, const std::map<std::string, int>& map, int& value);
+ bool getTokenInteger(const Poco::StringTokenizer& tokens, const std::string& name, int& value);
+ bool getTokenString(const Poco::StringTokenizer& tokens, const std::string& name, std::string& value);
+ bool getTokenKeyword(const Poco::StringTokenizer& tokens, const std::string& name, const std::map<std::string, int>& map, int& value);
+
// Functions that parse messages. All return false if parsing fails
bool parseStatus(const std::string& message, LibreOfficeKitDocumentType& type, int& nParts, int& currentPart, int& width, int& height);
commit d423f7c2fdd2a21f7c2d32b110ba4613173d7ac7
Author: Tor Lillqvist <tml at collabora.com>
Date: Wed Apr 20 16:43:00 2016 +0300
Add Util::UniqueId() to get a string id that is unique across processes and calls
diff --git a/loolwsd/Util.cpp b/loolwsd/Util.cpp
index d30b31a..aef31fe 100644
--- a/loolwsd/Util.cpp
+++ b/loolwsd/Util.cpp
@@ -10,10 +10,13 @@
#include "config.h"
#include <execinfo.h>
+#include <signal.h>
#include <sys/poll.h>
#include <sys/prctl.h>
#include <sys/uio.h>
+#include <unistd.h>
+#include <atomic>
#include <cassert>
#include <cstdlib>
#include <cstring>
@@ -23,12 +26,9 @@
#include <random>
#include <sstream>
#include <string>
-#include <unistd.h>
#include <png.h>
-#include <signal.h>
-
#include <Poco/ConsoleChannel.h>
#include <Poco/Exception.h>
#include <Poco/Format.h>
@@ -437,6 +437,12 @@ namespace Util
hash.resize(std::min(8, (int)hash.length()));
std::cout << app << " " << LOOLWSD_VERSION << " - " << hash << std::endl;
}
+
+ std::string UniqueId()
+ {
+ static std::atomic_int counter(0);
+ return std::to_string(Poco::Process::id()) + "/" + std::to_string(counter++);
+ }
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/loolwsd/Util.hpp b/loolwsd/Util.hpp
index f2b0ffb..4647865 100644
--- a/loolwsd/Util.hpp
+++ b/loolwsd/Util.hpp
@@ -120,6 +120,9 @@ namespace Util
/// Display version information
void displayVersionInfo(const char *app);
+ /// Return a string that is unique across processes and calls.
+ std::string UniqueId();
+
/// Given one or more patterns to allow, and one or more to deny,
/// the match member will return true if, and only if, the subject
/// matches the allowed list, but not the deny.
commit e94e8344adcdf8c2cd24288792c22b8894d49f1a
Author: Tor Lillqvist <tml at collabora.com>
Date: Wed Apr 20 16:35:36 2016 +0300
IIUC, the 'tile' and 'tile:' messages have an optional timestamp parameter
diff --git a/loolwsd/protocol.txt b/loolwsd/protocol.txt
index 2b4d80f..989dc13 100644
--- a/loolwsd/protocol.txt
+++ b/loolwsd/protocol.txt
@@ -105,7 +105,7 @@ status
styles
-tile part=<partNumber> width=<width> height=<height> tileposx=<xpos> tileposy=<ypos> tilewidth=<tileWidth> tileheight=<tileHeight>
+tile part=<partNumber> width=<width> height=<height> tileposx=<xpos> tileposy=<ypos> tilewidth=<tileWidth> tileheight=<tileHeight> [timestamp=<time>]
All parameters are numbers.
@@ -232,7 +232,7 @@ textselectioncontent: <content>
Current selection's content
-tile: part=<partNumber> width=<width> height=<height> tileposx=<xpos> tileposy=<ypos> tilewidth=<tileWidth> tileheight=<tileHeight>
+tile: part=<partNumber> width=<width> height=<height> tileposx=<xpos> tileposy=<ypos> tilewidth=<tileWidth> tileheight=<tileHeight> [timestamp=<time>]
<binaryPngImage>
The parameters from the corresponding 'tile' command.
commit 949907170780f9da1da78f4cd07515ed82a450e8
Author: Tor Lillqvist <tml at collabora.com>
Date: Wed Apr 20 16:10:39 2016 +0300
Change comment to make sense
diff --git a/loolwsd/MasterProcessSession.cpp b/loolwsd/MasterProcessSession.cpp
index 54962b9..0320de1 100644
--- a/loolwsd/MasterProcessSession.cpp
+++ b/loolwsd/MasterProcessSession.cpp
@@ -196,7 +196,7 @@ bool MasterProcessSession::_handleInput(const char *buffer, int length)
queue = subscriber->getQueue();
// re-emit the tile command in the other thread
// to re-check and hit the cache. NB. it needs to be
- // 'tile' and not 'tile'
+ // 'tile' and not 'tile:'
if (queue)
{
std::string noColon = firstLine + "\n";
More information about the Libreoffice-commits
mailing list