summaryrefslogtreecommitdiff
path: root/src/analysis/db/cdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis/db/cdb.c')
-rw-r--r--src/analysis/db/cdb.c133
1 files changed, 106 insertions, 27 deletions
diff --git a/src/analysis/db/cdb.c b/src/analysis/db/cdb.c
index c5d3af7..b1e47bc 100644
--- a/src/analysis/db/cdb.c
+++ b/src/analysis/db/cdb.c
@@ -101,9 +101,13 @@ struct _GCdbArchive
char *filename; /* Chemin d'accès à l'archive */
char *tmpdir; /* Répertoire de travail */
- char *cnt_file; /* Fichier de contenu binaire */
char *xml_desc; /* Fichier de description */
+ char *cnt_file; /* Fichier de contenu binaire */
+
+ GMutex loading_access; /* Verrou pour l'accès */
+
+
GList *collections; /* Ensemble de modifications */
GDbSnapshot *snapshot; /* Instantanés de bases SQL */
@@ -189,8 +193,8 @@ static bool g_cdb_archive_send_snapshot_change(GCdbArchive *, packed_buffer_t *)
/* ------------------------- PRISES EN COMPTE DES COMMANDES ------------------------- */
-/* Prépare la réponse à envoyer à un client connecté. */
-static bool setup_server_answer(DBCommand, DBError, packed_buffer_t *);
+/* Prépare une courte réponse à envoyer à un client connecté. */
+static bool craft_server_short_answer(DBCommand, uleb128_t, packed_buffer_t *);
/* Enregistre le contenu binaire lié à une analyse. */
static bool g_cdb_archive_set_content(GCdbArchive *, packed_buffer_t *, packed_buffer_t *);
@@ -218,7 +222,7 @@ static cdb_client *create_cdb_client(SSL *fd, const char *peer_name, const char
{
cdb_client *result; /* Fiche d'entité à retourner */
- result = malloc(sizeof(cdb_client *));
+ result = malloc(sizeof(cdb_client));
result->tls_fd = fd;
@@ -358,9 +362,11 @@ static void g_cdb_archive_init(GCdbArchive *archive)
archive->filename = NULL;
archive->tmpdir = NULL;
- archive->cnt_file = NULL;
archive->xml_desc = NULL;
+ archive->cnt_file = NULL;
+ g_mutex_init(&archive->loading_access);
+
archive->collections = create_collections_list();
archive->snapshot = NULL;
@@ -387,9 +393,11 @@ static void g_cdb_archive_dispose(GCdbArchive *archive)
{
g_server_backend_stop(G_SERVER_BACKEND(archive));
+ g_mutex_clear(&archive->clients_access);
+
g_clear_object(&archive->snapshot);
- g_mutex_clear(&archive->clients_access);
+ g_mutex_clear(&archive->loading_access);
G_OBJECT_CLASS(g_cdb_archive_parent_class)->dispose(G_OBJECT(archive));
@@ -1459,38 +1467,100 @@ static void *g_cdb_archive_process(GCdbArchive *archive)
* *
******************************************************************************/
+static LoadingStatusHint g_cdb_archive_compute_loading_hint(GCdbArchive *archive)
+{
+ LoadingStatusHint result; /* Statut à retourner */
+
+
+ // Try
+ // g_mutex_lock(&archive->loading_access);
+
+
+
+ // cnt_file
+
+ if (archive->cnt_file == NULL)
+ result = LSH_NEED_CONTENT;
+
+ else
+ result = LSH_NEED_FORMAT;
+
+
+
+
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : archive = support pour le suivi d'une connexion. *
+* fd = canal de communication réseau ouvert. *
+* peer_name = désignation de la connexion. *
+* user = désignation de l'utilisateur de la connexion. *
+* *
+* Description : Prend en compte une connexion nouvelle d'un utilisateur. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
static void g_cdb_archive_add_client(GCdbArchive *archive, SSL *fd, const char *peer_name, const char *user)
{
cdb_client *client; /* Nouvelle fiche d'entité */
+ packed_buffer_t out_pbuf; /* Tampon d'émission */
+ LoadingStatusHint hint; /* Statut de chargement */
+ bool status; /* Bilan de lecture initiale */
+
+ client = create_cdb_client(fd, peer_name, user);
/**
- * La situation est un peu compliquée lors de l'accueil d'un nouveau client :
- *
- * - soit on envoie tous les éléments à prendre en compte, mais on doit
- * bloquer la base de données jusqu'à l'intégration pleine et entière
- * du client, afin que ce dernier ne loupe pas l'envoi d'un nouvel
- * élément entre temps.
+ * Le verrou encadrant les évolutions des contenus initiaux doit englober
+ * l'extension de la liste des clients.
*
- * - soit on intègre le client et celui ci demande des mises à jour
- * collection par collection ; c'est également à lui que revient le rejet
- * des éléments envoyés en solitaires avant la réception de la base
- * complète.
+ * En effet, une évolution partielle peut intervenir dans la fonction
+ * g_cdb_archive_process(), à un moment au seul le verrou dans les
+ * évolutions sera posé (g_cdb_archive_set_content() par exemple).
*
- * On fait le choix du second scenario ici, du fait de la difficulté
- * de maîtriser facilement la reconstitution d'une liste de clients dans
- * g_cdb_archive_process() depuis un autre flot d'exécution.
+ * Or g_cdb_archive_compute_loading_hint() doit fournir ici un état qui ne
+ * varie pas entre le calcul et l'envoi. Donc verrous sur les clients et
+ * l'état de l'archive doivent englover l'ensemble des traitements ci-après.
*/
- client = create_cdb_client(fd, peer_name, user);
+ g_mutex_lock(&archive->loading_access);
g_mutex_lock(&archive->clients_access);
- archive->clients = realloc(archive->clients, ++archive->count * sizeof(cdb_client *));
+ hint = g_cdb_archive_compute_loading_hint(archive);
+
+ if (hint != LSH_READY)
+ hint = (archive->count == 0 ? hint : LSH_ON_WAIT_LIST);
+
+ init_packed_buffer(&out_pbuf);
+
+ status = craft_server_short_answer(DBC_LOADING_STATUS, hint, &out_pbuf);
+
+ if (status)
+ status = ssl_send_packed_buffer(&out_pbuf, fd);
+
+ exit_packed_buffer(&out_pbuf);
+
+ if (status)
+ {
+ archive->clients = realloc(archive->clients, ++archive->count * sizeof(cdb_client *));
+
+ archive->clients[archive->count - 1] = client;
- archive->clients[archive->count - 1] = client;
+ }
g_mutex_unlock(&archive->clients_access);
+ g_mutex_unlock(&archive->loading_access);
+
}
@@ -1694,10 +1764,10 @@ static bool g_cdb_archive_send_snapshot_change(GCdbArchive *archive, packed_buff
/******************************************************************************
* *
* Paramètres : cmd = commande à l'origine d'un traitement. *
-* error = bilan de traitement à communiquer. *
+* value = valeur à communiquer. *
* out_pbuf = paquet à consituer pour un retour au client. [OUT]*
* *
-* Description : Prépare la réponse à envoyer à un client connecté. *
+* Description : Prépare une courte réponse à envoyer à un client connecté. *
* *
* Retour : Indication pour le maintien de la communication. *
* *
@@ -1705,7 +1775,7 @@ static bool g_cdb_archive_send_snapshot_change(GCdbArchive *archive, packed_buff
* *
******************************************************************************/
-static bool setup_server_answer(DBCommand cmd, DBError error, packed_buffer_t *out_pbuf)
+static bool craft_server_short_answer(DBCommand cmd, uleb128_t value, packed_buffer_t *out_pbuf)
{
bool result; /* Bilan à retourner */
@@ -1714,7 +1784,7 @@ static bool setup_server_answer(DBCommand cmd, DBError error, packed_buffer_t *o
result = extend_packed_buffer(out_pbuf, (uint32_t []) { cmd }, sizeof(uint32_t), true);
if (result)
- result = extend_packed_buffer(out_pbuf, (uint32_t []) { error }, sizeof(uint32_t), true);
+ result = pack_uleb128((uleb128_t []){ value }, out_pbuf);
return result;
@@ -1748,6 +1818,7 @@ static bool g_cdb_archive_set_content(GCdbArchive *archive, packed_buffer_t *in_
const gchar *hash; /* Empreinte de ce contenu */
int fd; /* Flux ouvert en écriture */
bool status; /* Bilan d'une écriture */
+ LoadingStatusHint hint; /* Statut de chargement */
result = true;
error = DBE_NONE;
@@ -1848,7 +1919,15 @@ static bool g_cdb_archive_set_content(GCdbArchive *archive, packed_buffer_t *in_
/* Formulation de la réponse */
- result = setup_server_answer(DBC_SET_CONTENT, error, out_pbuf);
+ result = craft_server_short_answer(DBC_SET_CONTENT, error, out_pbuf);
+
+ if (result && error == DBE_NONE)
+ {
+ hint = g_cdb_archive_compute_loading_hint(archive);
+
+ result = craft_server_short_answer(DBC_LOADING_STATUS, hint, out_pbuf);
+
+ }
free_and_exit: