[nautilus/gnome-2-32: 9/283] Refactor the load/save code for the list.
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus/gnome-2-32: 9/283] Refactor the load/save code for the list.
- Date: Thu, 12 Aug 2010 11:04:47 +0000 (UTC)
commit 0f46dba0a4f41e6a5f5a3e53334deb6eddce1ff5
Author: Cosimo Cecchi <cosimoc gnome org>
Date: Mon Apr 12 15:04:35 2010 +0200
Refactor the load/save code for the list.
Don't use sync i/o anymore. This should also fix bug #532911.
src/nautilus-bookmark-list.c | 255 ++++++++++++++++++++++++++----------------
src/nautilus-bookmark-list.h | 2 +-
2 files changed, 162 insertions(+), 95 deletions(-)
---
diff --git a/src/nautilus-bookmark-list.c b/src/nautilus-bookmark-list.c
index 0e57768..f7e1b7c 100644
--- a/src/nautilus-bookmark-list.c
+++ b/src/nautilus-bookmark-list.c
@@ -36,6 +36,8 @@
#include <gio/gio.h>
#define MAX_BOOKMARK_LENGTH 80
+#define LOAD_JOB 1
+#define SAVE_JOB 2
enum {
CONTENTS_CHANGED,
@@ -165,6 +167,8 @@ do_finalize (GObject *object)
NAUTILUS_BOOKMARK_LIST (object)->monitor = NULL;
}
+ g_queue_free (NAUTILUS_BOOKMARK_LIST (object)->pending_ops);
+
clear (NAUTILUS_BOOKMARK_LIST (object));
G_OBJECT_CLASS (nautilus_bookmark_list_parent_class)->finalize (object);
@@ -199,7 +203,6 @@ bookmark_monitor_changed_cb (GFileMonitor *monitor,
eflags == G_FILE_MONITOR_EVENT_CREATED) {
g_return_if_fail (NAUTILUS_IS_BOOKMARK_LIST (NAUTILUS_BOOKMARK_LIST (user_data)));
nautilus_bookmark_list_load_file (NAUTILUS_BOOKMARK_LIST (user_data));
- g_signal_emit (user_data, signals[CONTENTS_CHANGED], 0);
}
}
@@ -208,6 +211,8 @@ nautilus_bookmark_list_init (NautilusBookmarkList *bookmarks)
{
GFile *file;
+ bookmarks->pending_ops = g_queue_new ();
+
nautilus_bookmark_list_load_file (bookmarks);
file = nautilus_bookmark_list_get_file ();
@@ -249,7 +254,7 @@ nautilus_bookmark_list_append (NautilusBookmarkList *bookmarks,
nautilus_bookmark_copy (bookmark),
-1);
- nautilus_bookmark_list_contents_changed (bookmarks);
+ nautilus_bookmark_list_save_file (bookmarks);
}
/**
@@ -275,21 +280,6 @@ nautilus_bookmark_list_contains (NautilusBookmarkList *bookmarks,
}
/**
- * nautilus_bookmark_list_contents_changed:
- *
- * Save the bookmark list to disk, and emit the contents_changed signal.
- * @bookmarks: NautilusBookmarkList whose contents have been modified.
- **/
-void
-nautilus_bookmark_list_contents_changed (NautilusBookmarkList *bookmarks)
-{
- g_return_if_fail (NAUTILUS_IS_BOOKMARK_LIST (bookmarks));
-
- nautilus_bookmark_list_save_file (bookmarks);
- g_signal_emit (bookmarks, signals[CONTENTS_CHANGED], 0);
-}
-
-/**
* nautilus_bookmark_list_delete_item_at:
*
* Delete the bookmark at the specified position.
@@ -314,7 +304,7 @@ nautilus_bookmark_list_delete_item_at (NautilusBookmarkList *bookmarks,
g_list_free_1 (doomed);
- nautilus_bookmark_list_contents_changed (bookmarks);
+ nautilus_bookmark_list_save_file (bookmarks);
}
/**
@@ -349,7 +339,7 @@ nautilus_bookmark_list_move_item (NautilusBookmarkList *bookmarks,
destination);
}
- nautilus_bookmark_list_contents_changed (bookmarks);
+ nautilus_bookmark_list_save_file (bookmarks);
}
/**
@@ -386,7 +376,7 @@ nautilus_bookmark_list_delete_items_with_uri (NautilusBookmarkList *bookmarks,
}
if (list_changed) {
- nautilus_bookmark_list_contents_changed (bookmarks);
+ nautilus_bookmark_list_save_file (bookmarks);
}
}
@@ -426,7 +416,7 @@ nautilus_bookmark_list_insert_item (NautilusBookmarkList *bookmarks,
nautilus_bookmark_copy (new_bookmark),
index);
- nautilus_bookmark_list_contents_changed (bookmarks);
+ nautilus_bookmark_list_save_file (bookmarks);
}
/**
@@ -463,25 +453,18 @@ nautilus_bookmark_list_length (NautilusBookmarkList *bookmarks)
return g_list_length (bookmarks->list);
}
-/**
- * nautilus_bookmark_list_load_file:
- *
- * Reads bookmarks from file, clobbering contents in memory.
- * @bookmarks: the list of bookmarks to fill with file contents.
- **/
static void
-nautilus_bookmark_list_load_file (NautilusBookmarkList *bookmarks)
+load_file_finish (NautilusBookmarkList *bookmarks,
+ GObject *source,
+ GAsyncResult *res)
{
- GFile *file;
- char *contents;
GError *error = NULL;
+ gchar *contents = NULL;
- file = nautilus_bookmark_list_get_file ();
-
- /* Wipe out old list. */
- clear (bookmarks);
+ g_file_load_contents_finish (G_FILE (source),
+ res, &contents, NULL, NULL, &error);
- if (g_file_load_contents (file, NULL, &contents, NULL, NULL, &error)) {
+ if (error == NULL) {
char **lines;
int i;
@@ -508,45 +491,67 @@ nautilus_bookmark_list_load_file (NautilusBookmarkList *bookmarks)
}
g_free (contents);
g_strfreev (lines);
- }
- else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) {
+
+ g_signal_emit (bookmarks, signals[CONTENTS_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);
}
+}
+
+static void
+load_file_async (NautilusBookmarkList *self,
+ GAsyncReadyCallback callback)
+{
+ GFile *file;
+
+ file = nautilus_bookmark_list_get_file ();
+
+ /* Wipe out old list. */
+ clear (self);
+
+ /* keep the bookmark list alive */
+ g_object_ref (self);
+ g_file_load_contents_async (file, NULL, callback, self);
g_object_unref (file);
}
-/**
- * nautilus_bookmark_list_new:
- *
- * Create a new bookmark_list, with contents read from disk.
- *
- * Return value: A pointer to the new widget.
- **/
-NautilusBookmarkList *
-nautilus_bookmark_list_new (void)
+static void
+save_file_finish (NautilusBookmarkList *bookmarks,
+ GObject *source,
+ GAsyncResult *res)
{
- NautilusBookmarkList *list;
+ GError *error = NULL;
+ GFile *file;
- list = NAUTILUS_BOOKMARK_LIST (g_object_new (NAUTILUS_TYPE_BOOKMARK_LIST, NULL));
+ g_file_replace_contents_finish (G_FILE (source),
+ res, NULL, &error);
- return g_object_ref_sink (list);
+ if (error != NULL) {
+ g_warning ("Unable to replace contents of the bookmarks file: %s",
+ error->message);
+ 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);
}
-/**
- * nautilus_bookmark_list_save_file:
- *
- * Save bookmarks to disk.
- * @bookmarks: the list of bookmarks to save.
- **/
static void
-nautilus_bookmark_list_save_file (NautilusBookmarkList *bookmarks)
+save_file_async (NautilusBookmarkList *bookmarks,
+ GAsyncReadyCallback callback)
{
GFile *file;
- GOutputStream *out;
- GError *error = NULL;
GList *l;
+ GString *bookmark_string;
/* temporarily disable bookmark file monitoring when writing file */
if (bookmarks->monitor != NULL) {
@@ -555,16 +560,10 @@ nautilus_bookmark_list_save_file (NautilusBookmarkList *bookmarks)
}
file = nautilus_bookmark_list_get_file ();
+ bookmark_string = g_string_new (NULL);
- out = (GOutputStream *)g_file_replace (file, NULL, FALSE, 0, NULL, &error);
- if (out == NULL) {
- g_message ("Opening bookmark file failed: %s\n", error->message);
- goto error;
- }
-
- for (l = bookmarks->list; l; l = l->next) {
+ for (l = bookmarks->list; l; l = l->next) {
NautilusBookmark *bookmark;
- char *bookmark_string;
bookmark = NAUTILUS_BOOKMARK (l->data);
@@ -573,50 +572,118 @@ nautilus_bookmark_list_save_file (NautilusBookmarkList *bookmarks)
char *label, *uri;
label = nautilus_bookmark_get_name (bookmark);
uri = nautilus_bookmark_get_uri (bookmark);
- bookmark_string = g_strconcat (uri, " ", label, "\n", NULL);
+ g_string_append_printf (bookmark_string,
+ "%s %s\n", uri, label);
g_free (uri);
g_free (label);
} else {
char *uri;
uri = nautilus_bookmark_get_uri (bookmark);
- bookmark_string = g_strconcat (uri, "\n", NULL);
+ g_string_append_printf (bookmark_string, "%s\n", uri);
g_free (uri);
}
+ }
- if (!g_output_stream_write_all (out,
- bookmark_string,
- strlen (bookmark_string),
- NULL, NULL,
- &error)) {
- g_warning ("writing %s to bookmark file failed: %s\n",
- bookmark_string, error->message);
- g_free (bookmark_string);
- goto error;
- }
+ /* keep the bookmark list alive */
+ g_object_ref (bookmarks);
+ 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));
- g_free (bookmark_string);
+ if (op == LOAD_JOB) {
+ load_file_finish (self, source, res);
+ } else {
+ save_file_finish (self, source, res);
}
- if (!g_output_stream_close (out, NULL, &error)) {
- g_warning ("Closing bookmark file failed: %s\n", error->message);
+ if (!g_queue_is_empty (self->pending_ops)) {
+ process_next_op (self);
}
-error:
- if (error)
- g_error_free (error);
+ /* release the reference acquired during the _async method */
+ g_object_unref (self);
+}
+
+static void
+process_next_op (NautilusBookmarkList *bookmarks)
+{
+ gint op;
- if (out)
- g_object_unref (out);
+ op = GPOINTER_TO_INT (g_queue_peek_tail (bookmarks->pending_ops));
- /* 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);
+ if (op == LOAD_JOB) {
+ load_file_async (bookmarks, op_processed_cb);
+ } else {
+ save_file_async (bookmarks, op_processed_cb);
+ }
+}
- if (out)
- g_object_unref (out);
- g_object_unref (file);
+/**
+ * nautilus_bookmark_list_load_file:
+ *
+ * Reads bookmarks from file, clobbering contents in memory.
+ * @bookmarks: the list of bookmarks to fill with file contents.
+ **/
+static void
+nautilus_bookmark_list_load_file (NautilusBookmarkList *bookmarks)
+{
+ g_queue_push_head (bookmarks->pending_ops, GINT_TO_POINTER (LOAD_JOB));
+
+ if (g_queue_get_length (bookmarks->pending_ops) == 1) {
+ process_next_op (bookmarks);
+ }
+}
+
+/**
+ * nautilus_bookmark_list_save_file:
+ *
+ * Save bookmarks to disk.
+ * @bookmarks: the list of bookmarks to save.
+ **/
+static void
+nautilus_bookmark_list_save_file (NautilusBookmarkList *bookmarks)
+{
+ g_signal_emit (bookmarks, signals[CONTENTS_CHANGED], 0);
+
+ g_queue_push_head (bookmarks->pending_ops, GINT_TO_POINTER (SAVE_JOB));
+
+ if (g_queue_get_length (bookmarks->pending_ops) == 1) {
+ process_next_op (bookmarks);
+ }
+}
+
+/**
+ * nautilus_bookmark_list_new:
+ *
+ * Create a new bookmark_list, with contents read from disk.
+ *
+ * Return value: A pointer to the new widget.
+ **/
+NautilusBookmarkList *
+nautilus_bookmark_list_new (void)
+{
+ NautilusBookmarkList *list;
+
+ list = NAUTILUS_BOOKMARK_LIST (g_object_new (NAUTILUS_TYPE_BOOKMARK_LIST, NULL));
+
+ return g_object_ref_sink (list);
}
/**
diff --git a/src/nautilus-bookmark-list.h b/src/nautilus-bookmark-list.h
index 231b50e..dfb4e5e 100644
--- a/src/nautilus-bookmark-list.h
+++ b/src/nautilus-bookmark-list.h
@@ -51,6 +51,7 @@ struct NautilusBookmarkList {
GList *list;
GFileMonitor *monitor;
+ GQueue *pending_ops;
};
struct NautilusBookmarkListClass {
@@ -64,7 +65,6 @@ void nautilus_bookmark_list_append (NautilusBook
NautilusBookmark *bookmark);
gboolean nautilus_bookmark_list_contains (NautilusBookmarkList *bookmarks,
NautilusBookmark *bookmark);
-void nautilus_bookmark_list_contents_changed (NautilusBookmarkList *bookmarks);
void nautilus_bookmark_list_delete_item_at (NautilusBookmarkList *bookmarks,
guint index);
void nautilus_bookmark_list_delete_items_with_uri (NautilusBookmarkList *bookmarks,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]