[nautilus] bookmark-list: make sure to avoid sync I/O while loading/saving
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus] bookmark-list: make sure to avoid sync I/O while loading/saving
- Date: Mon, 30 Apr 2012 14:17:39 +0000 (UTC)
commit e098781b3ede80517ceea56daa7f5a8c1c95f2af
Author: Cosimo Cecchi <cosimoc gnome org>
Date: Mon Apr 30 10:15:24 2012 -0400
bookmark-list: make sure to avoid sync I/O while loading/saving
Last patch introduces sync I/O in the load and save paths; avoid that by
explicitly using separate threads for saving and loading, thanks to
g_simple_async_result_run_in_thread().
src/nautilus-bookmark-list.c | 243 ++++++++++++++++++++++--------------------
1 files changed, 129 insertions(+), 114 deletions(-)
---
diff --git a/src/nautilus-bookmark-list.c b/src/nautilus-bookmark-list.c
index c66a417..07e5a0c 100644
--- a/src/nautilus-bookmark-list.c
+++ b/src/nautilus-bookmark-list.c
@@ -462,82 +462,142 @@ nautilus_bookmark_list_length (NautilusBookmarkList *bookmarks)
}
static void
-load_file_finish (NautilusBookmarkList *bookmarks,
- GObject *source,
- GAsyncResult *res)
+process_next_op (NautilusBookmarkList *bookmarks);
+
+static void
+op_processed_cb (NautilusBookmarkList *self)
{
- GError *error = NULL;
- gchar *contents = NULL;
-
- g_file_load_contents_finish (G_FILE (source),
- res, &contents, NULL, NULL, &error);
-
- if (error == NULL) {
- char **lines;
- int i;
-
- lines = g_strsplit (contents, "\n", -1);
- for (i = 0; lines[i]; i++) {
- /* Ignore empty or invalid lines that cannot be parsed properly */
- if (lines[i][0] != '\0' && lines[i][0] != ' ') {
- /* gtk 2.7/2.8 might have labels appended to bookmarks which are separated by a space */
- /* we must seperate the bookmark uri and the potential label */
- char *space, *label;
-
- label = NULL;
- space = strchr (lines[i], ' ');
- if (space) {
- *space = '\0';
- label = g_strdup (space + 1);
- }
- insert_bookmark_internal (bookmarks,
- new_bookmark_from_uri (lines[i], label),
- -1);
-
- g_free (label);
+ g_queue_pop_tail (self->pending_ops);
+
+ if (!g_queue_is_empty (self->pending_ops)) {
+ process_next_op (self);
+ }
+}
+
+static void
+load_callback (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ NautilusBookmarkList *self = NAUTILUS_BOOKMARK_LIST (source);
+ gchar *contents;
+ char **lines;
+ int i;
+
+ contents = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
+
+ if (contents == NULL) {
+ return;
+ }
+
+ lines = g_strsplit (contents, "\n", -1);
+ for (i = 0; lines[i]; i++) {
+ /* Ignore empty or invalid lines that cannot be parsed properly */
+ if (lines[i][0] != '\0' && lines[i][0] != ' ') {
+ /* gtk 2.7/2.8 might have labels appended to bookmarks which are separated by a space */
+ /* we must seperate the bookmark uri and the potential label */
+ char *space, *label;
+
+ label = NULL;
+ space = strchr (lines[i], ' ');
+ if (space) {
+ *space = '\0';
+ label = g_strdup (space + 1);
}
- }
- g_free (contents);
- g_strfreev (lines);
- g_signal_emit (bookmarks, signals[CHANGED], 0);
- } else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) {
- g_warning ("Could not load bookmark file: %s\n", error->message);
- g_error_free (error);
+ insert_bookmark_internal (self, new_bookmark_from_uri (lines[i], label), -1);
+ g_free (label);
+ }
}
+
+ g_signal_emit (self, signals[CHANGED], 0);
+ op_processed_cb (self);
+
+ g_strfreev (lines);
}
static void
-load_file_async (NautilusBookmarkList *self,
- GAsyncReadyCallback callback)
+load_io_thread (GSimpleAsyncResult *result,
+ GObject *object,
+ GCancellable *cancellable)
{
GFile *file;
+ gchar *contents;
+ GError *error = NULL;
file = nautilus_bookmark_list_get_file ();
if (!g_file_query_exists (file, NULL)) {
file = nautilus_bookmark_list_get_legacy_file ();
}
+ g_file_load_contents (file, NULL, &contents, NULL, NULL, &error);
+
+ if (error != NULL) {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) {
+ g_warning ("Could not load bookmark file: %s\n", error->message);
+ }
+ g_error_free (error);
+ } else {
+ g_simple_async_result_set_op_res_gpointer (result, contents, g_free);
+ }
+}
+
+static void
+load_file_async (NautilusBookmarkList *self)
+{
+ GSimpleAsyncResult *result;
+
/* Wipe out old list. */
clear (self);
- /* keep the bookmark list alive */
- g_object_ref (self);
- g_file_load_contents_async (file, NULL, callback, self);
+ result = g_simple_async_result_new (G_OBJECT (self),
+ load_callback, NULL, NULL);
+ g_simple_async_result_run_in_thread (result, load_io_thread,
+ G_PRIORITY_DEFAULT, NULL);
+ g_object_unref (result);
+}
+static void
+save_callback (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ NautilusBookmarkList *self = NAUTILUS_BOOKMARK_LIST (source);
+ GFile *file;
+
+ /* re-enable bookmark file monitoring */
+ file = nautilus_bookmark_list_get_file ();
+ self->monitor = g_file_monitor_file (file, 0, NULL, NULL);
g_object_unref (file);
+
+ g_file_monitor_set_rate_limit (self->monitor, 1000);
+ g_signal_connect (self->monitor, "changed",
+ G_CALLBACK (bookmark_monitor_changed_cb), self);
+
+ op_processed_cb (self);
}
static void
-save_file_finish (NautilusBookmarkList *bookmarks,
- GObject *source,
- GAsyncResult *res)
+save_io_thread (GSimpleAsyncResult *result,
+ GObject *object,
+ GCancellable *cancellable)
{
+ gchar *contents, *path;
+ GFile *parent, *file;
GError *error = NULL;
- GFile *file;
- g_file_replace_contents_finish (G_FILE (source),
- res, NULL, &error);
+ file = nautilus_bookmark_list_get_file ();
+ parent = g_file_get_parent (file);
+ path = g_file_get_path (parent);
+ g_mkdir_with_parents (path, 0700);
+ g_free (path);
+ g_object_unref (parent);
+
+ contents = g_simple_async_result_get_op_res_gpointer (result);
+ g_file_replace_contents (file,
+ contents, strlen (contents),
+ NULL, FALSE, 0, NULL,
+ NULL, &error);
if (error != NULL) {
g_warning ("Unable to replace contents of the bookmarks file: %s",
@@ -545,37 +605,26 @@ save_file_finish (NautilusBookmarkList *bookmarks,
g_error_free (error);
}
- file = nautilus_bookmark_list_get_file ();
-
- /* re-enable bookmark file monitoring */
- bookmarks->monitor = g_file_monitor_file (file, 0, NULL, NULL);
- g_file_monitor_set_rate_limit (bookmarks->monitor, 1000);
- g_signal_connect (bookmarks->monitor, "changed",
- G_CALLBACK (bookmark_monitor_changed_cb), bookmarks);
-
g_object_unref (file);
}
static void
-save_file_async (NautilusBookmarkList *bookmarks,
- GAsyncReadyCallback callback)
+save_file_async (NautilusBookmarkList *self)
{
- GFile *file;
- GList *l;
+ GSimpleAsyncResult *result;
GString *bookmark_string;
- GFile *parent;
- char *path;
+ gchar *contents;
+ GList *l;
+
+ bookmark_string = g_string_new (NULL);
/* temporarily disable bookmark file monitoring when writing file */
- if (bookmarks->monitor != NULL) {
- g_file_monitor_cancel (bookmarks->monitor);
- bookmarks->monitor = NULL;
+ if (self->monitor != NULL) {
+ g_file_monitor_cancel (self->monitor);
+ self->monitor = NULL;
}
- file = nautilus_bookmark_list_get_file ();
- bookmark_string = g_string_new (NULL);
-
- for (l = bookmarks->list; l; l = l->next) {
+ for (l = self->list; l; l = l->next) {
NautilusBookmark *bookmark;
bookmark = NAUTILUS_BOOKMARK (l->data);
@@ -597,48 +646,14 @@ save_file_async (NautilusBookmarkList *bookmarks,
}
}
- /* keep the bookmark list alive */
- g_object_ref (bookmarks);
-
- parent = g_file_get_parent (file);
- path = g_file_get_path (parent);
- g_mkdir_with_parents (path, 0700);
- g_free (path);
- g_object_unref (parent);
-
- g_file_replace_contents_async (file, bookmark_string->str,
- bookmark_string->len, NULL,
- FALSE, 0, NULL, callback,
- bookmarks);
-
- g_object_unref (file);
-}
-
-static void
-process_next_op (NautilusBookmarkList *bookmarks);
-
-static void
-op_processed_cb (GObject *source,
- GAsyncResult *res,
- gpointer user_data)
-{
- NautilusBookmarkList *self = user_data;
- int op;
-
- op = GPOINTER_TO_INT (g_queue_pop_tail (self->pending_ops));
-
- if (op == LOAD_JOB) {
- load_file_finish (self, source, res);
- } else {
- save_file_finish (self, source, res);
- }
-
- if (!g_queue_is_empty (self->pending_ops)) {
- process_next_op (self);
- }
+ result = g_simple_async_result_new (G_OBJECT (self),
+ save_callback, NULL, NULL);
+ contents = g_string_free (bookmark_string, FALSE);
+ g_simple_async_result_set_op_res_gpointer (result, contents, g_free);
- /* release the reference acquired during the _async method */
- g_object_unref (self);
+ g_simple_async_result_run_in_thread (result, save_io_thread,
+ G_PRIORITY_DEFAULT, NULL);
+ g_object_unref (result);
}
static void
@@ -649,9 +664,9 @@ process_next_op (NautilusBookmarkList *bookmarks)
op = GPOINTER_TO_INT (g_queue_peek_tail (bookmarks->pending_ops));
if (op == LOAD_JOB) {
- load_file_async (bookmarks, op_processed_cb);
+ load_file_async (bookmarks);
} else {
- save_file_async (bookmarks, op_processed_cb);
+ save_file_async (bookmarks);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]