[tracker/wip/carlosg/parallel-stmts: 2/2] libtracker-data: Favor free interfaces over new ones harder
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/wip/carlosg/parallel-stmts: 2/2] libtracker-data: Favor free interfaces over new ones harder
- Date: Sun, 18 Oct 2020 20:58:32 +0000 (UTC)
commit 2d9743a93b9046b4ad17f4a51f408f1337dd5ba1
Author: Carlos Garnacho <carlosg gnome org>
Date: Sun Oct 18 19:59:18 2020 +0200
libtracker-data: Favor free interfaces over new ones harder
We typically do that, but once we've found that the first interface
in the pool is already busy with other statements, we assume they're
all busy and jump into creating a new interface. Even worse, if that
interface is kept busy indefinitely, every new query will opt for
creating a new interface, quickly filling the allotment.
There might be other interfaces in the pool that are already
free, so check all of them before trying to create a new interface.
This makes us more conservative at creating new interfaces on load
periods, only doing so if all interfaces are actually busy.
src/libtracker-data/tracker-db-manager.c | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
---
diff --git a/src/libtracker-data/tracker-db-manager.c b/src/libtracker-data/tracker-db-manager.c
index 4eec98e11..5e98337de 100644
--- a/src/libtracker-data/tracker-db-manager.c
+++ b/src/libtracker-data/tracker-db-manager.c
@@ -819,7 +819,8 @@ TrackerDBInterface *
tracker_db_manager_get_db_interface (TrackerDBManager *db_manager)
{
GError *internal_error = NULL;
- TrackerDBInterface *interface;
+ TrackerDBInterface *interface = NULL;
+ guint len, i;
/* The interfaces never actually leave the async queue,
* we use it as a thread synchronized LRU, which doesn't
@@ -830,19 +831,30 @@ tracker_db_manager_get_db_interface (TrackerDBManager *db_manager)
* in the interface lock).
*/
g_async_queue_lock (db_manager->interfaces);
- interface = g_async_queue_try_pop_unlocked (db_manager->interfaces);
+ len = g_async_queue_length_unlocked (db_manager->interfaces);
+
+ /* 1st. Find a free interface */
+ for (i = 0; i < len; i++) {
+ interface = g_async_queue_try_pop_unlocked (db_manager->interfaces);
+
+ if (!interface)
+ break;
+ if (!tracker_db_interface_get_is_used (interface))
+ break;
- if (interface && tracker_db_interface_get_is_used (interface) &&
- g_async_queue_length_unlocked (db_manager->interfaces) < MAX_INTERFACES) {
- /* Put it back and go at creating a new one */
- g_async_queue_push_front_unlocked (db_manager->interfaces, interface);
+ g_async_queue_push_unlocked (db_manager->interfaces, interface);
interface = NULL;
}
+ /* 2nd. If no more interfaces can be created, pick one */
+ if (!interface && len >= MAX_INTERFACES) {
+ interface = g_async_queue_try_pop_unlocked (db_manager->interfaces);
+ }
+
if (interface) {
g_signal_emit (db_manager, signals[UPDATE_INTERFACE], 0, interface);
} else {
- /* Create a new one to satisfy the request */
+ /* 3rd. Create a new interface to satisfy the request */
interface = tracker_db_manager_create_db_interface (db_manager,
TRUE, &internal_error);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]