https://bugs.kde.org/show_bug.cgi?id=525025

Sharad <[email protected]> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |[email protected]

--- Comment #4 from Sharad <[email protected]> ---
I hit the same freeze today (master, built from source with debug info) and the
symbolized
backtrace pins down the cycle. Trigger here was ordinary use: an SMS app
conversation was open
(RequestConversationWorker running for thread 152) when a reply sent from the
phone arrived.

Thread 2 (RequestConversationWorker):
  QSemaphore::acquire
  QDBusConnection::asyncCall
  OrgKdeKdeconnectDeviceSmsInterface::requestConversation
  ConversationsDbusInterface::updateConversation  
conversationsdbusinterface.cpp:199
  RequestConversationWorker::handleRequestConversation  
requestconversationworker.cpp:52

Thread 1 (main):
  QReadWriteLock::lockForWrite
  ConversationsDbusInterface::addMessages   conversationsdbusinterface.cpp:137
  SmsPlugin::handleBatchMessages   smsplugin.cpp:126
  Device::privateReceivedPacket
  LanDeviceLink::dataReceived

Cause: updateConversation() takes waitingForMessagesLock for write and, still
holding it, calls
m_smsInterface.requestConversation(). That is a D-Bus call to the daemon's own
SMS plugin object,
which lives on the main thread, so the worker blocks until the main thread
dispatches it. If a
batch packet arrives first, the main thread enters addMessages() and blocks on
lockForWrite()
of the same lock. Neither can proceed, and the whole daemon stops answering
D-Bus.

The lock was a QMutex before 3bf16922b, but the call was made under it then as
well, so this is
not new; more concurrent requestConversation workers (as in the comments above)
just make the
window easier to hit.

Possible fix: release the lock around the D-Bus call. The conversation ID is
already in
conversationsWaitingForMessages, so a reply that lands before we re-lock simply
removes it and
the wait loop falls through:

--- a/plugins/sms/conversationsdbusinterface.cpp
+++ b/plugins/sms/conversationsdbusinterface.cpp
@@ ConversationsDbusInterface::updateConversation
         numberToRequest = MIN_NUMBER_TO_REQUEST;
     }
+    // Do not hold the lock across the D-Bus call: it is delivered on the main
thread,
+    // which may be blocked in addMessages() waiting for this same lock
+    waitingForMessagesLock.unlock();
     m_smsInterface.requestConversation(conversationID, rangeStartTimestamp,
numberToRequest);

+    waitingForMessagesLock.lockForRead();
     while (conversationsWaitingForMessages.contains(conversationID)) {
         waitingForMessages.wait(&waitingForMessagesLock);
     }

I am running with this locally now.

Side effect seen on the client: while the daemon was wedged, kdeconnect-sms
crashed with a null
m_conversationsInterface in ConversationModel::requestMessages()
(conversationmodel.cpp:172),
reached via QAbstractItemModel::fetchMore() from the ListView before the model
had a deviceId.
requestMessages() checks m_threadId but not the interface pointer.

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to