[gnome-builder/wip/libide: 45/237] vcs: add some safeguards to DirectoryVcs
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder/wip/libide: 45/237] vcs: add some safeguards to DirectoryVcs
- Date: Tue, 17 Feb 2015 21:33:12 +0000 (UTC)
commit 08d1b0e42a7b78f5f98675f2dd744eb9f16e4041
Author: Christian Hergert <christian hergert me>
Date: Sat Feb 7 19:11:20 2015 -0800
vcs: add some safeguards to DirectoryVcs
Try to not load so many files with directory vcs. It's okay to "soft fail"
after say 2000 files have been loaded. We want to be careful with the
situation where we open files starting from the home directory (which
shouldn't happen after we have project loading, but does now).
Also, the directory loader needs to be rewritten to be synchronous and
run from a GTaskThreadFunc.
libide/directory/ide-directory-vcs.c | 77 +++----------------------------
libide/tasks/ide-load-directory-task.c | 27 +++++++++--
libide/tasks/ide-load-directory-task.h | 1 +
3 files changed, 32 insertions(+), 73 deletions(-)
---
diff --git a/libide/directory/ide-directory-vcs.c b/libide/directory/ide-directory-vcs.c
index 0df8992..9796d59 100644
--- a/libide/directory/ide-directory-vcs.c
+++ b/libide/directory/ide-directory-vcs.c
@@ -24,80 +24,23 @@
#include "ide-project-files.h"
#include "tasks/ide-load-directory-task.h"
-typedef struct
-{
- gpointer dummy;
-} IdeDirectoryVcsPrivate;
+/*
+ * TODO: This all needs to be written synchronously on a thread so that we
+ * cant hit the case of too many open files. Right now, child directories
+ * are done async, and that can fail.
+ */
-enum
-{
- PROP_0,
- LAST_PROP
-};
+#define LOAD_MAX_FILES 2000
static void async_initable_iface_init (GAsyncInitableIface *iface);
G_DEFINE_TYPE_EXTENDED (IdeDirectoryVcs, ide_directory_vcs, IDE_TYPE_VCS, 0,
- G_ADD_PRIVATE (IdeDirectoryVcs)
G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE,
async_initable_iface_init))
-#if 0
-static GParamSpec *gParamSpecs [LAST_PROP];
-#endif
-
-static void
-ide_directory_vcs_finalize (GObject *object)
-{
-#if 0
- IdeDirectoryVcs *self = (IdeDirectoryVcs *)object;
- IdeDirectoryVcsPrivate *priv = ide_directory_vcs_get_instance_private (self);
-#endif
-
- G_OBJECT_CLASS (ide_directory_vcs_parent_class)->finalize (object);
-}
-
-static void
-ide_directory_vcs_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
-#if 0
- IdeDirectoryVcs *vcs = IDE_DIRECTORY_VCS (object);
-#endif
-
- switch (prop_id) {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static void
-ide_directory_vcs_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
-#if 0
- IdeDirectoryVcs *vcs = IDE_DIRECTORY_VCS (object);
-#endif
-
- switch (prop_id) {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
static void
ide_directory_vcs_class_init (IdeDirectoryVcsClass *klass)
{
- GObjectClass *object_class;
-
- object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = ide_directory_vcs_finalize;
- object_class->get_property = ide_directory_vcs_get_property;
- object_class->set_property = ide_directory_vcs_set_property;
}
static void
@@ -134,12 +77,8 @@ ide_directory_vcs_init_async (GAsyncInitable *initable,
NULL);
ide_project_item_append (root, files);
- task = ide_load_directory_task_new (self,
- directory,
- files,
- io_priority,
- cancellable,
- callback,
+ task = ide_load_directory_task_new (self, directory, files, LOAD_MAX_FILES,
+ io_priority, cancellable, callback,
user_data);
g_object_unref (files);
diff --git a/libide/tasks/ide-load-directory-task.c b/libide/tasks/ide-load-directory-task.c
index 1cef4c8..33901df 100644
--- a/libide/tasks/ide-load-directory-task.c
+++ b/libide/tasks/ide-load-directory-task.c
@@ -22,7 +22,7 @@
#include "ide-project-item.h"
#include "ide-project-file.h"
-#define NUM_FILES_DEFAULT 1000
+#define NUM_FILES_DEFAULT 100
typedef struct
{
@@ -30,6 +30,8 @@ typedef struct
guint failed : 1;
GTask *task;
GHashTable *project_items;
+ gsize file_count;
+ gsize max_files;
} TaskState;
static void enumerate_children_cb (GObject *object,
@@ -49,6 +51,7 @@ task_state_unref (TaskState *state)
if (--state->ref_count == 0)
{
+ g_print ("Failed: %d\n", state->failed);
if (state->failed)
g_task_return_new_error (state->task,
G_IO_ERROR,
@@ -74,7 +77,8 @@ task_state_ref (TaskState *state)
static gboolean
should_ignore_file (const gchar *name)
{
- g_return_val_if_fail (name, FALSE);
+ if (!name || !*name || (*name == '.'))
+ return TRUE;
if (g_str_equal (name, ".git"))
return TRUE;
@@ -102,7 +106,7 @@ next_files_cb (GObject *object,
TaskState *state = user_data;
GError *error = NULL;
GFile *directory;
- GList *list;
+ GList *list = NULL;
GList *iter;
g_return_if_fail (G_IS_FILE_ENUMERATOR (enumerator));
@@ -116,6 +120,7 @@ next_files_cb (GObject *object,
if (error)
{
+ g_warning ("%s\n", error->message);
state->failed = TRUE;
goto cleanup;
}
@@ -136,11 +141,18 @@ next_files_cb (GObject *object,
(file_type != G_FILE_TYPE_REGULAR))
continue;
- name = g_file_info_get_display_name (file_info);
+ state->file_count++;
+ name = g_file_info_get_name (file_info);
+ g_print ("name: %s\n", name);
if (should_ignore_file (name))
continue;
+ name = g_file_info_get_display_name (file_info);
+
+ if (state->file_count >= state->max_files)
+ goto cleanup;
+
item = g_object_new (IDE_TYPE_PROJECT_FILE,
"context", context,
"file-info", file_info,
@@ -157,6 +169,7 @@ next_files_cb (GObject *object,
g_object_ref (item));
g_file_enumerate_children_async (file,
(G_FILE_ATTRIBUTE_STANDARD_TYPE","
+ G_FILE_ATTRIBUTE_STANDARD_NAME","
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME),
G_FILE_QUERY_INFO_NONE,
G_PRIORITY_DEFAULT,
@@ -192,6 +205,7 @@ enumerate_children_cb (GObject *object,
if (!enumerator)
{
+ g_warning ("%s\n", error->message);
state->failed = TRUE;
goto cleanup;
}
@@ -226,6 +240,7 @@ query_info_cb (GObject *object,
if (!file_info)
{
+ g_warning ("%s\n", error->message);
state->failed = TRUE;
goto cleanup;
}
@@ -234,6 +249,7 @@ query_info_cb (GObject *object,
if (file_type != G_FILE_TYPE_DIRECTORY)
{
+ g_warning (_("Not a directory"));
state->failed = TRUE;
goto cleanup;
}
@@ -256,6 +272,7 @@ GTask *
ide_load_directory_task_new (gpointer source_object,
GFile *directory,
IdeProjectItem *parent,
+ gsize max_files,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
@@ -270,6 +287,8 @@ ide_load_directory_task_new (gpointer source_object,
state = g_slice_new0 (TaskState);
state->ref_count = 1;
+ state->max_files = max_files;
+ state->file_count = 0;
state->task = g_task_new (source_object, cancellable, callback, user_data);
state->project_items = g_hash_table_new_full (g_direct_hash,
g_direct_equal,
diff --git a/libide/tasks/ide-load-directory-task.h b/libide/tasks/ide-load-directory-task.h
index c879b63..d15ecde 100644
--- a/libide/tasks/ide-load-directory-task.h
+++ b/libide/tasks/ide-load-directory-task.h
@@ -28,6 +28,7 @@ G_BEGIN_DECLS
GTask *ide_load_directory_task_new (gpointer source_object,
GFile *directory,
IdeProjectItem *parent,
+ gsize max_files,
int io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]