summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/analysis/project.c901
-rw-r--r--src/core/queue.c10
-rw-r--r--src/core/queue.h3
3 files changed, 536 insertions, 378 deletions
diff --git a/src/analysis/project.c b/src/analysis/project.c
index d2228e2..13887ee 100644
--- a/src/analysis/project.c
+++ b/src/analysis/project.c
@@ -37,25 +37,14 @@
#include "../core/global.h"
#include "../core/logs.h"
#include "../core/params.h"
+#include "../core/queue.h"
+#include "../glibext/delayed-int.h"
/* ------------------------- DEFINITION D'UN PROJET INTERNE ------------------------- */
-/* Suivi du chargement de contenus binaires */
-typedef struct _loading_params
-{
- const wgroup_id_t **exp_wids; /* Identifiants d'exploration */
- size_t exp_count; /* Quantitié d'identifiants */
-
- size_t resolved; /* Compteur de résolutions */
-
- xmlDoc *xdoc; /* Structure XML chargée ? */
- xmlXPathContext *context; /* Eventuel contexte XML */
-
-} loading_params;
-
/* Projet d'étude regroupant les binaires analysés (instance) */
struct _GStudyProject
{
@@ -63,10 +52,6 @@ struct _GStudyProject
char *filename; /* Lieu d'enregistrement */
- loading_params *ld_params; /* Infos d'accompagnement */
- size_t ld_count; /* Quantité de ces infos */
- GMutex ld_mutex; /* Encadrement des accès */
-
GLoadedContent **contents; /* Contenus chargés et intégrés*/
size_t count; /* Quantité de ces contenus */
GMutex mutex; /* Encadrement des accès */
@@ -104,26 +89,83 @@ static void g_study_project_finalize(GStudyProject *);
/* ------------------------ INTEGRATION DE CONTENUS BINAIRES ------------------------ */
-/* Prépare le suivi d'une nouvelle phase d'intégration. */
-static loading_params *g_study_project_prepare_content_loading(GStudyProject *);
+/* Assure l'intégration de contenus listés dans du XML. */
+static void g_study_project_recover_binary_contents(GStudyProject *, xmlDoc *, xmlXPathContext *);
+
+/* Réceptionne la recette d'une analyse de contenu. */
+static void on_loaded_content_analyzed(GLoadedContent *, gboolean, GStudyProject *);
+
-/* Efface le suivi d'une phase d'intégration obsolète. */
-static void g_study_project_destroy_content_loading(GStudyProject *, loading_params *);
-/* Retrouve les infos de chargements liées à une exploration. */
-static loading_params *g_study_project_find_exploration(GStudyProject *, wgroup_id_t, const wgroup_id_t **);
+/* ------------------------ CHARGEMENTS DE CONTENUS BINAIRES ------------------------ */
-/* Assure l'intégration de contenus listés dans du XML. */
-static void g_study_project_recover_binary_contents(GStudyProject *, xmlDoc *, xmlXPathContext *);
+
+#define G_TYPE_LOADING_HANDLER g_loading_handler_get_type()
+#define G_LOADING_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_LOADING_HANDLER, GLoadingHandler))
+#define G_IS_LOADING_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_LOADING_HANDLER))
+#define G_LOADING_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_LOADING_HANDLER, GLoadingHandlerClass))
+#define G_IS_LOADING_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_LOADING_HANDLER))
+#define G_LOADING_HANDLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_LOADING_HANDLER, GLoadingHandlerClass))
+
+
+/* Chargement de contenus binaires (instance) */
+typedef struct _GLoadingHandler
+{
+ GDelayedWork parent; /* A laisser en premier */
+
+ GStudyProject *project; /* Projet à compléter */
+
+ xmlDoc *xdoc; /* Structure XML chargée ? */
+ xmlXPathContext *context; /* Eventuel contexte XML */
+
+ const wgroup_id_t **exp_wids; /* Identifiants d'exploration */
+ size_t exp_count; /* Quantitié d'identifiants */
+ size_t resolved; /* Compteur de résolutions */
+ GCond wait_cond; /* Réveil d'attente de fin */
+ GMutex mutex; /* Encadrement des accès */
+
+} GLoadingHandler;
+
+/* Chargement de contenus binaires (classe) */
+typedef struct _GLoadingHandlerClass
+{
+ GDelayedWorkClass parent; /* A laisser en premier */
+
+} GLoadingHandlerClass;
+
+
+/* Indique le type défini pour les tâches de chargement de contenus binaires. */
+GType g_loading_handler_get_type(void);
+
+/* Initialise la classe des tâches de chargement de contenus. */
+static void g_loading_handler_class_init(GLoadingHandlerClass *);
+
+/* Initialise une tâche de chargement de contenus binaires. */
+static void g_loading_handler_init(GLoadingHandler *);
+
+/* Supprime toutes les références externes. */
+static void g_loading_handler_dispose(GLoadingHandler *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_loading_handler_finalize(GLoadingHandler *);
+
+/* Crée une tâche de chargement de contenu bianire. */
+static GLoadingHandler *g_loading_handler_new_discovering(GStudyProject *, GBinContent *);
+
+/* Crée une tâche de chargement de contenu bianire. */
+static GLoadingHandler *g_loading_handler_new_recovering(GStudyProject *, xmlDoc *, xmlXPathContext *);
+
+/* Assure le chargement de contenus binaires en différé. */
+static void g_loading_handler_process(GLoadingHandler *, GtkStatusStack *);
+
+/* Détermine si un encadrement est adapté pour un identifiant. */
+static bool g_loading_handler_check(GLoadingHandler *, wgroup_id_t, const wgroup_id_t **);
/* Note la fin d'une phase d'exploration de contenu. */
-static void on_new_content_explored(GContentExplorer *, wgroup_id_t, GStudyProject *);
+static void on_new_content_explored(GContentExplorer *, wgroup_id_t, GLoadingHandler *);
/* Note la fin d'une phase de resolution de contenu. */
-static void on_new_content_resolved(GContentResolver *, wgroup_id_t, GStudyProject *);
-
-/* Réceptionne la recette d'une analyse de contenu. */
-static void on_loaded_content_analyzed(GLoadedContent *, gboolean, GStudyProject *);
+static void on_new_content_resolved(GContentResolver *, wgroup_id_t, GLoadingHandler *);
@@ -190,27 +232,12 @@ static void g_study_project_class_init(GStudyProjectClass *klass)
static void g_study_project_init(GStudyProject *project)
{
- GContentExplorer *explorer; /* Explorateur de contenus */
- GContentResolver *resolver; /* Resolveur de contenus */
-
project->filename = NULL;
- project->ld_params = NULL;
- project->ld_count = 0;
- g_mutex_init(&project->ld_mutex);
-
project->contents = NULL;
project->count = 0;
g_mutex_init(&project->mutex);
- explorer = get_current_content_explorer();
- g_signal_connect(explorer, "explored", G_CALLBACK(on_new_content_explored), project);
- g_object_unref(G_OBJECT(explorer));
-
- resolver = get_current_content_resolver();
- g_signal_connect(resolver, "resolved", G_CALLBACK(on_new_content_resolved), project);
- g_object_unref(G_OBJECT(resolver));
-
}
@@ -228,30 +255,8 @@ static void g_study_project_init(GStudyProject *project)
static void g_study_project_dispose(GStudyProject *project)
{
- GContentExplorer *explorer; /* Explorateur de contenus */
- GContentResolver *resolver; /* Resolveur de contenus */
size_t i; /* Boucle de parcours */
- explorer = get_current_content_explorer();
- g_signal_handlers_disconnect_by_func(explorer, G_CALLBACK(on_new_content_explored), project);
- g_object_unref(G_OBJECT(explorer));
-
- resolver = get_current_content_resolver();
- g_signal_handlers_disconnect_by_func(resolver, G_CALLBACK(on_new_content_resolved), project);
- g_object_unref(G_OBJECT(resolver));
-
- g_mutex_lock(&project->ld_mutex);
-
- while (project->ld_count > 0)
- g_study_project_destroy_content_loading(project, project->ld_params);
-
- if (project->ld_params != NULL)
- free(project->ld_params);
-
- g_mutex_unlock(&project->ld_mutex);
-
- g_mutex_clear(&project->ld_mutex);
-
g_mutex_lock(&project->mutex);
for (i = 0; i < project->count; i++)
@@ -513,36 +518,297 @@ const char *g_study_project_get_filename(const GStudyProject *project)
/******************************************************************************
* *
* Paramètres : project = projet dont le contenu est à compléter. *
+* xdoc = structure XML en cours d'édition. *
+* context = contexte à utiliser pour les recherches. *
* *
-* Description : Prépare le suivi d'une nouvelle phase d'intégration. *
+* Description : Assure l'intégration de contenus listés dans du XML. *
* *
-* Retour : Nouvelle structure de suivi prête à être complétée. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static loading_params *g_study_project_prepare_content_loading(GStudyProject *project)
+static void g_study_project_recover_binary_contents(GStudyProject *project, xmlDoc *xdoc, xmlXPathContext *context)
{
- loading_params *result; /* Trouvaille à retourner */
+ GLoadingHandler *handler; /* Encadrement du chargement */
- assert(!g_mutex_trylock(&project->ld_mutex));
+ handler = g_loading_handler_new_recovering(project, xdoc, context);
- project->ld_params = (loading_params *)realloc(project->ld_params,
- ++project->ld_count * sizeof(loading_params));
+ if (handler != NULL)
+ g_work_queue_schedule_work(get_work_queue(), G_DELAYED_WORK(handler), LOADING_WORK_GROUP);
- result = &project->ld_params[project->ld_count - 1];
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : project = projet dont le contenu est à compléter. *
+* content = contenu binaire à mémoriser pour le projet. *
+* *
+* Description : Assure l'intégration de contenus binaires dans un projet. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_study_project_discover_binary_content(GStudyProject *project, GBinContent *content)
+{
+ GLoadingHandler *handler; /* Encadrement du chargement */
+
+ handler = g_loading_handler_new_discovering(project, content);
+
+ g_work_queue_schedule_work(get_work_queue(), G_DELAYED_WORK(handler), LOADING_WORK_GROUP);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu chargé et analysé. *
+* success = bilan d'une analyse menée. *
+* project = projet avide des résultats des opérations. *
+* *
+* Description : Réceptionne la recette d'une analyse de contenu. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void on_loaded_content_analyzed(GLoadedContent *content, gboolean success, GStudyProject *project)
+{
+ const char *desc; /* Description du contenu */
+
+ desc = g_loaded_content_describe(content, true);
+
+ if (success)
+ {
+ g_study_project_attach_content(project, content);
+ log_variadic_message(LMT_INFO, _("Content from '%s' has been analyzed successfully!"), desc);
+ }
+
+ else
+ log_variadic_message(LMT_ERROR, _("Failed to load '%s'"), desc);
+
+ g_object_ref(G_OBJECT(content));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : project = project à manipuler. *
+* content = contenu chargé à associer au projet actuel. *
+* *
+* Description : Attache un contenu donné à un projet donné. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_study_project_attach_content(GStudyProject *project, GLoadedContent *content)
+{
+ g_mutex_lock(&project->mutex);
+
+ project->contents = (GLoadedContent **)realloc(project->contents,
+ ++project->count * sizeof(GLoadedContent *));
+
+ project->contents[project->count - 1] = content;
+ g_object_ref(G_OBJECT(content));
+
+ g_mutex_unlock(&project->mutex);
+
+ g_signal_emit_by_name(project, "content-added", content);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : project = project à manipuler. *
+* content = contenu chargé à dissocier du projet actuel. *
+* *
+* Description : Détache un contenu donné d'un projet donné. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_study_project_detach_content(GStudyProject *project, GLoadedContent *content)
+{
+ size_t i; /* Boucle de parcours */
+
+ g_mutex_lock(&project->mutex);
+
+ for (i = 0; i < project->count; i++)
+ if (project->contents[i] == content) break;
+
+ if ((i + 1) < project->count)
+ memmove(&project->contents[i], &project->contents[i + 1],
+ (project->count - i - 1) * sizeof(GLoadedContent *));
+
+ project->contents = (GLoadedContent **)realloc(project->contents,
+ --project->count * sizeof(GLoadedContent *));
+
+ g_mutex_unlock(&project->mutex);
+
+ g_signal_emit_by_name(project, "content-removed", content);
+
+ g_object_unref(G_OBJECT(content));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : project = projet dont le contenu est à afficher. *
+* *
+* Description : Met en place un projet à l'écran. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_study_project_display(const GStudyProject *project)
+{
+#if 0
+ size_t i; /* Boucle de parcours #1 */
+ loaded_binary *handled; /* Binaire prise en compte */
+ size_t j; /* Boucle de parcours #2 */
+
+ for (i = 0; i < project->binaries_count; i++)
+ {
+ handled = project->binaries[i];
+
+ for (j = 0; j < handled->count; j++)
+ g_panel_item_dock(handled->items[j]);
+
+ }
+#endif
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : project = projet dont le contenu est à cacher. *
+* *
+* Description : Supprime de l'écran un projet en place. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_study_project_hide(const GStudyProject *project)
+{
+#if 0
+ size_t i; /* Boucle de parcours #1 */
+ loaded_binary *handled; /* Binaire prise en compte */
+ size_t j; /* Boucle de parcours #2 */
+
+ for (i = 0; i < project->binaries_count; i++)
+ {
+ handled = project->binaries[i];
+
+ for (j = 0; j < handled->count; j++)
+ g_panel_item_undock(handled->items[j]);
+
+ }
+#endif
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : project = projet dont le contenu est à afficher. *
+* count = nombre de contenus pris en compte. [OUT] *
+* *
+* Description : Fournit l'ensemble des contenus associés à un projet. *
+* *
+* Retour : Liste à libérer de la mémoire. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GLoadedContent **g_study_project_get_contents(GStudyProject *project, size_t *count)
+{
+ GLoadedContent **result; /* Tableau à retourner */
+ size_t i; /* Boucle de parcours */
+
+ g_mutex_lock(&project->mutex);
+
+ *count = project->count;
+ result = (GLoadedContent **)calloc(*count, sizeof(GLoadedContent *));
+
+ for (i = 0; i < *count; i++)
+ {
+ result[i] = project->contents[i];
+ g_object_ref(G_OBJECT(result[i]));
+ }
+
+ g_mutex_unlock(&project->mutex);
return result;
}
+
+
+/* ---------------------------------------------------------------------------------- */
+/* CHARGEMENTS DE CONTENUS BINAIRES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini pour les tâches de chargement de contenus binaires. */
+G_DEFINE_TYPE(GLoadingHandler, g_loading_handler, G_TYPE_DELAYED_WORK);
+
+
/******************************************************************************
* *
-* Paramètres : project = projet dont le contenu est à compléter. *
-* params = paramètres de chargemeent à supprimer. *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des tâches de chargement de contenus. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_loading_handler_class_init(GLoadingHandlerClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GDelayedWorkClass *work; /* Version en classe parente */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_loading_handler_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_loading_handler_finalize;
+
+ work = G_DELAYED_WORK_CLASS(klass);
+
+ work->run = (run_task_fc)g_loading_handler_process;
+
+}
+
+
+/******************************************************************************
* *
-* Description : Efface le suivi d'une phase d'intégration obsolète. *
+* Paramètres : handler = instance à initialiser. *
+* *
+* Description : Initialise une tâche de chargement de contenus binaires. *
* *
* Retour : - *
* *
@@ -550,92 +816,142 @@ static loading_params *g_study_project_prepare_content_loading(GStudyProject *pr
* *
******************************************************************************/
-static void g_study_project_destroy_content_loading(GStudyProject *project, loading_params *params)
+static void g_loading_handler_init(GLoadingHandler *handler)
{
GContentExplorer *explorer; /* Explorateur de contenus */
GContentResolver *resolver; /* Resolveur de contenus */
- size_t i; /* Boucle de parcours */
- size_t index; /* Indice des paramètres */
- assert(!g_mutex_trylock(&project->ld_mutex));
+ g_cond_init(&handler->wait_cond);
+ g_mutex_init(&handler->mutex);
+
+ explorer = get_current_content_explorer();
+ g_signal_connect(explorer, "explored", G_CALLBACK(on_new_content_explored), handler);
+ g_object_unref(G_OBJECT(explorer));
+
+ resolver = get_current_content_resolver();
+ g_signal_connect(resolver, "resolved", G_CALLBACK(on_new_content_resolved), handler);
+ g_object_unref(G_OBJECT(resolver));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : handler = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_loading_handler_dispose(GLoadingHandler *handler)
+{
+ GContentExplorer *explorer; /* Explorateur de contenus */
+ GContentResolver *resolver; /* Resolveur de contenus */
+ size_t i; /* Boucle de parcours */
/* Supression des groupes de travail */
explorer = get_current_content_explorer();
resolver = get_current_content_resolver();
- for (i = 0; i < params->exp_count; i++)
+ g_signal_handlers_disconnect_by_func(explorer, G_CALLBACK(on_new_content_explored), handler);
+ g_signal_handlers_disconnect_by_func(resolver, G_CALLBACK(on_new_content_resolved), handler);
+
+ g_mutex_lock(&handler->mutex);
+
+ for (i = 0; i < handler->exp_count; i++)
{
- g_content_resolver_delete_group(resolver, *params->exp_wids[i]);
- g_content_explorer_delete_group(explorer, *params->exp_wids[i]);
+ g_content_resolver_delete_group(resolver, *handler->exp_wids[i]);
+ g_content_explorer_delete_group(explorer, *handler->exp_wids[i]);
}
- free(params->exp_wids);
+ g_mutex_unlock(&handler->mutex);
g_object_unref(G_OBJECT(explorer));
g_object_unref(G_OBJECT(resolver));
- /* Fermture de l'éventuel fichier XML de chargement */
+ /* Nettoyage plus général */
- if (params->xdoc != NULL)
- close_xml_file(params->xdoc, params->context);
+ g_mutex_clear(&handler->mutex);
+ g_cond_clear(&handler->wait_cond);
- /* Réorganisation de la liste */
+ g_object_unref(G_OBJECT(handler->project));
- index = params - project->ld_params;
+ G_OBJECT_CLASS(g_loading_handler_parent_class)->dispose(G_OBJECT(handler));
- if ((index + 1) < project->ld_count)
- memmove(&project->ld_params[index], &project->ld_params[index + 1],
- (project->ld_count - index - 1) * sizeof(loading_params));
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : handler = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_loading_handler_finalize(GLoadingHandler *handler)
+{
+ free(handler->exp_wids);
- project->ld_params = (loading_params *)realloc(project->ld_params,
- --project->ld_count * sizeof(loading_params));
+ /* Fermture de l'éventuel fichier XML de chargement */
+
+ if (handler->xdoc != NULL)
+ close_xml_file(handler->xdoc, handler->context);
+
+ G_OBJECT_CLASS(g_loading_handler_parent_class)->finalize(G_OBJECT(handler));
}
/******************************************************************************
* *
-* Paramètres : project = projet dont le contenu est à consulter. *
-* wid = identifiant du groupe d'exploration recherché. *
-* ptr = pointeur vers la valeur d'origine externe. *
+* Paramètres : project = projet dont le contenu est à compléter. *
+* content = contenu binaire à mémoriser pour le projet. *
* *
-* Description : Retrouve les infos de chargements liées à une exploration. *
+* Description : Crée une tâche de chargement de contenu bianire. *
* *
-* Retour : Informations trouvées ou NULL en cas d'échec. *
+* Retour : Tâche créée. *
* *
* Remarques : - *
* *
******************************************************************************/
-static loading_params *g_study_project_find_exploration(GStudyProject *project, wgroup_id_t wid, const wgroup_id_t **ptr)
+static GLoadingHandler *g_loading_handler_new_discovering(GStudyProject *project, GBinContent *content)
{
- loading_params *result; /* Trouvaille à retourner */
- const wgroup_id_t *value; /* Raccourci de confort */
- size_t i; /* Boucle de parcours #1 */
- size_t k; /* Boucle de parcours #2 */
+ GLoadingHandler *result; /* Tâche à retourner */
+ GContentExplorer *explorer; /* Explorateur de contenus */
- assert(!g_mutex_trylock(&project->ld_mutex));
+ result = g_object_new(G_TYPE_LOADING_HANDLER, NULL);
- result = NULL;
+ result->project = project;
+ g_object_ref(G_OBJECT(result->project));
- value = NULL;
+ result->xdoc = NULL;
+ result->context = NULL;
- for (i = 0; i < project->ld_count && result == NULL; i++)
- for (k = 0; k < project->ld_params[i].exp_count && result == NULL; k++)
- {
- value = project->ld_params[i].exp_wids[k];
+ result->exp_wids = (const wgroup_id_t **)malloc(sizeof(wgroup_id_t *));
+ result->exp_count = 1;
- if (*value == wid)
- result = &project->ld_params[i];
+ result->resolved = 0;
- }
+ explorer = get_current_content_explorer();
- if (ptr != NULL)
- {
- assert(result == NULL || value != NULL);
- *ptr = (result == NULL ? NULL : value);
- }
+ g_mutex_lock(&result->mutex);
+
+ result->exp_wids[0] = g_content_explorer_create_group(explorer, content);
+
+ g_mutex_unlock(&result->mutex);
+
+ g_object_unref(G_OBJECT(explorer));
return result;
@@ -648,17 +964,17 @@ static loading_params *g_study_project_find_exploration(GStudyProject *project,
* xdoc = structure XML en cours d'édition. *
* context = contexte à utiliser pour les recherches. *
* *
-* Description : Assure l'intégration de contenus listés dans du XML. *
+* Description : Crée une tâche de chargement de contenu bianire. *
* *
-* Retour : - *
+* Retour : Tâche créée. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void g_study_project_recover_binary_contents(GStudyProject *project, xmlDoc *xdoc, xmlXPathContext *context)
+static GLoadingHandler *g_loading_handler_new_recovering(GStudyProject *project, xmlDoc *xdoc, xmlXPathContext *context)
{
- loading_params *params; /* Informations de chargement */
+ GLoadingHandler *result; /* Tâche à retourner */
xmlXPathObjectPtr xobject; /* Cible d'une recherche */
size_t count; /* Nombre de contenus premiers */
GContentExplorer *explorer; /* Explorateur de contenus */
@@ -673,21 +989,24 @@ static void g_study_project_recover_binary_contents(GStudyProject *project, xmlD
if (count > 0)
{
- explorer = get_current_content_explorer();
+ result = g_object_new(G_TYPE_LOADING_HANDLER, NULL);
- g_mutex_lock(&project->ld_mutex);
+ result->project = project;
+ g_object_ref(G_OBJECT(result->project));
- params = g_study_project_prepare_content_loading(project);
+ result->xdoc = xdoc;
+ result->context = context;
- params->exp_wids = (const wgroup_id_t **)malloc(count * sizeof(wgroup_id_t *));
+ result->exp_wids = (const wgroup_id_t **)malloc(count * sizeof(wgroup_id_t *));
- params->resolved = 0;
+ result->resolved = 0;
- params->xdoc = xdoc;
- params->context = context;
+ explorer = get_current_content_explorer();
explored = 0;
+ g_mutex_lock(&result->mutex);
+
for (i = 0; i < XPATH_OBJ_NODES_COUNT(xobject); i++)
{
asprintf(&access, "/ChrysalideProject/RootContents/Content[position()=%zu]", i + 1);
@@ -702,32 +1021,37 @@ static void g_study_project_recover_binary_contents(GStudyProject *project, xmlD
continue;
}
- params->exp_wids[explored++] = g_content_explorer_create_group(explorer, content);
+ result->exp_wids[explored++] = g_content_explorer_create_group(explorer, content);
g_object_unref(G_OBJECT(content));
}
- params->exp_count = explored;
+ result->exp_count = explored;
- g_mutex_unlock(&project->ld_mutex);
+ g_mutex_unlock(&result->mutex);
g_object_unref(G_OBJECT(explorer));
}
+ else
+ result = NULL;
+
if(xobject != NULL)
xmlXPathFreeObject(xobject);
+ return result;
+
}
/******************************************************************************
* *
-* Paramètres : project = projet dont le contenu est à compléter. *
-* content = contenu binaire à mémoriser pour le projet. *
+* Paramètres : handler = opération de chargement à menuer. *
+* status = barre de statut à tenir informée. *
* *
-* Description : Assure l'intégration de contenus binaires dans un projet. *
+* Description : Assure le chargement de contenus binaires en différé. *
* *
* Retour : - *
* *
@@ -735,30 +1059,59 @@ static void g_study_project_recover_binary_contents(GStudyProject *project, xmlD
* *
******************************************************************************/
-void g_study_project_discover_binary_content(GStudyProject *project, GBinContent *content)
+static void g_loading_handler_process(GLoadingHandler *handler, GtkStatusStack *status)
{
- loading_params *params; /* Informations de chargement */
- GContentExplorer *explorer; /* Explorateur de contenus */
+ g_mutex_lock(&handler->mutex);
- explorer = get_current_content_explorer();
+ while (handler->resolved < handler->exp_count)
+ g_cond_wait(&handler->wait_cond, &handler->mutex);
+
+ g_mutex_unlock(&handler->mutex);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : handler = gestionnaire dont contenu est à consulter. *
+* wid = identifiant du groupe d'exploration recherché. *
+* ptr = pointeur vers la valeur d'origine externe. *
+* *
+* Description : Détermine si un encadrement est adapté pour un identifiant. *
+* *
+* Retour : Bilan d'adéquation. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- g_mutex_lock(&project->ld_mutex);
+static bool g_loading_handler_check(GLoadingHandler *handler, wgroup_id_t wid, const wgroup_id_t **ptr)
+{
+ bool result; /* Bilan à retourner */
+ const wgroup_id_t *value; /* Raccourci de confort */
+ size_t i; /* Boucle de parcours */
- params = g_study_project_prepare_content_loading(project);
+ assert(!g_mutex_trylock(&handler->mutex));
- params->exp_wids = (const wgroup_id_t **)malloc(sizeof(wgroup_id_t *));
- params->exp_count = 1;
+ result = false;
+
+ value = NULL;
- params->resolved = 0;
+ for (i = 0; i < handler->exp_count && !result; i++)
+ {
+ value = handler->exp_wids[i];
- params->xdoc = NULL;
- params->context = NULL;
+ result = (*value == wid);
- params->exp_wids[0] = g_content_explorer_create_group(explorer, content);
+ }
- g_mutex_unlock(&project->ld_mutex);
+ if (ptr != NULL)
+ {
+ assert(!result || value != NULL);
+ *ptr = (result ? value : NULL);
+ }
- g_object_unref(G_OBJECT(explorer));
+ return result;
}
@@ -767,7 +1120,7 @@ void g_study_project_discover_binary_content(GStudyProject *project, GBinContent
* *
* Paramètres : explorer = gestionnaire d'explorations à consulter. *
* wid = groupe d'exploration concerné. *
-* project = projet avide des résultats des opérations. *
+* handler = gestionnaire avide des résultats des opérations. *
* *
* Description : Note la fin d'une phase d'exploration de contenu. *
* *
@@ -777,21 +1130,17 @@ void g_study_project_discover_binary_content(GStudyProject *project, GBinContent
* *
******************************************************************************/
-static void on_new_content_explored(GContentExplorer *explorer, wgroup_id_t wid, GStudyProject *project)
+static void on_new_content_explored(GContentExplorer *explorer, wgroup_id_t wid, GLoadingHandler *handler)
{
const wgroup_id_t *wid_ptr; /* Référence vers l'origine */
- loading_params *params; /* Informations de chargement */
GBinContent **available; /* Contenus binaires présents */
size_t count; /* Quantité de ces contenus */
GContentResolver *resolver; /* Resolveur de contenus */
size_t i; /* Boucle de parcours */
- g_mutex_lock(&project->ld_mutex);
-
- params = g_study_project_find_exploration(project, wid, &wid_ptr);
+ g_mutex_lock(&handler->mutex);
- /* S'il s'agit bien d'une exploration nouvelle */
- if (params != NULL)
+ if (g_loading_handler_check(handler, wid, &wid_ptr))
{
available = g_content_explorer_get_all(explorer, wid, &count);
assert(count > 0);
@@ -809,7 +1158,7 @@ static void on_new_content_explored(GContentExplorer *explorer, wgroup_id_t wid,
}
- g_mutex_unlock(&project->ld_mutex);
+ g_mutex_unlock(&handler->mutex);
}
@@ -818,7 +1167,7 @@ static void on_new_content_explored(GContentExplorer *explorer, wgroup_id_t wid,
* *
* Paramètres : resolver = gestionnaire de résolutions à consulter. *
* wid = groupe d'exploration concerné. *
-* project = projet avide des résultats des opérations. *
+* handler = gestionnaire avide des résultats des opérations. *
* *
* Description : Note la fin d'une phase de resolution de contenu. *
* *
@@ -828,9 +1177,8 @@ static void on_new_content_explored(GContentExplorer *explorer, wgroup_id_t wid,
* *
******************************************************************************/
-static void on_new_content_resolved(GContentResolver *resolver, wgroup_id_t wid, GStudyProject *project)
+static void on_new_content_resolved(GContentResolver *resolver, wgroup_id_t wid, GLoadingHandler *handler)
{
- loading_params *params; /* Informations de chargement */
GLoadedContent **available; /* Contenus chargés valables */
size_t count; /* Quantité de ces contenus */
size_t i; /* Boucle de parcours */
@@ -841,19 +1189,16 @@ static void on_new_content_resolved(GContentResolver *resolver, wgroup_id_t wid,
xmlXPathObjectPtr xobject; /* Cible d'une recherche */
bool status; /* Bilan d'une restauration */
- g_mutex_lock(&project->ld_mutex);
+ g_mutex_lock(&handler->mutex);
- params = g_study_project_find_exploration(project, wid, NULL);
-
- /* S'il s'agit bien d'une exploration nouvelle */
- if (params != NULL)
+ if (g_loading_handler_check(handler, wid, NULL))
{
available = g_content_resolver_get_all(resolver, wid, &count);
/* Rechargement à partir d'XML ? */
- if (params->xdoc != NULL)
+ if (handler->xdoc != NULL)
{
- assert(params->context != NULL);
+ assert(handler->context != NULL);
for (i = 0; i < count; i++)
{
@@ -866,12 +1211,12 @@ static void on_new_content_resolved(GContentResolver *resolver, wgroup_id_t wid,
asprintf(&access, "/ChrysalideProject/LoadedContents/Content[@hash='%s' and @format='%s']",
hash, format);
- xobject = get_node_xpath_object(params->context, access);
+ xobject = get_node_xpath_object(handler->context, access);
if (XPATH_OBJ_NODES_COUNT(xobject) > 0)
{
- status = g_loaded_content_restore(available[i], params->xdoc, params->context, access);
+ status = g_loaded_content_restore(available[i], handler->xdoc, handler->context, access);
if (!status)
log_variadic_message(LMT_ERROR,
@@ -888,7 +1233,8 @@ static void on_new_content_resolved(GContentResolver *resolver, wgroup_id_t wid,
*/
g_object_ref(G_OBJECT(available[i]));
- g_signal_connect(available[i], "analyzed", G_CALLBACK(on_loaded_content_analyzed), project);
+ g_signal_connect(available[i], "analyzed",
+ G_CALLBACK(on_loaded_content_analyzed), handler->project);
g_loaded_content_analyze(available[i]);
@@ -921,7 +1267,8 @@ static void on_new_content_resolved(GContentResolver *resolver, wgroup_id_t wid,
*/
g_object_ref(G_OBJECT(available[i]));
- g_signal_connect(available[i], "analyzed", G_CALLBACK(on_loaded_content_analyzed), project);
+ g_signal_connect(available[i], "analyzed",
+ G_CALLBACK(on_loaded_content_analyzed), handler->project);
g_loaded_content_analyze(available[i]);
@@ -936,212 +1283,14 @@ static void on_new_content_resolved(GContentResolver *resolver, wgroup_id_t wid,
free(available);
/* Si c'était la dernière résolution... */
- if (++params->resolved == params->exp_count)
- g_study_project_destroy_content_loading(project, params);
- }
+ handler->resolved++;
- g_mutex_unlock(&project->ld_mutex);
+ g_cond_broadcast(&handler->wait_cond);
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : content = contenu chargé et analysé. *
-* success = bilan d'une analyse menée. *
-* project = projet avide des résultats des opérations. *
-* *
-* Description : Réceptionne la recette d'une analyse de contenu. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void on_loaded_content_analyzed(GLoadedContent *content, gboolean success, GStudyProject *project)
-{
- const char *desc; /* Description du contenu */
-
- desc = g_loaded_content_describe(content, true);
-
- if (success)
- {
- g_study_project_attach_content(project, content);
- log_variadic_message(LMT_INFO, _("Content from '%s' has been analyzed successfully!"), desc);
}
- else
- log_variadic_message(LMT_ERROR, _("Failed to load '%s'"), desc);
-
- g_object_ref(G_OBJECT(content));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : project = project à manipuler. *
-* content = contenu chargé à associer au projet actuel. *
-* *
-* Description : Attache un contenu donné à un projet donné. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_study_project_attach_content(GStudyProject *project, GLoadedContent *content)
-{
- g_mutex_lock(&project->mutex);
-
- project->contents = (GLoadedContent **)realloc(project->contents,
- ++project->count * sizeof(GLoadedContent *));
-
- project->contents[project->count - 1] = content;
- g_object_ref(G_OBJECT(content));
-
- g_mutex_unlock(&project->mutex);
-
- g_signal_emit_by_name(project, "content-added", content);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : project = project à manipuler. *
-* content = contenu chargé à dissocier du projet actuel. *
-* *
-* Description : Détache un contenu donné d'un projet donné. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_study_project_detach_content(GStudyProject *project, GLoadedContent *content)
-{
- size_t i; /* Boucle de parcours */
-
- g_mutex_lock(&project->mutex);
-
- for (i = 0; i < project->count; i++)
- if (project->contents[i] == content) break;
-
- if ((i + 1) < project->count)
- memmove(&project->contents[i], &project->contents[i + 1],
- (project->count - i - 1) * sizeof(GLoadedContent *));
-
- project->contents = (GLoadedContent **)realloc(project->contents,
- --project->count * sizeof(GLoadedContent *));
-
- g_mutex_unlock(&project->mutex);
-
- g_signal_emit_by_name(project, "content-removed", content);
-
- g_object_unref(G_OBJECT(content));
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : project = projet dont le contenu est à afficher. *
-* *
-* Description : Met en place un projet à l'écran. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_study_project_display(const GStudyProject *project)
-{
-#if 0
- size_t i; /* Boucle de parcours #1 */
- loaded_binary *handled; /* Binaire prise en compte */
- size_t j; /* Boucle de parcours #2 */
-
- for (i = 0; i < project->binaries_count; i++)
- {
- handled = project->binaries[i];
-
- for (j = 0; j < handled->count; j++)
- g_panel_item_dock(handled->items[j]);
-
- }
-#endif
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : project = projet dont le contenu est à cacher. *
-* *
-* Description : Supprime de l'écran un projet en place. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_study_project_hide(const GStudyProject *project)
-{
-#if 0
- size_t i; /* Boucle de parcours #1 */
- loaded_binary *handled; /* Binaire prise en compte */
- size_t j; /* Boucle de parcours #2 */
-
- for (i = 0; i < project->binaries_count; i++)
- {
- handled = project->binaries[i];
-
- for (j = 0; j < handled->count; j++)
- g_panel_item_undock(handled->items[j]);
-
- }
-#endif
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : project = projet dont le contenu est à afficher. *
-* count = nombre de contenus pris en compte. [OUT] *
-* *
-* Description : Fournit l'ensemble des contenus associés à un projet. *
-* *
-* Retour : Liste à libérer de la mémoire. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GLoadedContent **g_study_project_get_contents(GStudyProject *project, size_t *count)
-{
- GLoadedContent **result; /* Tableau à retourner */
- size_t i; /* Boucle de parcours */
-
- g_mutex_lock(&project->mutex);
-
- *count = project->count;
- result = (GLoadedContent **)calloc(*count, sizeof(GLoadedContent *));
-
- for (i = 0; i < *count; i++)
- {
- result[i] = project->contents[i];
- g_object_ref(G_OBJECT(result[i]));
- }
-
- g_mutex_unlock(&project->mutex);
-
- return result;
+ g_mutex_unlock(&handler->mutex);
}
diff --git a/src/core/queue.c b/src/core/queue.c
index 615e351..79a87b2 100644
--- a/src/core/queue.c
+++ b/src/core/queue.c
@@ -60,6 +60,13 @@ bool init_global_works(void)
g_work_queue_define_work_group(queue);
#endif
+#ifndef NDEBUG
+ expected = g_work_queue_define_work_group(queue);
+ assert(expected == LOADING_WORK_GROUP);
+#else
+ g_work_queue_define_work_group(queue);
+#endif
+
return true;
}
@@ -105,7 +112,8 @@ void wait_for_all_global_works(void)
GWorkQueue *queue; /* Singleton pour tâches */
static const wgroup_id_t group_ids[] = {
- DEFAULT_WORK_GROUP
+ DEFAULT_WORK_GROUP,
+ LOADING_WORK_GROUP
};
queue = get_work_queue();
diff --git a/src/core/queue.h b/src/core/queue.h
index 1984fff..bee16a4 100644
--- a/src/core/queue.h
+++ b/src/core/queue.h
@@ -34,8 +34,9 @@
*/
#define DEFAULT_WORK_GROUP 0
+#define LOADING_WORK_GROUP 1
-#define GLOBAL_WORK_GROUPS_COUNT 1
+#define GLOBAL_WORK_GROUPS_COUNT 2
/* Met en place les mécanismes de traitements parallèles. */