[tracker/collation-gconf-locale] libtracker-data: Make sure there's no cursor alive when we do the collator reset
- From: Aleksander Morgado <aleksm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/collation-gconf-locale] libtracker-data: Make sure there's no cursor alive when we do the collator reset
- Date: Fri, 19 Nov 2010 11:02:18 +0000 (UTC)
commit 9bc2c9d78bcbb5a2bc15f67299af6ab623a8253b
Author: Aleksander Morgado <aleksander lanedo com>
Date: Fri Nov 19 11:59:12 2010 +0100
libtracker-data: Make sure there's no cursor alive when we do the collator reset
src/libtracker-data/tracker-db-interface-sqlite.c | 74 ++++++++++++---------
1 files changed, 43 insertions(+), 31 deletions(-)
---
diff --git a/src/libtracker-data/tracker-db-interface-sqlite.c b/src/libtracker-data/tracker-db-interface-sqlite.c
index 12af736..576699e 100644
--- a/src/libtracker-data/tracker-db-interface-sqlite.c
+++ b/src/libtracker-data/tracker-db-interface-sqlite.c
@@ -62,6 +62,9 @@ struct TrackerDBInterface {
gpointer locale_notification_id;
gint collator_reset_requested;
+ /* Number of active cursors */
+ gint n_active_cursors;
+
guint ro : 1;
#if HAVE_TRACKER_FTS
TrackerFts *fts;
@@ -1095,9 +1098,13 @@ create_result_set_from_stmt (TrackerDBInterface *interface,
/* Statement is going to start, check if we got a request to reset the
* collator, and if so, do it. */
- if (g_atomic_int_compare_and_exchange (&(interface->collator_reset_requested), TRUE, FALSE)) {
+ if (interface->n_active_cursors == 0 &&
+ g_atomic_int_compare_and_exchange (&(interface->collator_reset_requested), TRUE, FALSE)) {
tracker_db_interface_sqlite_reset_collator (interface);
}
+ /* Note that we do not need to update n_active_cursors here, as this whole iteration
+ * is going to be fully sync, so there is no possibility of getting a cursor created
+ * at the same time */
while (result == SQLITE_OK ||
result == SQLITE_ROW) {
@@ -1129,10 +1136,15 @@ create_result_set_from_stmt (TrackerDBInterface *interface,
}
}
+
if (result == SQLITE_DONE) {
/* Statement finished, check if we got a request to reset the
- * collator, and if so, do it. */
- if (g_atomic_int_compare_and_exchange (&(interface->collator_reset_requested), TRUE, FALSE)) {
+ * collator, and if so, do it.
+ * Note that we do not need to update n_active_cursors here, as this whole iteration
+ * is going to be fully sync, so there is no possibility of getting a cursor created
+ * at the same time */
+ if (interface->n_active_cursors == 0 &&
+ g_atomic_int_compare_and_exchange (&(interface->collator_reset_requested), TRUE, FALSE)) {
tracker_db_interface_sqlite_reset_collator (interface);
}
} else {
@@ -1303,10 +1315,21 @@ static void
tracker_db_cursor_finalize (GObject *object)
{
TrackerDBCursor *cursor;
+ TrackerDBInterface *iface;
int i;
cursor = TRACKER_DB_CURSOR (object);
+ /* As soon as we finalize the cursor, check if we need a collator reset
+ * and notify the iface about the removed cursor */
+ iface = cursor->ref_stmt->db_interface;
+ iface->n_active_cursors--;
+ g_assert_cmpint (iface->n_active_cursors, >=, 0); /* Just in case we fuck up the count */
+ if (iface->n_active_cursors == 0 &&
+ g_atomic_int_compare_and_exchange (&(iface->collator_reset_requested), TRUE, FALSE)) {
+ tracker_db_interface_sqlite_reset_collator (iface);
+ }
+
g_free (cursor->types);
for (i = 0; i < cursor->n_variable_names; i++) {
@@ -1314,13 +1337,9 @@ tracker_db_cursor_finalize (GObject *object)
}
g_free (cursor->variable_names);
- if (cursor->ref_stmt) {
- cursor->ref_stmt->stmt_is_sunk = FALSE;
- tracker_db_statement_sqlite_reset (cursor->ref_stmt);
- g_object_unref (cursor->ref_stmt);
- } else {
- sqlite3_finalize (cursor->stmt);
- }
+ cursor->ref_stmt->stmt_is_sunk = FALSE;
+ tracker_db_statement_sqlite_reset (cursor->ref_stmt);
+ g_object_unref (cursor->ref_stmt);
G_OBJECT_CLASS (tracker_db_cursor_parent_class)->finalize (object);
}
@@ -1420,18 +1439,24 @@ tracker_db_cursor_sqlite_new (sqlite3_stmt *sqlite_stmt,
gint n_variable_names)
{
TrackerDBCursor *cursor;
+ TrackerDBInterface *iface;
+
+ /* As soon as we create a cursor, check if we need a collator reset
+ * and notify the iface about the new cursor */
+ iface = ref_stmt->db_interface;
+ if (iface->n_active_cursors == 0 &&
+ g_atomic_int_compare_and_exchange (&(iface->collator_reset_requested), TRUE, FALSE)) {
+ tracker_db_interface_sqlite_reset_collator (iface);
+ }
+ iface->n_active_cursors++;
+ g_assert_cmpint (iface->n_active_cursors, >, 0); /* Just in case we fuck up the count */
cursor = g_object_new (TRACKER_TYPE_DB_CURSOR, NULL);
- cursor->stmt = sqlite_stmt;
cursor->finished = FALSE;
-
- if (ref_stmt) {
- ref_stmt->stmt_is_sunk = TRUE;
- cursor->ref_stmt = g_object_ref (ref_stmt);
- } else {
- cursor->ref_stmt = NULL;
- }
+ cursor->stmt = sqlite_stmt;
+ ref_stmt->stmt_is_sunk = TRUE;
+ cursor->ref_stmt = g_object_ref (ref_stmt);
if (types) {
gint i;
@@ -1533,12 +1558,6 @@ db_cursor_iter_next (TrackerDBCursor *cursor,
TrackerDBInterface *iface = stmt->db_interface;
if (!cursor->started) {
- /* Statement is going to start, check if we got a request to reset the
- * collator, and if so, do it. */
- if (g_atomic_int_compare_and_exchange (&(iface->collator_reset_requested), TRUE, FALSE)) {
- tracker_db_interface_sqlite_reset_collator (iface);
- }
-
cursor->started = TRUE;
}
@@ -1570,13 +1589,6 @@ db_cursor_iter_next (TrackerDBCursor *cursor,
cursor->finished = (result != SQLITE_ROW);
}
- /* Statement finished, check if we got a request to reset the
- * collator, and if so, do it. */
- if (cursor->finished &&
- g_atomic_int_compare_and_exchange (&(iface->collator_reset_requested), TRUE, FALSE)) {
- tracker_db_interface_sqlite_reset_collator (iface);
- }
-
return (!cursor->finished);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]