loolwsd: centralized document loading in Document
Change-Id: I1ff7e0a53cc415958e46aea74c775d7f265b8b8e Reviewed-on: https://gerrit.libreoffice.org/21319 Reviewed-by: Ashod Nakashian <ashnakash@gmail.com> Tested-by: Ashod Nakashian <ashnakash@gmail.com>
This commit is contained in:
parent
2e34e2c8cf
commit
b3d06869f5
3 changed files with 63 additions and 62 deletions
|
@ -46,7 +46,7 @@ ChildProcessSession::ChildProcessSession(const std::string& id,
|
|||
LibreOfficeKit *loKit,
|
||||
LibreOfficeKitDocument * loKitDocument,
|
||||
const std::string& jailId,
|
||||
std::function<void(LibreOfficeKitDocument*, int)> onLoad,
|
||||
std::function<LibreOfficeKitDocument*(ChildProcessSession*, const std::string&)> onLoad,
|
||||
std::function<void(int)> onUnload) :
|
||||
LOOLSession(id, Kind::ToMaster, ws),
|
||||
_loKitDocument(loKitDocument),
|
||||
|
@ -230,15 +230,6 @@ bool ChildProcessSession::_handleInput(const char *buffer, int length)
|
|||
return true;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
static void myCallback(int nType, const char* pPayload, void* pData)
|
||||
{
|
||||
auto pNotif = new CallBackNotification(nType, pPayload ? pPayload : "(nil)", pData);
|
||||
ChildProcessSession::_callbackQueue.enqueueNotification(pNotif);
|
||||
}
|
||||
}
|
||||
|
||||
bool ChildProcessSession::loadDocument(const char * /*buffer*/, int /*length*/, StringTokenizer& tokens)
|
||||
{
|
||||
int part = -1;
|
||||
|
@ -256,29 +247,10 @@ bool ChildProcessSession::loadDocument(const char * /*buffer*/, int /*length*/,
|
|||
|
||||
Poco::Mutex::ScopedLock lock(_mutex);
|
||||
|
||||
if (_loKitDocument != nullptr)
|
||||
{
|
||||
Log::info("Loading view to document from URI: [" + _jailedFilePath + "].");
|
||||
|
||||
_viewId = _loKitDocument->pClass->createView(_loKitDocument);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::info("Loading new document from URI: [" + _jailedFilePath + "].");
|
||||
|
||||
if ( LIBREOFFICEKIT_HAS(_loKit, registerCallback))
|
||||
_loKit->pClass->registerCallback(_loKit, myCallback, this);
|
||||
|
||||
if ((_loKitDocument = _loKit->pClass->documentLoad(_loKit, _jailedFilePath.c_str())) == nullptr)
|
||||
{
|
||||
Log::error("Failed to load: " + _jailedFilePath + ", error: " + _loKit->pClass->getError(_loKit));
|
||||
sendTextFrame("error: cmd=load kind=failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
_loKitDocument = _onLoad(this, _jailedFilePath);
|
||||
|
||||
if (_multiView)
|
||||
_loKitDocument->pClass->setView(_loKitDocument, _viewId);
|
||||
_viewId = _loKitDocument->pClass->getView(_loKitDocument);
|
||||
|
||||
std::string renderingOptions;
|
||||
if (!_docOptions.empty())
|
||||
|
@ -297,14 +269,11 @@ bool ChildProcessSession::loadDocument(const char * /*buffer*/, int /*length*/,
|
|||
_loKitDocument->pClass->setPart(_loKitDocument, part);
|
||||
}
|
||||
|
||||
_loKitDocument->pClass->registerCallback(_loKitDocument, myCallback, this);
|
||||
|
||||
// Respond by the document status, whih has no arguments.
|
||||
// Respond by the document status, which has no arguments.
|
||||
if (!getStatus(nullptr, 0))
|
||||
return false;
|
||||
|
||||
_onLoad(_loKitDocument, _viewId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
LibreOfficeKit *loKit,
|
||||
LibreOfficeKitDocument * loKitDocument,
|
||||
const std::string& jailId,
|
||||
std::function<void(LibreOfficeKitDocument*, int)> onLoad,
|
||||
std::function<LibreOfficeKitDocument*(ChildProcessSession*, const std::string&)> onLoad,
|
||||
std::function<void(int)> onUnload);
|
||||
virtual ~ChildProcessSession();
|
||||
|
||||
|
@ -89,7 +89,7 @@ private:
|
|||
/// View ID, returned by createView() or 0 by default.
|
||||
int _viewId;
|
||||
int _clientPart;
|
||||
std::function<void(LibreOfficeKitDocument*, int)> _onLoad;
|
||||
std::function<LibreOfficeKitDocument*(ChildProcessSession*, const std::string&)> _onLoad;
|
||||
std::function<void(int)> _onUnload;
|
||||
};
|
||||
|
||||
|
|
|
@ -324,7 +324,7 @@ class Connection: public Runnable
|
|||
public:
|
||||
Connection(LibreOfficeKit *loKit, LibreOfficeKitDocument *loKitDocument,
|
||||
const std::string& jailId, const std::string& sessionId,
|
||||
std::function<void(LibreOfficeKitDocument*, int)> onLoad,
|
||||
std::function<LibreOfficeKitDocument*(ChildProcessSession*, const std::string&)> onLoad,
|
||||
std::function<void(int)> onUnload) :
|
||||
_loKit(loKit),
|
||||
_loKitDocument(loKitDocument),
|
||||
|
@ -346,6 +346,8 @@ public:
|
|||
const std::string& getSessionId() const { return _sessionId; }
|
||||
std::shared_ptr<WebSocket> getWebSocket() const { return _ws; }
|
||||
|
||||
std::shared_ptr<ChildProcessSession> getSession() { return _session; }
|
||||
|
||||
void start()
|
||||
{
|
||||
_thread.start(*this);
|
||||
|
@ -455,7 +457,7 @@ private:
|
|||
Thread _thread;
|
||||
std::shared_ptr<ChildProcessSession> _session;
|
||||
volatile bool _stop;
|
||||
std::function<void(LibreOfficeKitDocument*, int)> _onLoad;
|
||||
std::function<LibreOfficeKitDocument*(ChildProcessSession*, const std::string&)> _onLoad;
|
||||
std::function<void(int)> _onUnload;
|
||||
std::shared_ptr<WebSocket> _ws;
|
||||
};
|
||||
|
@ -545,7 +547,7 @@ public:
|
|||
<< " on child: " << _jailId << Log::end;
|
||||
|
||||
auto thread = std::make_shared<Connection>(_loKit, _loKitDocument, _jailId, sessionId,
|
||||
[this](LibreOfficeKitDocument *loKitDocument, const int viewId) { onLoad(loKitDocument, viewId); },
|
||||
[this](ChildProcessSession* session, const std::string& jailedFilePath) { return onLoad(session, jailedFilePath); },
|
||||
[this](const int viewId) { onUnload(viewId); });
|
||||
|
||||
const auto aInserted = _connections.emplace(sessionId, thread);
|
||||
|
@ -578,33 +580,63 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
void onLoad(LibreOfficeKitDocument *loKitDocument, const int viewId)
|
||||
static void DocumentCallback(int nType, const char* pPayload, void* pData)
|
||||
{
|
||||
Document* self = reinterpret_cast<Document*>(pData);
|
||||
if (self)
|
||||
{
|
||||
for (auto& it: self->_connections)
|
||||
{
|
||||
if (it.second->isRunning())
|
||||
{
|
||||
auto pNotif = new CallBackNotification(nType, pPayload ? pPayload : "(nil)", it.second->getSession().get());
|
||||
ChildProcessSession::_callbackQueue.enqueueNotification(pNotif);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ViewCallback(int nType, const char* pPayload, void* pData)
|
||||
{
|
||||
auto pNotif = new CallBackNotification(nType, pPayload ? pPayload : "(nil)", pData);
|
||||
ChildProcessSession::_callbackQueue.enqueueNotification(pNotif);
|
||||
}
|
||||
|
||||
/// Load a document (or view) and register callbacks.
|
||||
LibreOfficeKitDocument* onLoad(ChildProcessSession* session, const std::string& jailedFilePath)
|
||||
{
|
||||
if (_loKitDocument == nullptr)
|
||||
{
|
||||
Log::info("Loading new document from URI: [" + jailedFilePath + "].");
|
||||
|
||||
if ( LIBREOFFICEKIT_HAS(_loKit, registerCallback))
|
||||
_loKit->pClass->registerCallback(_loKit, DocumentCallback, this);
|
||||
|
||||
if ((_loKitDocument = _loKit->pClass->documentLoad(_loKit, jailedFilePath.c_str())) == nullptr)
|
||||
{
|
||||
Log::error("Failed to load: " + jailedFilePath + ", error: " + _loKit->pClass->getError(_loKit));
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (_multiView)
|
||||
{
|
||||
Log::info("Loading view to document from URI: [" + jailedFilePath + "].");
|
||||
const auto viewId = _loKitDocument->pClass->createView(_loKitDocument);
|
||||
|
||||
_loKitDocument->pClass->registerCallback(_loKitDocument, ViewCallback, session);
|
||||
|
||||
++_clientViews;
|
||||
Log::info() << "Document [" << _url << "] view ["
|
||||
<< viewId << "] loaded, leaving "
|
||||
<< _clientViews << " views." << Log::end;
|
||||
|
||||
assert(loKitDocument != nullptr);
|
||||
|
||||
// Check that the document instance doesn't change.
|
||||
if (_loKitDocument != nullptr)
|
||||
assert(_loKitDocument == loKitDocument);
|
||||
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
|
||||
if (_loKitDocument == nullptr)
|
||||
{
|
||||
_loKitDocument = loKitDocument;
|
||||
|
||||
if (_multiView)
|
||||
{
|
||||
// Create a view so we retain the document in memory
|
||||
// when all clients are disconnected.
|
||||
_mainViewId = _loKitDocument->pClass->createView(loKitDocument);
|
||||
Log::info("Created main view [" + std::to_string(_mainViewId) + "].");
|
||||
}
|
||||
else
|
||||
{
|
||||
_loKitDocument->pClass->registerCallback(_loKitDocument, DocumentCallback, this);
|
||||
}
|
||||
|
||||
return _loKitDocument;
|
||||
}
|
||||
|
||||
void onUnload(const int viewId)
|
||||
|
|
Loading…
Reference in a new issue