[Libreoffice-commits] online.git: loolwsd/ChildProcessSession.cpp loolwsd/ChildProcessSession.hpp loolwsd/.gitignore loolwsd/LOOLKit.cpp loolwsd/LOOLWSD.cpp loolwsd/Makefile.am
Henry Castro
hcastro at collabora.com
Wed Dec 23 09:11:08 PST 2015
loolwsd/.gitignore | 4
loolwsd/ChildProcessSession.cpp | 9
loolwsd/ChildProcessSession.hpp | 19 +
loolwsd/LOOLKit.cpp | 617 ++++++++++++++++++++++++++++++++++++++++
loolwsd/LOOLWSD.cpp | 4
loolwsd/Makefile.am | 10
6 files changed, 657 insertions(+), 6 deletions(-)
New commits:
commit 4af013e87ec5bca1dc2f4fe9cc26970a3c2f1c7b
Author: Henry Castro <hcastro at collabora.com>
Date: Sat Dec 19 15:55:19 2015 -0500
loolwsd: LOOLKit process added
Change-Id: I91e8a131b4959a78e43b29faede477d39150c97c
Reviewed-on: https://gerrit.libreoffice.org/20902
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
Tested-by: Ashod Nakashian <ashnakash at gmail.com>
diff --git a/loolwsd/.gitignore b/loolwsd/.gitignore
index 0f52b76..2054b6a 100644
--- a/loolwsd/.gitignore
+++ b/loolwsd/.gitignore
@@ -19,15 +19,19 @@
/stamp-h1
/systemplate
/test-driver
+/jails
*.o
*.exe
cscope*
.*
+*.orig
+
connect
lokitclient
loadtest
loolwsd
+loolkit
sockettransporttest
# Debug output
diff --git a/loolwsd/ChildProcessSession.cpp b/loolwsd/ChildProcessSession.cpp
index dfa179f..f5b0320 100644
--- a/loolwsd/ChildProcessSession.cpp
+++ b/loolwsd/ChildProcessSession.cpp
@@ -40,6 +40,9 @@ using Poco::StringTokenizer;
using Poco::URI;
using Poco::Util::Application;
+Poco::NotificationQueue ChildProcessSession::_callbackQueue;
+Poco::Mutex ChildProcessSession::_mutex;
+
ChildProcessSession::ChildProcessSession(std::shared_ptr<WebSocket> ws,
LibreOfficeKit *loKit,
LibreOfficeKitDocument * loKitDocument,
@@ -528,6 +531,7 @@ bool ChildProcessSession::clientZoom(const char* /*buffer*/, int /*length*/, Str
_loKitDocument->pClass->setClientZoom(_loKitDocument, tilePixelWidth, tilePixelHeight, tileTwipWidth, tileTwipHeight);
return true;
}
+
bool ChildProcessSession::downloadAs(const char* /*buffer*/, int /*length*/, StringTokenizer& tokens)
{
std::string name, id, format, filterOptions;
@@ -568,8 +572,9 @@ bool ChildProcessSession::downloadAs(const char* /*buffer*/, int /*length*/, Str
format.size() == 0 ? NULL :format.c_str(),
filterOptions.size() == 0 ? NULL : filterOptions.c_str());
- sendTextFrame("downloadas: jail=" + _childId + " dir=" + tmpDir + " name=" + name +
- " port=" + std::to_string(LOOLWSD::portNumber) + " id=" + id);
+ //TODO: handle download portNumber.
+ //sendTextFrame("downloadas: jail=" + _childId + " dir=" + tmpDir + " name=" + name +
+ // " port=" + std::to_string(LOOLWSD::portNumber) + " id=" + id);
return true;
}
diff --git a/loolwsd/ChildProcessSession.hpp b/loolwsd/ChildProcessSession.hpp
index 5b7baef..63a24a3 100644
--- a/loolwsd/ChildProcessSession.hpp
+++ b/loolwsd/ChildProcessSession.hpp
@@ -13,6 +13,7 @@
#define LOK_USE_UNSTABLE_API
#include <LibreOfficeKit/LibreOfficeKit.h>
+#include <Poco/NotificationQueue.h>
#include "LOOLSession.hpp"
class ChildProcessSession final : public LOOLSession
@@ -42,6 +43,8 @@ public:
std::string _docType;
/// View ID, returned by createView() or 0 by default.
int _viewId;
+ static Poco::NotificationQueue _callbackQueue;
+ static Poco::Mutex _mutex;
protected:
virtual bool loadDocument(const char *buffer, int length, Poco::StringTokenizer& tokens) override;
@@ -74,6 +77,22 @@ public:
int _clientPart;
};
+class CallBackNotification: public Poco::Notification
+{
+public:
+ typedef Poco::AutoPtr<CallBackNotification> Ptr;
+
+ CallBackNotification(int nType, const std::string& rPayload, void* pSession)
+ : m_nType(nType),
+ m_aPayload(rPayload),
+ m_pSession(pSession)
+ {}
+
+ int m_nType;
+ std::string m_aPayload;
+ void* m_pSession;
+};
+
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp
new file mode 100644
index 0000000..af0b5f6
--- /dev/null
+++ b/loolwsd/LOOLKit.cpp
@@ -0,0 +1,617 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+/*
+ * NB. this file is compiled both standalone, and as part of the LOOLBroker.
+ */
+
+#include <sys/prctl.h>
+#include <sys/poll.h>
+#include <sys/syscall.h>
+
+#include <memory>
+#include <iostream>
+
+#include <Poco/Util/Application.h>
+#include <Poco/Net/WebSocket.h>
+#include <Poco/Net/HTTPClientSession.h>
+#include <Poco/Net/HTTPRequest.h>
+#include <Poco/Net/HTTPResponse.h>
+#include <Poco/Thread.h>
+#include <Poco/ThreadPool.h>
+#include <Poco/Runnable.h>
+#include <Poco/StringTokenizer.h>
+#include <Poco/Exception.h>
+#include <Poco/Process.h>
+#include <Poco/Environment.h>
+#include <Poco/NotificationQueue.h>
+#include <Poco/Notification.h>
+#include <Poco/Mutex.h>
+
+#define LOK_USE_UNSTABLE_API
+#include <LibreOfficeKit/LibreOfficeKitInit.h>
+
+#include "MessageQueue.hpp"
+#include "Util.hpp"
+#include "ChildProcessSession.hpp"
+#include "LOOLProtocol.hpp"
+
+using namespace LOOLProtocol;
+using Poco::Net::WebSocket;
+using Poco::Net::HTTPClientSession;
+using Poco::Net::HTTPRequest;
+using Poco::Net::HTTPResponse;
+using Poco::Thread;
+using Poco::Runnable;
+using Poco::StringTokenizer;
+using Poco::Exception;
+using Poco::Process;
+using Poco::Notification;
+using Poco::NotificationQueue;
+using Poco::FastMutex;
+
+const int MASTER_PORT_NUMBER = 9981;
+const std::string CHILD_URI = "/loolws/child/";
+const std::string LOKIT_BROKER = "/tmp/loolbroker.fifo";
+
+class CallBackWorker: public Runnable
+{
+public:
+ CallBackWorker(NotificationQueue& queue):
+ _queue(queue)
+ {
+ }
+
+ std::string callbackTypeToString (int nType)
+ {
+ switch (nType)
+ {
+ case LOK_CALLBACK_INVALIDATE_TILES:
+ return std::string("LOK_CALLBACK_INVALIDATE_TILES");
+ case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
+ return std::string("LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR");
+ case LOK_CALLBACK_TEXT_SELECTION:
+ return std::string("LOK_CALLBACK_TEXT_SELECTION");
+ case LOK_CALLBACK_TEXT_SELECTION_START:
+ return std::string("LOK_CALLBACK_TEXT_SELECTION_START");
+ case LOK_CALLBACK_TEXT_SELECTION_END:
+ return std::string("LOK_CALLBACK_TEXT_SELECTION_END");
+ case LOK_CALLBACK_CURSOR_VISIBLE:
+ return std::string("LOK_CALLBACK_CURSOR_VISIBLE");
+ case LOK_CALLBACK_GRAPHIC_SELECTION:
+ return std::string("LOK_CALLBACK_GRAPHIC_SELECTION");
+ case LOK_CALLBACK_HYPERLINK_CLICKED:
+ return std::string("LOK_CALLBACK_HYPERLINK_CLICKED");
+ case LOK_CALLBACK_STATE_CHANGED:
+ return std::string("LOK_CALLBACK_STATE_CHANGED");
+ case LOK_CALLBACK_STATUS_INDICATOR_START:
+ return std::string("LOK_CALLBACK_STATUS_INDICATOR_START");
+ case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE:
+ return std::string("LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE");
+ case LOK_CALLBACK_STATUS_INDICATOR_FINISH:
+ return std::string("LOK_CALLBACK_STATUS_INDICATOR_FINISH");
+ case LOK_CALLBACK_SEARCH_NOT_FOUND:
+ return std::string("LOK_CALLBACK_SEARCH_NOT_FOUND");
+ case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED:
+ return std::string("LOK_CALLBACK_DOCUMENT_SIZE_CHANGED");
+ case LOK_CALLBACK_SET_PART:
+ return std::string("LOK_CALLBACK_SET_PART");
+ }
+ return std::string("");
+ }
+
+ void callback(int nType, std::string& rPayload, void* pData)
+ {
+ ChildProcessSession *srv = reinterpret_cast<ChildProcessSession *>(pData);
+ pid_t tid = syscall(SYS_gettid);
+
+ //if ( nType == LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR )
+ std::cout << tid << " callback : " << srv->_viewId << " " << callbackTypeToString(nType) << " " << rPayload << std::endl;
+
+ switch ( nType )
+ {
+ case LOK_CALLBACK_INVALIDATE_TILES:
+ {
+ //int curPart = srv->_loKitDocument->pClass->getPart(srv->_loKitDocument);
+ int curPart = 0;
+ srv->sendTextFrame("curpart: part=" + std::to_string(curPart));
+ StringTokenizer tokens(rPayload, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
+ if (tokens.count() == 4)
+ {
+ int x(std::stoi(tokens[0]));
+ int y(std::stoi(tokens[1]));
+ int width(std::stoi(tokens[2]));
+ int height(std::stoi(tokens[3]));
+ srv->sendTextFrame("invalidatetiles:"
+ " part=" + std::to_string(curPart) +
+ " x=" + std::to_string(x) +
+ " y=" + std::to_string(y) +
+ " width=" + std::to_string(width) +
+ " height=" + std::to_string(height));
+ }
+ else {
+ srv->sendTextFrame("invalidatetiles: " + rPayload);
+ }
+ }
+ break;
+ case LOK_CALLBACK_STATUS_INDICATOR_START:
+ srv->sendTextFrame("statusindicatorstart:");
+ break;
+
+ case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE:
+ srv->sendTextFrame("statusindicatorsetvalue: " + rPayload);
+ break;
+
+ case LOK_CALLBACK_STATUS_INDICATOR_FINISH:
+ srv->sendTextFrame("statusindicatorfinish:");
+ break;
+ case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
+ srv->sendTextFrame("invalidatecursor: " + rPayload);
+ break;
+ case LOK_CALLBACK_TEXT_SELECTION:
+ srv->sendTextFrame("textselection: " + rPayload);
+ break;
+ case LOK_CALLBACK_TEXT_SELECTION_START:
+ srv->sendTextFrame("textselectionstart: " + rPayload);
+ break;
+ case LOK_CALLBACK_TEXT_SELECTION_END:
+ srv->sendTextFrame("textselectionend: " + rPayload);
+ break;
+ case LOK_CALLBACK_CURSOR_VISIBLE:
+ srv->sendTextFrame("cursorvisible: " + rPayload);
+ break;
+ case LOK_CALLBACK_GRAPHIC_SELECTION:
+ srv->sendTextFrame("graphicselection: " + rPayload);
+ break;
+ case LOK_CALLBACK_HYPERLINK_CLICKED:
+ srv->sendTextFrame("hyperlinkclicked: " + rPayload);
+ break;
+ case LOK_CALLBACK_STATE_CHANGED:
+ srv->sendTextFrame("statechanged: " + rPayload);
+ break;
+ case LOK_CALLBACK_SEARCH_NOT_FOUND:
+ srv->sendTextFrame("searchnotfound: " + rPayload);
+ break;
+ case LOK_CALLBACK_DOCUMENT_SIZE_CHANGED:
+ srv->getStatus("", 0);
+ break;
+ case LOK_CALLBACK_SET_PART:
+ srv->sendTextFrame("setpart: " + rPayload);
+ break;
+ }
+ }
+
+
+ void run()
+ {
+ while ( true )
+ {
+ Notification::Ptr aNotification(_queue.waitDequeueNotification());
+ if (aNotification)
+ {
+ CallBackNotification::Ptr aCallBackNotification = aNotification.cast<CallBackNotification>();
+ if (aCallBackNotification)
+ {
+ {
+ FastMutex::ScopedLock lock(_mutex);
+ callback(aCallBackNotification->m_nType, aCallBackNotification->m_aPayload, aCallBackNotification->m_pSession);
+ }
+ }
+ }
+ else break;
+ }
+ }
+
+private:
+ NotificationQueue& _queue;
+ static FastMutex _mutex;
+};
+
+FastMutex CallBackWorker::_mutex;
+
+class QueueHandler: public Runnable
+{
+public:
+ QueueHandler(MessageQueue& queue):
+ _queue(queue)
+ {
+ }
+
+ void setSession(std::shared_ptr<LOOLSession> session)
+ {
+ _session = session;
+ }
+
+ void run() override
+ {
+#ifdef __linux
+ if (prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("queue_handler"), 0, 0, 0) != 0)
+ std::cout << Util::logPrefix() << "Cannot set thread name :" << strerror(errno) << std::endl;
+#endif
+ while (true)
+ {
+ std::string input = _queue.get();
+ if (input == "eof")
+ break;
+ if (!_session->handleInput(input.c_str(), input.size()))
+ break;
+ }
+ }
+
+private:
+ std::shared_ptr<LOOLSession> _session;
+ MessageQueue& _queue;
+};
+
+class Connection: public Runnable
+{
+public:
+ Connection(LibreOfficeKit *loKit, LibreOfficeKitDocument *loKitDocument, Poco::UInt64 childId, const std::string& threadId) :
+ _loKit(loKit),
+ _loKitDocument(loKitDocument),
+ _childId(childId),
+ _threadId(threadId)
+ {
+ }
+
+ void start()
+ {
+ _thread.start(*this);
+ }
+
+ bool isRunning()
+ {
+ return _thread.isRunning();
+ }
+
+ LibreOfficeKitDocument * getLOKitDocument()
+ {
+ return (_session ? _session->_loKitDocument : NULL);
+ };
+
+ void run() override
+ {
+#ifdef __linux
+ if (prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("lokit_connection"), 0, 0, 0) != 0)
+ std::cout << Util::logPrefix() << "Cannot set thread name :" << strerror(errno) << std::endl;
+#endif
+ try
+ {
+ // Open websocket connection between the child process and the
+ // parent. The parent forwards us requests that it can't handle.
+
+ HTTPClientSession cs("127.0.0.1", MASTER_PORT_NUMBER);
+ cs.setTimeout(0);
+ HTTPRequest request(HTTPRequest::HTTP_GET, CHILD_URI);
+ HTTPResponse response;
+ std::shared_ptr<WebSocket> ws(new WebSocket(cs, request, response));
+
+ _session.reset(new ChildProcessSession(ws, _loKit, _loKitDocument, std::to_string(_childId)));
+ //std::shared_ptr<ChildProcessSession> session(new ChildProcessSession(ws, _loKit, _loKitDocument));
+ ws->setReceiveTimeout(0);
+
+ // child Jail TID PID
+ std::string hello("child " + std::to_string(_childId) + " " +
+ _threadId + " " + std::to_string(Process::id()));
+ _session->sendTextFrame(hello);
+
+ TileQueue queue;
+ Thread queueHandlerThread;
+ QueueHandler handler(queue);
+
+ handler.setSession(_session);
+ queueHandlerThread.start(handler);
+
+ int flags;
+ int n;
+ do
+ {
+ char buffer[1024];
+ n = ws->receiveFrame(buffer, sizeof(buffer), flags);
+
+ if (n > 0 && (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE)
+ {
+ std::string firstLine = getFirstLine(buffer, n);
+ StringTokenizer tokens(firstLine, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
+
+ // The only kind of messages a child process receives are the single-line ones (?)
+ assert(firstLine.size() == static_cast<std::string::size_type>(n));
+
+ queue.put(firstLine);
+ }
+ }
+ while (n > 0 && (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE);
+
+ queue.clear();
+ queue.put("eof");
+ queueHandlerThread.join();
+ }
+
+ catch (Exception& exc)
+ {
+ std::cout << Util::logPrefix() + "Exception: " + exc.what() << std::endl;
+ }
+ catch (std::exception& exc)
+ {
+ std::cout << Util::logPrefix() + "Exception: " + exc.what() << std::endl;
+ }
+ }
+
+ ~Connection()
+ {
+ //_thread.stop();
+ }
+
+private:
+ LibreOfficeKit *_loKit;
+ LibreOfficeKitDocument *_loKitDocument;
+ Poco::UInt64 _childId;
+ std::string _threadId;
+ Thread _thread;
+ std::shared_ptr<ChildProcessSession> _session;
+};
+
+void run_lok_main(const std::string &loSubPath, Poco::UInt64 _childId, const std::string& pipe)
+{
+ struct pollfd aPoll;
+ ssize_t nBytes = -1;
+ char aBuffer[1024*2];
+ char* pStart = NULL;
+ char* pEnd = NULL;
+
+ std::string aURL;
+ std::map<std::string, std::shared_ptr<Connection>> _connections;
+
+ assert (_childId != 0);
+ assert (!loSubPath.empty());
+
+#ifdef __linux
+ if (prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("libreofficekit"), 0, 0, 0) != 0)
+ std::cout << Util::logPrefix() << "Cannot set thread name :" << strerror(errno) << std::endl;
+#endif
+
+ try
+ {
+#ifdef __APPLE__
+ LibreOfficeKit *loKit(lok_init_2(("/" + loSubPath + "/Frameworks").c_str(), "file:///user"));
+#else
+ LibreOfficeKit *loKit(lok_init_2(("/" + loSubPath + "/program").c_str(), "file:///user"));
+#endif
+
+ if (!loKit)
+ {
+ std::cout << Util::logPrefix() + "LibreOfficeKit initialization failed" << std::endl;
+ exit(-1);
+ }
+
+ int writerBroker;
+ int readerBroker;
+
+ if ( (readerBroker = open(pipe.c_str(), O_RDONLY) ) < 0 )
+ {
+ std::cout << Util::logPrefix() << "open pipe read only: " << strerror(errno) << std::endl;
+ exit(-1);
+ }
+
+ if ( (writerBroker = open(LOKIT_BROKER.c_str(), O_WRONLY) ) < 0 )
+ {
+ std::cout << Util::logPrefix() << "open pipe write only: " << strerror(errno) << std::endl;
+ exit(-1);
+ }
+
+ CallBackWorker callbackWorker(ChildProcessSession::_callbackQueue);
+ Poco::ThreadPool::defaultPool().start(callbackWorker);
+
+ std::cout << Util::logPrefix() << "child ready!" << std::endl;
+
+ std::string aResponse;
+ std::string aMessage;
+
+ while ( true )
+ {
+ if ( pStart == pEnd )
+ {
+ aPoll.fd = readerBroker;
+ aPoll.events = POLLIN;
+ aPoll.revents = 0;
+
+ (void)poll(&aPoll, 1, -1);
+
+ if( (aPoll.revents & POLLIN) != 0 )
+ {
+ nBytes = Util::readFIFO(readerBroker, aBuffer, sizeof(aBuffer));
+ if (nBytes < 0)
+ {
+ pStart = pEnd = NULL;
+ std::cout << Util::logPrefix() << "Error reading message :" << strerror(errno) << std::endl;
+ continue;
+ }
+ pStart = aBuffer;
+ pEnd = aBuffer + nBytes;
+ }
+ }
+
+ if ( pStart != pEnd )
+ {
+ char aChar = *pStart++;
+ while (pStart != pEnd && aChar != '\r' && aChar != '\n')
+ {
+ aMessage += aChar;
+ aChar = *pStart++;
+ }
+
+ if ( aChar == '\r' && *pStart == '\n')
+ {
+ pStart++;
+ //std::cout << Util::logPrefix() << "child receive: " << aMessage << std::endl;
+ StringTokenizer tokens(aMessage, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
+
+ if (tokens[0] == "search")
+ {
+ if ( !_connections.empty() )
+ {
+ aResponse = std::to_string(Process::id()) + ( aURL == tokens[1] ? " ok \r\n" : " no \r\n");
+ Util::writeFIFO(writerBroker, aResponse.c_str(), aResponse.length() );
+ }
+ else
+ {
+ aURL.clear();
+ aResponse = std::to_string(Process::id()) + " empty \r\n";
+ Util::writeFIFO(writerBroker, aResponse.c_str(), aResponse.length() );
+ }
+ }
+ else if (tokens[0] == "thread")
+ {
+ auto aItem = _connections.find(tokens[1]);
+ if (aItem != _connections.end())
+ { // found item, check if still running
+ std::cout << Util::logPrefix() << "found thread" << std::endl;
+ if ( !aItem->second->isRunning() )
+ std::cout << Util::logPrefix() << "found thread not running!" << std::endl;
+ }
+ else
+ { // new thread id
+ //std::cout << Util::logPrefix() << "new thread starting!" << std::endl;
+ std::shared_ptr<Connection> thread;
+ if ( _connections.empty() )
+ {
+ std::cout << Util::logPrefix() << "create main thread" << std::endl;
+ thread = std::shared_ptr<Connection>(new Connection(loKit, NULL, _childId, tokens[1]));
+ }
+ else
+ {
+ std::cout << Util::logPrefix() << "create view thread" << std::endl;
+ auto aConnection = _connections.begin();
+ thread = std::shared_ptr<Connection>(new Connection(loKit, aConnection->second->getLOKitDocument(), _childId, tokens[1]));
+ }
+
+ auto aInserted = _connections.insert(
+ std::pair<std::string, std::shared_ptr<Connection>>
+ (
+ tokens[1],
+ thread
+ ));
+
+ if ( aInserted.second )
+ thread->start();
+ else
+ std::cout << Util::logPrefix() << "Connection not created!" << std::endl;
+
+ std::cout << Util::logPrefix() << "connections: " << Process::id() << " " << _connections.size() << std::endl;
+ }
+ }
+ else if (tokens[0] == "url")
+ {
+ aURL = tokens[1];
+ }
+ else
+ {
+ aResponse = "bad message \r\n";
+ Util::writeFIFO(writerBroker, aResponse.c_str(), aResponse.length() );
+ }
+ aMessage.clear();
+ }
+ }
+ }
+
+
+ // Destroy LibreOfficeKit
+ loKit->pClass->destroy(loKit);
+
+ pthread_exit(0);
+ }
+ catch (Exception& exc)
+ {
+ std::cout << Util::logPrefix() + "Exception: " + exc.what() << std::endl;
+ }
+ catch (std::exception& exc)
+ {
+ std::cout << Util::logPrefix() + "Exception: " + exc.what() << std::endl;
+ }
+
+ std::cout << Util::logPrefix() << "loolkit finished OK!" << std::endl;
+}
+
+#ifndef LOOLKIT_NO_MAIN
+
+/// Simple argument parsing wrapper / helper for the above.
+int main(int argc, char** argv)
+{
+ std::string loSubPath;
+ Poco::UInt64 _childId = 0;
+ std::string _pipe;
+
+ for (int i = 1; i < argc; ++i)
+ {
+ char *cmd = argv[i];
+ char *eq = NULL;
+ if (strstr(cmd, "--losubpath=") == cmd)
+ {
+ eq = strchrnul(cmd, '=');
+ if (*eq)
+ loSubPath = std::string(++eq);
+ }
+ else if (strstr(cmd, "--child=") == cmd)
+ {
+ eq = strchrnul(cmd, '=');
+ if (*eq)
+ _childId = std::stoll(std::string(++eq));
+ }
+ else if (strstr(cmd, "--pipe=") == cmd)
+ {
+ eq = strchrnul(cmd, '=');
+ if (*eq)
+ _pipe = std::string(++eq);
+ }
+ }
+
+ if (loSubPath.empty())
+ {
+ std::cout << Util::logPrefix() << "--losubpath is empty" << std::endl;
+ exit(1);
+ }
+
+ if ( !_childId )
+ {
+ std::cout << Util::logPrefix() << "--child is 0" << std::endl;
+ exit(1);
+ }
+
+ if ( _pipe.empty() )
+ {
+ std::cout << Util::logPrefix() << "--pipe is empty" << std::endl;
+ exit(1);
+ }
+
+ try
+ {
+ Poco::Environment::get("LD_BIND_NOW");
+ }
+ catch (Poco::NotFoundException& aError)
+ {
+ std::cout << Util::logPrefix() << aError.what() << std::endl;
+ }
+
+ try
+ {
+ Poco::Environment::get("LOK_VIEW_CALLBACK");
+ }
+ catch (Poco::NotFoundException& aError)
+ {
+ std::cout << Util::logPrefix() << aError.what() << std::endl;
+ }
+
+ run_lok_main(loSubPath, _childId, _pipe);
+
+ return 0;
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/loolwsd/LOOLWSD.cpp b/loolwsd/LOOLWSD.cpp
index f02d7e5..5588be2 100644
--- a/loolwsd/LOOLWSD.cpp
+++ b/loolwsd/LOOLWSD.cpp
@@ -1341,11 +1341,11 @@ int LOOLWSD::main(const std::vector<std::string>& /*args*/)
}
else
{
- std::cout << Util::logPrefix() << "None of our known child processes died :" << std::to_string(pid) << std::endl;
+ std::cout << Util::logPrefix() << "None of our known child processes died :" << std::to_string(pid) << std::endl;
}
}
else if (pid < 0)
- std::cout << Util::logPrefix() << "Child error: " << strerror(errno);
+ std::cout << Util::logPrefix() << "Child error: " << strerror(errno) << std::endl;
++timeoutCounter;
if (timeoutCounter == INTERVAL_PROBES)
diff --git a/loolwsd/Makefile.am b/loolwsd/Makefile.am
index e34292f..f5036bc 100644
--- a/loolwsd/Makefile.am
+++ b/loolwsd/Makefile.am
@@ -1,13 +1,15 @@
SUBDIRS = test
-bin_PROGRAMS = loolwsd
+bin_PROGRAMS = loolwsd loolkit
dist_bin_SCRIPTS = loolwsd-systemplate-setup
AM_CPPFLAGS = -pthread
AM_LDFLAGS = -pthread
-loolwsd_SOURCES = LOOLWSD.cpp LOOLSession.cpp MasterProcessSession.cpp ChildProcessSession.cpp MessageQueue.cpp TileCache.cpp Util.cpp LOOLProtocol.cpp
+shared_sources = MessageQueue.cpp Util.cpp
+
+loolwsd_SOURCES = LOOLWSD.cpp LOOLSession.cpp MasterProcessSession.cpp ChildProcessSession.cpp TileCache.cpp LOOLProtocol.cpp $(shared_sources)
noinst_PROGRAMS = loadtest connect lokitclient
@@ -17,6 +19,10 @@ connect_SOURCES = Connect.cpp Util.cpp LOOLProtocol.cpp
lokitclient_SOURCES = LOKitClient.cpp Util.cpp
+broker_shared_sources = ChildProcessSession.cpp LOOLProtocol.cpp LOOLSession.cpp $(shared_sources)
+
+loolkit_SOURCES = LOOLKit.cpp $(broker_shared_sources)
+
noinst_HEADERS = LOKitHelper.hpp LOOLProtocol.hpp LOOLSession.hpp MasterProcessSession.hpp ChildProcessSession.hpp LOOLWSD.hpp LoadTest.hpp MessageQueue.hpp TileCache.hpp Util.hpp Png.hpp \
bundled/include/LibreOfficeKit/LibreOfficeKit.h bundled/include/LibreOfficeKit/LibreOfficeKitEnums.h \
bundled/include/LibreOfficeKit/LibreOfficeKitInit.h bundled/include/LibreOfficeKit/LibreOfficeKitTypes.h
More information about the Libreoffice-commits
mailing list