[gnome-builder] libide: add rw lock functions to IdeProject
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] libide: add rw lock functions to IdeProject
- Date: Mon, 23 Mar 2015 23:29:44 +0000 (UTC)
commit 054e57a8a9ded38c6879cb4ace1a2c8048a454df
Author: Christian Hergert <christian hergert me>
Date: Thu Feb 12 16:08:38 2015 -0800
libide: add rw lock functions to IdeProject
libide/clang/ide-clang-translation-unit.c | 16 ++++++
libide/git/ide-git-vcs.c | 10 +++-
libide/ide-project.c | 72 +++++++++++++++++++++++++----
libide/ide-project.h | 4 ++
src/tree/gb-project-tree-builder.c | 4 ++
tools/ide-list-diagnostics.c | 3 +
tools/ide-list-files.c | 2 +
7 files changed, 99 insertions(+), 12 deletions(-)
---
diff --git a/libide/clang/ide-clang-translation-unit.c b/libide/clang/ide-clang-translation-unit.c
index 765afda..c8676c8 100644
--- a/libide/clang/ide-clang-translation-unit.c
+++ b/libide/clang/ide-clang-translation-unit.c
@@ -131,6 +131,8 @@ ide_clang_translation_unit_get_diagnostics (IdeClangTranslationUnit *self)
if (!priv->diagnostics)
{
+ IdeContext *context;
+ IdeProject *project;
GPtrArray *ar;
guint count;
guint i;
@@ -138,6 +140,18 @@ ide_clang_translation_unit_get_diagnostics (IdeClangTranslationUnit *self)
ar = g_ptr_array_new_with_free_func ((GDestroyNotify)ide_diagnostic_unref);
count = clang_getNumDiagnostics (priv->tu);
+ /*
+ * Acquire the reader lock for the project since we will need to do
+ * a bunch of project tree lookups when creating diagnostics. By doing
+ * this outside of the loops, we avoid creating lots of contention on
+ * the reader lock, but potentially hold on to the entire lock for a bit
+ * longer at a time.
+ */
+ context = ide_object_get_context (IDE_OBJECT (self));
+ project = ide_context_get_project (context);
+
+ ide_project_reader_lock (project);
+
for (i = 0; i < count; i++)
{
CXDiagnostic cxdiag;
@@ -150,6 +164,8 @@ ide_clang_translation_unit_get_diagnostics (IdeClangTranslationUnit *self)
clang_disposeDiagnostic (cxdiag);
}
+ ide_project_reader_unlock (project);
+
priv->diagnostics = _ide_diagnostics_new (ar);
}
diff --git a/libide/git/ide-git-vcs.c b/libide/git/ide-git-vcs.c
index 9d7477e..b9515ca 100644
--- a/libide/git/ide-git-vcs.c
+++ b/libide/git/ide-git-vcs.c
@@ -213,12 +213,14 @@ ide_git_vcs_reload_index (IdeGitVcs *self,
context = ide_object_get_context (IDE_OBJECT (self));
project = ide_context_get_project (context);
+
+ ide_project_reader_lock (project);
root = ide_project_get_root (project);
files = g_object_new (IDE_TYPE_PROJECT_FILES,
"context", context,
"parent", root,
NULL);
- ide_project_item_append (root, files);
+ ide_project_reader_unlock (project);
g_hash_table_insert (cache, g_strdup ("."), g_object_ref (files));
@@ -229,12 +231,14 @@ ide_git_vcs_reload_index (IdeGitVcs *self,
entry = ggit_index_entries_get_by_index (entries, i);
path = ggit_index_entry_get_path (entry);
-
ide_git_vcs_reload_index_add_path (self, cache, path, FALSE);
-
ggit_index_entry_unref (entry);
}
+ ide_project_writer_lock (project);
+ ide_project_item_append (root, files);
+ ide_project_writer_unlock (project);
+
ret = TRUE;
cleanup:
diff --git a/libide/ide-project.c b/libide/ide-project.c
index 88e53da..3c8237b 100644
--- a/libide/ide-project.c
+++ b/libide/ide-project.c
@@ -24,8 +24,9 @@
typedef struct
{
+ GRWLock rw_lock;
IdeProjectItem *root;
- gchar *name;
+ gchar *name;
} IdeProjectPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (IdeProject, ide_project, IDE_TYPE_OBJECT)
@@ -39,6 +40,46 @@ enum {
static GParamSpec *gParamSpecs [LAST_PROP];
+void
+ide_project_reader_lock (IdeProject *self)
+{
+ IdeProjectPrivate *priv = ide_project_get_instance_private (self);
+
+ g_return_if_fail (IDE_IS_PROJECT (self));
+
+ g_rw_lock_reader_lock (&priv->rw_lock);
+}
+
+void
+ide_project_reader_unlock (IdeProject *self)
+{
+ IdeProjectPrivate *priv = ide_project_get_instance_private (self);
+
+ g_return_if_fail (IDE_IS_PROJECT (self));
+
+ g_rw_lock_reader_unlock (&priv->rw_lock);
+}
+
+void
+ide_project_writer_lock (IdeProject *self)
+{
+ IdeProjectPrivate *priv = ide_project_get_instance_private (self);
+
+ g_return_if_fail (IDE_IS_PROJECT (self));
+
+ g_rw_lock_writer_lock (&priv->rw_lock);
+}
+
+void
+ide_project_writer_unlock (IdeProject *self)
+{
+ IdeProjectPrivate *priv = ide_project_get_instance_private (self);
+
+ g_return_if_fail (IDE_IS_PROJECT (self));
+
+ g_rw_lock_writer_unlock (&priv->rw_lock);
+}
+
const gchar *
ide_project_get_name (IdeProject *project)
{
@@ -50,8 +91,8 @@ ide_project_get_name (IdeProject *project)
}
void
-ide_project_set_name (IdeProject *project,
- const gchar *name)
+_ide_project_set_name (IdeProject *project,
+ const gchar *name)
{
IdeProjectPrivate *priv = ide_project_get_instance_private (project);
@@ -70,7 +111,16 @@ ide_project_set_name (IdeProject *project,
*
* Retrieves the root item of the project tree.
*
- * Returns: (transfer none): An #IdeProjectItem
+ * You must be holding the reader lock while calling and using the result of
+ * this function. Other thread may be accessing or modifying the tree without
+ * your knowledge. See ide_project_reader_lock() and ide_project_reader_unlock()
+ * for more information.
+ *
+ * If you need to modify the tree, you must hold a writer lock that has been
+ * acquired with ide_project_writer_lock() and released with
+ * ide_project_writer_unlock() when you are no longer modifiying the tree.
+ *
+ * Returns: (transfer none): An #IdeProjectItem.
*/
IdeProjectItem *
ide_project_get_root (IdeProject *project)
@@ -113,6 +163,10 @@ ide_project_set_root (IdeProject *project,
* Retrieves an #IdeFile for the path specified. #IdeFile provides access to
* language specific features via ide_file_get_language().
*
+ * You must hold the reader lock while calling this function. See
+ * ide_project_reader_lock() and ide_project_reader_unlock() for more
+ * information.
+ *
* Returns: (transfer full) (nullable): An #IdeFile or %NULL if no matching
* file could be found.
*/
@@ -161,6 +215,7 @@ ide_project_finalize (GObject *object)
g_clear_object (&priv->root);
g_clear_pointer (&priv->name, g_free);
+ g_rw_lock_clear (&priv->rw_lock);
G_OBJECT_CLASS (ide_project_parent_class)->finalize (object);
}
@@ -198,10 +253,6 @@ ide_project_set_property (GObject *object,
switch (prop_id)
{
- case PROP_NAME:
- ide_project_set_name (self, g_value_get_string (value));
- break;
-
case PROP_ROOT:
ide_project_set_root (self, g_value_get_object (value));
break;
@@ -225,7 +276,7 @@ ide_project_class_init (IdeProjectClass *klass)
_("Name"),
_("The name of the project."),
NULL,
- (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_NAME,
gParamSpecs [PROP_NAME]);
@@ -244,4 +295,7 @@ ide_project_class_init (IdeProjectClass *klass)
static void
ide_project_init (IdeProject *self)
{
+ IdeProjectPrivate *priv = ide_project_get_instance_private (self);
+
+ g_rw_lock_init (&priv->rw_lock);
}
diff --git a/libide/ide-project.h b/libide/ide-project.h
index 1a9c255..f4f8211 100644
--- a/libide/ide-project.h
+++ b/libide/ide-project.h
@@ -36,6 +36,10 @@ IdeProjectItem *ide_project_get_root (IdeProject *project);
const gchar *ide_project_get_name (IdeProject *project);
IdeFile *ide_project_get_file_for_path (IdeProject *project,
const gchar *path);
+void ide_project_reader_lock (IdeProject *project);
+void ide_project_reader_unlock (IdeProject *project);
+void ide_project_writer_lock (IdeProject *project);
+void ide_project_writer_unlock (IdeProject *project);
G_END_DECLS
diff --git a/src/tree/gb-project-tree-builder.c b/src/tree/gb-project-tree-builder.c
index a16803c..e132144 100644
--- a/src/tree/gb-project-tree-builder.c
+++ b/src/tree/gb-project-tree-builder.c
@@ -140,6 +140,8 @@ build_project (GbProjectTreeBuilder *self,
project = IDE_PROJECT (gb_tree_node_get_item (node));
+ ide_project_reader_lock (project);
+
root = ide_project_get_root (project);
children = ide_project_item_get_children (root);
@@ -169,6 +171,8 @@ build_project (GbProjectTreeBuilder *self,
}
}
}
+
+ ide_project_reader_unlock (project);
}
static void
diff --git a/tools/ide-list-diagnostics.c b/tools/ide-list-diagnostics.c
index 10e724b..706d6d6 100644
--- a/tools/ide-list-diagnostics.c
+++ b/tools/ide-list-diagnostics.c
@@ -95,7 +95,10 @@ context_cb (GObject *object,
}
project = ide_context_get_project (context);
+
+ ide_project_reader_lock (project);
file = ide_project_get_file_for_path (project, gPath);
+ ide_project_reader_unlock (project);
if (!file)
{
diff --git a/tools/ide-list-files.c b/tools/ide-list-files.c
index 5eb2f83..52ed55d 100644
--- a/tools/ide-list-files.c
+++ b/tools/ide-list-files.c
@@ -105,7 +105,9 @@ context_cb (GObject *object,
project = ide_context_get_project (context);
root = ide_project_get_root (project);
+ ide_project_reader_lock (project);
walk_tree (root, 0);
+ ide_project_reader_unlock (project);
quit (EXIT_SUCCESS);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]