Commit 8c3c27da authored by Alexander Kandaurov's avatar Alexander Kandaurov Committed by Méven Car
Browse files

activities: Close the database connection to prevent file descriptor leak

Summary: The connection to the database doesn't get closed, which leads to a leakage of file descriptors to kactivities database files, eventually reaching the open file limit. Also, sometimes warnings about duplicate connections may appear in the console. This patch fixes this by closing and removing the connection.

Test Plan:
  # Right-click a file in Dolphin and hover the Activities menu. Do it several times.
  # Check the output of
```
ls -l /proc/`pidof dolphin`/fd
```
for open descriptors to ~/.local/share/kactivitymanagerd/resources/database{,-wal}.

Reviewers: ivan, meven

Reviewed By: meven

Subscribers: meven, kde-frameworks-devel, kfm-devel

Tags: #dolphin, #frameworks

Differential Revision: https://phabricator.kde.org/D28739
parent 3a759885
......@@ -81,80 +81,89 @@ void FileItemLinkingPluginActionLoader::run()
}
} else {
auto database = QSqlDatabase::addDatabase(
QStringLiteral("QSQLITE"),
auto connectionName =
QStringLiteral("kactivities_db_resources_")
+ QString::number((quintptr) this));
database.setDatabaseName(
QStandardPaths::writableLocation(
QStandardPaths::GenericDataLocation)
+ QStringLiteral("/kactivitymanagerd/resources/database"));
if (database.open()) {
static const auto queryString = QStringLiteral(
"SELECT usedActivity, COUNT(targettedResource) "
"FROM ResourceLink "
"WHERE targettedResource IN (%1) "
"AND initiatingAgent = \":global\" "
"AND usedActivity != \":global\" "
"GROUP BY usedActivity");
QStringList escapedFiles;
QSqlField field;
field.setType(QVariant::String);
for (const auto& item: items.urlList()) {
field.setValue(QFileInfo(item.toLocalFile()).canonicalFilePath());
escapedFiles << database.driver()->formatValue(field);
}
+ QString::number((quintptr) this);
{
auto database = QSqlDatabase::addDatabase(
QStringLiteral("QSQLITE"),
connectionName);
database.setDatabaseName(
QStandardPaths::writableLocation(
QStandardPaths::GenericDataLocation)
+ QStringLiteral("/kactivitymanagerd/resources/database"));
if (database.open()) {
static const auto queryString = QStringLiteral(
"SELECT usedActivity, COUNT(targettedResource) "
"FROM ResourceLink "
"WHERE targettedResource IN (%1) "
"AND initiatingAgent = \":global\" "
"AND usedActivity != \":global\" "
"GROUP BY usedActivity");
QStringList escapedFiles;
QSqlField field;
field.setType(QVariant::String);
for (const auto& item: items.urlList()) {
field.setValue(QFileInfo(item.toLocalFile()).canonicalFilePath());
escapedFiles << database.driver()->formatValue(field);
}
QSqlQuery query(queryString.arg(escapedFiles.join(",")),
database);
QSqlQuery query(queryString.arg(escapedFiles.join(",")),
database);
QStringList activitiesForLinking;
QStringList activitiesForUnlinking;
QStringList activitiesForLinking;
QStringList activitiesForUnlinking;
for (const auto& result: query) {
const auto linkedFileCount = result[1].toInt();
const auto activity = result[0].toString();
if (linkedFileCount < itemsSize) {
activitiesForLinking << activity;
}
for (const auto& result: query) {
const auto linkedFileCount = result[1].toInt();
const auto activity = result[0].toString();
if (linkedFileCount < itemsSize) {
activitiesForLinking << activity;
}
if (linkedFileCount > 0) {
activitiesForUnlinking << activity;
if (linkedFileCount > 0) {
activitiesForUnlinking << activity;
}
}
}
if (activitiesForLinking.contains(activities.currentActivity()) ||
!activitiesForUnlinking.contains(activities.currentActivity())) {
actions << createAction(QString(), true,
i18n("Link to the current activity"),
"list-add");
}
if (activitiesForUnlinking.contains(activities.currentActivity())) {
actions << createAction(QString(), false,
i18n("Unlink from the current activity"),
"list-remove");
}
if (activitiesForLinking.contains(activities.currentActivity()) ||
!activitiesForUnlinking.contains(activities.currentActivity())) {
actions << createAction(QString(), true,
i18n("Link to the current activity"),
"list-add");
}
if (activitiesForUnlinking.contains(activities.currentActivity())) {
actions << createAction(QString(), false,
i18n("Unlink from the current activity"),
"list-remove");
}
actions << createSeparator(i18n("Link to:"));
for (const auto& activity: activitiesList) {
if (activitiesForLinking.contains(activity) ||
!activitiesForUnlinking.contains(activity)) {
actions << createAction(activity, true);
actions << createSeparator(i18n("Link to:"));
for (const auto& activity: activitiesList) {
if (activitiesForLinking.contains(activity) ||
!activitiesForUnlinking.contains(activity)) {
actions << createAction(activity, true);
}
}
}
actions << createSeparator(i18n("Unlink from:"));
for (const auto& activity: activitiesList) {
if (activitiesForUnlinking.contains(activity)) {
actions << createAction(activity, false);
actions << createSeparator(i18n("Unlink from:"));
for (const auto& activity: activitiesList) {
if (activitiesForUnlinking.contains(activity)) {
actions << createAction(activity, false);
}
}
database.close();
}
}
QSqlDatabase::removeDatabase(connectionName);
}
emit result(actions);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment