summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2020-10-18 19:59:18 +0200
committerCarlos Garnacho <carlosg@gnome.org>2020-10-18 22:56:32 +0200
commit2d9743a93b9046b4ad17f4a51f408f1337dd5ba1 (patch)
tree8e34d865ab533a49b88258e07b422db0285d2737
parent1412da10cb6c923188f0ba323c2092dc28d0361b (diff)
downloadtracker-wip/carlosg/parallel-stmts.tar.gz
libtracker-data: Favor free interfaces over new ones harderwip/carlosg/parallel-stmts
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.
-rw-r--r--src/libtracker-data/tracker-db-manager.c26
1 files 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);