[Libreoffice-commits] online.git: loolwsd/ChildProcessSession.cpp loolwsd/LOOLKit.cpp
Ashod Nakashian
ashod.nakashian at collabora.co.uk
Sat Apr 30 14:34:54 UTC 2016
loolwsd/ChildProcessSession.cpp | 9 ++++
loolwsd/LOOLKit.cpp | 79 ++++++++++++----------------------------
2 files changed, 33 insertions(+), 55 deletions(-)
New commits:
commit ce64895ceec81f3b28265c635b95c3f4ff636fc5
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date: Fri Apr 29 21:41:23 2016 -0400
bccu#1751 deadlock during save
While there are two separate callbacks registered
(one with lokit and the other with lokitDocument,)
there is no reason why they should be handled
separately (and indeed differently).
The lokit callback only sends notifications on
status indicator (during loading and saving)
and document password type (if protected).
Due to the different callback handlers
the status indicator was only sent to the
first client, not all (as one expects).
Furthermore, because the lokit callback
was processed on the Core thread, it
was bound to cause performance and
thread-safety issues. Specifically it
deadlocked when another callback was
in flight when a save issued status
indicator callback.
By unifying the callbacks and putting
all callback messages on the message
queue we avoid all of the above and
simplify the code.
Change-Id: I5bd790b6ce88b7939186c1ec1dead7fb6cabf7e0
Reviewed-on: https://gerrit.libreoffice.org/24522
Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
Tested-by: Ashod Nakashian <ashnakash at gmail.com>
diff --git a/loolwsd/ChildProcessSession.cpp b/loolwsd/ChildProcessSession.cpp
index f159ca8..abd18a2 100644
--- a/loolwsd/ChildProcessSession.cpp
+++ b/loolwsd/ChildProcessSession.cpp
@@ -218,6 +218,15 @@ public:
case LOK_CALLBACK_CONTEXT_MENU:
_session.sendTextFrame("contextmenu: " + rPayload);
break;
+ case LOK_CALLBACK_STATUS_INDICATOR_START:
+ _session.sendTextFrame("statusindicatorstart:");
+ break;
+ case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE:
+ _session.sendTextFrame("statusindicatorsetvalue: " + rPayload);
+ break;
+ case LOK_CALLBACK_STATUS_INDICATOR_FINISH:
+ _session.sendTextFrame("statusindicatorfinish:");
+ break;
}
}
diff --git a/loolwsd/LOOLKit.cpp b/loolwsd/LOOLKit.cpp
index cb3446a..c62d504 100644
--- a/loolwsd/LOOLKit.cpp
+++ b/loolwsd/LOOLKit.cpp
@@ -575,73 +575,41 @@ public:
}
private:
- static void KitCallback(int nType, const char* pPayload, void* pData)
- {
- Document* self = reinterpret_cast<Document*>(pData);
- Log::trace() << "Document::KitCallback "
- << LOKitHelper::kitCallbackTypeToString(nType)
- << " [" << (pPayload ? pPayload : "") << "]." << Log::end;
-
- if (self)
- {
- std::unique_lock<std::mutex> lock(self->_mutex);
- for (auto& it: self->_connections)
- {
- if (it.second->isRunning())
- {
- auto session = it.second->getSession();
- auto sessionLock = session->getLock();
-
- switch (nType)
- {
- case LOK_CALLBACK_STATUS_INDICATOR_START:
- session->sendTextFrame("statusindicatorstart:");
- break;
- case LOK_CALLBACK_STATUS_INDICATOR_SET_VALUE:
- session->sendTextFrame("statusindicatorsetvalue: " + std::string(pPayload));
- break;
- case LOK_CALLBACK_STATUS_INDICATOR_FINISH:
- session->sendTextFrame("statusindicatorfinish:");
- break;
- case LOK_CALLBACK_DOCUMENT_PASSWORD:
- case LOK_CALLBACK_DOCUMENT_PASSWORD_TO_MODIFY:
- self->setDocumentPassword(nType);
- break;
- }
-
- // Ideally, there would be only one *live* connection at this point of time
- // So, just get the first running one and break out.
- // TODO: Find a better way to find the correct connection.
- break;
- }
- }
- }
- }
static void ViewCallback(int , const char* , void* )
{
//TODO: Delegate the callback.
}
- static void DocumentCallback(int nType, const char* pPayload, void* pData)
+ static void DocumentCallback(const int nType, const char* pPayload, void* pData)
{
Log::trace() << "Document::DocumentCallback "
<< LOKitHelper::kitCallbackTypeToString(nType)
<< " [" << (pPayload ? pPayload : "") << "]." << Log::end;
Document* self = reinterpret_cast<Document*>(pData);
- if (self)
+ if (self == nullptr)
{
- std::unique_lock<std::mutex> lock(self->_mutex);
+ return;
+ }
+
+ std::unique_lock<std::mutex> lock(self->_mutex);
- for (auto& it: self->_connections)
+ if (nType == LOK_CALLBACK_DOCUMENT_PASSWORD_TO_MODIFY ||
+ nType == LOK_CALLBACK_DOCUMENT_PASSWORD)
+ {
+ // Mark the document password type.
+ self->setDocumentPassword(nType);
+ return;
+ }
+
+ for (auto& it: self->_connections)
+ {
+ if (it.second->isRunning())
{
- if (it.second->isRunning())
+ auto session = it.second->getSession();
+ if (session)
{
- auto session = it.second->getSession();
- if (session)
- {
- session->loKitCallback(nType, pPayload);
- }
+ session->loKitCallback(nType, pPayload);
}
}
}
@@ -740,9 +708,10 @@ private:
if (LIBREOFFICEKIT_HAS(_loKit, registerCallback))
{
- _loKit->pClass->registerCallback(_loKit, KitCallback, this);
- _loKit->pClass->setOptionalFeatures(_loKit, LOK_FEATURE_DOCUMENT_PASSWORD |
- LOK_FEATURE_DOCUMENT_PASSWORD_TO_MODIFY);
+ _loKit->pClass->registerCallback(_loKit, DocumentCallback, this);
+ const auto flags = LOK_FEATURE_DOCUMENT_PASSWORD
+ | LOK_FEATURE_DOCUMENT_PASSWORD_TO_MODIFY;
+ _loKit->pClass->setOptionalFeatures(_loKit, flags);
}
// Save the provided password with us and the jailed url
More information about the Libreoffice-commits
mailing list