[yelp] libyelp: Auto-reload Mallard documents
- From: Shaun McCance <shaunm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [yelp] libyelp: Auto-reload Mallard documents
- Date: Thu, 19 Jan 2012 19:50:34 +0000 (UTC)
commit f755aaf23e92a7211c50b8881b648c6f8b97939b
Author: Shaun McCance <shaunm gnome org>
Date: Thu Jan 19 14:49:19 2012 -0500
libyelp: Auto-reload Mallard documents
libyelp/yelp-document.c | 38 +++++++++++++++++-
libyelp/yelp-document.h | 2 +
libyelp/yelp-mallard-document.c | 83 +++++++++++++++++++++++++++++++++++++++
3 files changed, 122 insertions(+), 1 deletions(-)
---
diff --git a/libyelp/yelp-document.c b/libyelp/yelp-document.c
index d6c0ff7..83605dd 100644
--- a/libyelp/yelp-document.c
+++ b/libyelp/yelp-document.c
@@ -479,8 +479,9 @@ yelp_document_set_page_id (YelpDocument *document,
request->page_id = g_strdup (page_id);
hash_slist_insert (document->priv->reqs_by_page_id, page_id, request);
}
- if (reqs)
+ if (reqs) {
hash_remove (document->priv->reqs_by_page_id, id);
+ }
}
if (page_id != NULL) {
@@ -863,6 +864,41 @@ document_request_page (YelpDocument *document,
return ret;
}
+void
+yelp_document_clear_contents (YelpDocument *document)
+{
+ g_mutex_lock (document->priv->mutex);
+
+ if (document->priv->contents->null) {
+ str_unref (document->priv->contents->null);
+ document->priv->contents->null = NULL;
+ }
+ g_hash_table_remove_all (document->priv->contents->hash);
+
+ g_mutex_unlock (document->priv->mutex);
+}
+
+gchar **
+yelp_document_get_requests (YelpDocument *document)
+{
+ GList *reqs, *cur;
+ gchar **ret;
+ gint i;
+
+ g_mutex_lock (document->priv->mutex);
+
+ reqs = g_hash_table_get_keys (document->priv->reqs_by_page_id->hash);
+ ret = g_new0 (gchar*, g_list_length (reqs) + 1);
+ for (cur = reqs, i = 0; cur; cur = cur->next, i++) {
+ ret[i] = g_strdup ((gchar *) cur->data);
+ }
+ g_list_free (reqs);
+
+ g_mutex_unlock (document->priv->mutex);
+
+ return ret;
+}
+
/******************************************************************************/
const gchar *
diff --git a/libyelp/yelp-document.h b/libyelp/yelp-document.h
index 16fc8aa..3214dcf 100644
--- a/libyelp/yelp-document.h
+++ b/libyelp/yelp-document.h
@@ -85,6 +85,8 @@ gboolean yelp_document_request_page (YelpDocument *document,
GCancellable *cancellable,
YelpDocumentCallback callback,
gpointer user_data);
+void yelp_document_clear_contents (YelpDocument *document);
+gchar ** yelp_document_get_requests (YelpDocument *document);
void yelp_document_give_contents (YelpDocument *document,
const gchar *page_id,
diff --git a/libyelp/yelp-mallard-document.c b/libyelp/yelp-mallard-document.c
index 5ce5f17..fbb9c30 100644
--- a/libyelp/yelp-mallard-document.c
+++ b/libyelp/yelp-mallard-document.c
@@ -104,6 +104,11 @@ static void mallard_page_data_info (MallardPageData *page_data
xmlNodePtr cache_node);
static void mallard_page_data_run (MallardPageData *page_data);
static void mallard_page_data_free (MallardPageData *page_data);
+static void mallard_monitor_changed (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ YelpMallardDocument *mallard);
static const char * xml_node_get_icon (xmlNodePtr node);
static gboolean xml_node_is_ns_name (xmlNodePtr node,
@@ -130,6 +135,8 @@ struct _YelpMallardDocumentPrivate {
xmlNsPtr cache_ns;
GHashTable *pages_hash;
+ GFileMonitor **monitors;
+
xmlXPathCompExprPtr normalize;
};
@@ -176,6 +183,17 @@ yelp_mallard_document_init (YelpMallardDocument *mallard)
static void
yelp_mallard_document_dispose (GObject *object)
{
+ gint i;
+ YelpMallardDocumentPrivate *priv = GET_PRIV (object);
+
+ if (priv->monitors != NULL) {
+ for (i = 0; priv->monitors[i]; i++) {
+ g_object_unref (priv->monitors[i]);
+ }
+ g_free (priv->monitors);
+ priv->monitors = NULL;
+ }
+
G_OBJECT_CLASS (yelp_mallard_document_parent_class)->dispose (object);
}
@@ -188,6 +206,7 @@ yelp_mallard_document_finalize (GObject *object)
g_mutex_free (priv->mutex);
g_hash_table_destroy (priv->pages_hash);
+ xmlFreeDoc (priv->cache);
if (priv->normalize)
xmlXPathFreeCompExpr (priv->normalize);
@@ -202,6 +221,8 @@ yelp_mallard_document_new (YelpUri *uri)
YelpMallardDocument *mallard;
YelpMallardDocumentPrivate *priv;
gchar *doc_uri;
+ gchar **path;
+ gint path_i;
g_return_val_if_fail (uri != NULL, NULL);
@@ -216,6 +237,21 @@ yelp_mallard_document_new (YelpUri *uri)
yelp_document_set_page_id ((YelpDocument *) mallard, NULL, "index");
yelp_document_set_page_id ((YelpDocument *) mallard, "index", "index");
+ path = yelp_uri_get_search_path (uri);
+ priv->monitors = g_new0 (GFileMonitor*, g_strv_length (path) + 1);
+ for (path_i = 0; path[path_i]; path_i++) {
+ GFile *file;
+ file = g_file_new_for_path (path[path_i]);
+ priv->monitors[path_i] = g_file_monitor (file,
+ G_FILE_MONITOR_SEND_MOVED,
+ NULL, NULL);
+ g_signal_connect (priv->monitors[path_i], "changed",
+ G_CALLBACK (mallard_monitor_changed),
+ mallard);
+ g_object_unref (file);
+ }
+ g_strfreev (path);
+
return (YelpDocument *) mallard;
}
@@ -1069,3 +1105,50 @@ mallard_index (YelpDocument *document)
priv->index_running = TRUE;
}
+static void
+mallard_monitor_changed (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ YelpMallardDocument *mallard)
+{
+ gchar **ids;
+ gint i;
+ xmlNodePtr cur;
+ YelpMallardDocumentPrivate *priv = GET_PRIV (mallard);
+
+ /* Exiting the thinking thread would require a fair amount of retooling.
+ For now, we'll just fail to auto-reload if that's still happening.
+ */
+ if (priv->thread_running)
+ return;
+
+ g_mutex_lock (priv->mutex);
+
+ g_hash_table_remove_all (priv->pages_hash);
+ g_object_set (mallard, "indexed", FALSE, NULL);
+
+ ids = yelp_document_get_requests (YELP_DOCUMENT (mallard));
+ for (i = 0; ids[i]; i++) {
+ priv->pending = g_slist_prepend (priv->pending, ids[i]);
+ }
+ g_free (ids);
+
+ yelp_document_clear_contents (YELP_DOCUMENT (mallard));
+
+ xmlFreeDoc (priv->cache);
+ priv->cache = xmlNewDoc (BAD_CAST "1.0");
+ priv->cache_ns = xmlNewNs (NULL, BAD_CAST MALLARD_NS, BAD_CAST "mal");
+ cur = xmlNewDocNode (priv->cache, priv->cache_ns, BAD_CAST "cache", NULL);
+ xmlDocSetRootElement (priv->cache, cur);
+ priv->cache_ns->next = cur->nsDef;
+ cur->nsDef = priv->cache_ns;
+
+ priv->state = MALLARD_STATE_THINKING;
+ priv->thread_running = TRUE;
+ g_object_ref (mallard);
+ priv->thread = g_thread_create ((GThreadFunc) mallard_think,
+ mallard, FALSE, NULL);
+
+ g_mutex_unlock (priv->mutex);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]