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

Jérôme L <[email protected]> changed:

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

--- Comment #3 from Jérôme L <[email protected]> ---
Here is a technical explanation of the issue and two potential solutions.
I will send a MR for the first fix soon.
Adding Alexander for the idea in the last paragraph.

The issue involves the overview (kwin), Milou.ResultsView, the plugin
RecentDocuments (plasma-workspace) and Database/QSqlDatabaseWrapper
(plasma-activities-stats).
QSqlError is thrown when loading the plugin RecentDocuments on a new thread
with the same handle as an old thread.
The steps to reproduce are not consistent because the error depends on thread
ids/handles, but tends to occur more frequently as more handles are reused.

What happends?
1. When clearing the field or leaving overview, Milou.ResultsView's parent is
deactivated, destroying the ResultsView, ResultsModel, RunnerManager and
plugins instances.
2. When Milou.ResultsView is activated again, new instances are created,
RunnerManager::loadRunners is called, loading the plugin RecentDocuments on a
new thread (RunnerManagerPrivate::startJob).
3. RecentDocuments creates KActivities::Stats::ResultModel, Database::instance
tries to get an open database connection using the current thread id.
4. A weak_ptr is found in databases for the same thread id, but is 0x0 because
the thread as been deleted since.
5. In QSqlDatabaseWrapper, QSqlDatabase::contains returns true,
QSqlDatabase::database fails because the connection was created by an old
thread (different pointer) with the same handle (as stated in Qt's
documentation, currentThreadId should not be used).

POTENTIAL FIX
for the QSqlError
// plasma-activities-stats/src/common/database/Database.cpp
~Private()
{
        QString connectionName = database->connectionName();
        database = nullptr;
        QSqlDatabase::removeDatabase(connectionName);
}
~Private is under a shared_ptr, so it should only be called when the current
thread is destroyed too and the connection can no longer be used.

COMMENTS
This is not an issue for KRunner and Kicker because
Milou.ResultsView/ResultsModel are not destroyed and loadRunners is called
once.
In my opinion, loadPlugins should be called only the first time the search is
activated. I don't know how to keep the model alive when the effect is
deactivated, though.
Another idea (in addition to the fix for QSqlError) is to create a dbus to load
the plugins once. If the dbus exists, RunnerResultsModel/RunnerManager connects
to it instead of loading the plugins. This will reduce memory consumption (I
expect 10-40MB per loadPlugins) by sharing the runners between krunner, the
overview, milou's plasmoid, and maybe kicker (it uses a custom state).
Concider I am working on it.

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

Reply via email to