SF.net SVN: geany:[3933] trunk
eht16 at users.sourceforge.net
eht16 at xxxxx
Wed Jul 8 22:20:17 UTC 2009
Revision: 3933
http://geany.svn.sourceforge.net/geany/?rev=3933&view=rev
Author: eht16
Date: 2009-07-08 22:20:17 +0000 (Wed, 08 Jul 2009)
Log Message:
-----------
Rework the GIO based file monitoring code.
Now it is used only to indicate a possible change of the file, the real check if the file has been changed is performed by stat().
Modified Paths:
--------------
trunk/ChangeLog
trunk/src/document.c
trunk/src/documentprivate.h
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2009-07-08 15:47:38 UTC (rev 3932)
+++ trunk/ChangeLog 2009-07-08 22:20:17 UTC (rev 3933)
@@ -1,3 +1,11 @@
+2009-07-08 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
+
+ * src/document.c, src/documentprivate.h:
+ Rework the GIO based file monitoring code. Now it is used only
+ to indicate a possible change of the file, the real check if the
+ file has been changed is performed by stat().
+
+
2009-07-08 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
* src/interface.c, src/keyfile.c, src/editor.c, src/editor.h,
Modified: trunk/src/document.c
===================================================================
--- trunk/src/document.c 2009-07-08 15:47:38 UTC (rev 3932)
+++ trunk/src/document.c 2009-07-08 22:20:17 UTC (rev 3933)
@@ -387,7 +387,9 @@
priv->undo_actions = NULL;
priv->redo_actions = NULL;
priv->line_count = 0;
+#if ! defined(USE_GIO_FILEMON)
priv->last_check = time(NULL);
+#endif
}
@@ -422,99 +424,37 @@
#if defined(HAVE_GIO) && defined(USE_GIO_FILEMON)
-/* Set the file status to 'changed' after a single 'created' event. */
-static gboolean monitor_finish_pending_create(gpointer doc)
-{
- g_return_val_if_fail(doc != NULL, FALSE);
-
- ((GeanyDocument *)doc)->priv->file_disk_status = FILE_CHANGED;
- ui_update_tab_status(doc);
-
- return FALSE;
-}
-
-
-/* Resets the 'ignore' file status after a reload action. */
-static gboolean monitor_reset_ignore(gpointer data)
-{
- GeanyDocument *doc = data;
- /* FIXME even if the doc is valid, it might be the wrong document if the original document was
- * closed a new one opened which got this doc pointer while the timeout was active. Either
- * remove the timeout when closing or document or remove the timeout completely. */
- if (DOC_VALID(doc))
- {
- doc->priv->file_disk_status = FILE_OK;
- ui_update_tab_status(doc);
- }
- return FALSE;
-}
-
-
static void monitor_file_changed_cb(G_GNUC_UNUSED GFileMonitor *monitor, G_GNUC_UNUSED GFile *file,
- G_GNUC_UNUSED GFile *other_file, GFileMonitorEvent event, GeanyDocument *doc)
+ G_GNUC_UNUSED GFile *other_file, GFileMonitorEvent event,
+ GeanyDocument *doc)
{
g_return_if_fail(doc != NULL);
if (file_prefs.disk_check_timeout == 0)
return;
+ geany_debug("%s: event: %d previous file status: %d",
+ G_STRFUNC, event, doc->priv->file_disk_status);
switch (event)
{
+ case G_FILE_MONITOR_EVENT_CREATED:
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
{
- if (doc->priv->file_disk_status == FILE_CREATED_PENDING)
- {
- g_source_remove(doc->priv->last_check);
- doc->priv->file_disk_status = FILE_IGNORE;
- }
if (doc->priv->file_disk_status == FILE_IGNORE)
- { /* ignore this change completely, used after saving a file */
- FileDiskStatus old_status = doc->priv->file_disk_status;
doc->priv->file_disk_status = FILE_OK;
- if (old_status != FILE_OK)
- ui_update_tab_status(doc);
- return;
- }
- doc->priv->file_disk_status = FILE_CHANGED;
+ else
+ doc->priv->file_disk_status = FILE_CHANGED;
+ g_message("%s: FILE_CHANGED", G_STRFUNC);
break;
}
case G_FILE_MONITOR_EVENT_DELETED:
{
- if (doc->priv->file_disk_status != FILE_IGNORE)
- doc->priv->file_disk_status = FILE_MISSING;
+ doc->priv->file_disk_status = FILE_CHANGED;
+ g_message("%s: FILE_MISSING", G_STRFUNC);
break;
}
- case G_FILE_MONITOR_EVENT_CREATED:
- {
- if (doc->priv->file_disk_status == FILE_MISSING)
- { /* When the last state was 'missing', we are most probably in a
- * delete-create-change set, so set the new state to 'ok' and do the real handling
- * in the upcoming G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT event. */
- doc->priv->file_disk_status = FILE_OK;
- }
- else
- { /* In case we have a single 'created' event and not within a set of other events,
- * we defer the processing into a timeout function which is removed when a
- * G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT event arrives before. */
- doc->priv->file_disk_status = FILE_CREATED_PENDING;
- /* re-use otherwise unused 'last_check' field to store the timeout ID, we need it
- * to remove the timeout and we need to store it per-document */
- doc->priv->last_check = g_timeout_add_seconds(1, monitor_finish_pending_create, doc);
- }
- if (doc->real_path == NULL)
- {
- gchar *locale_filename = g_file_get_path(file);
- doc->real_path = tm_get_real_path(locale_filename);
- g_free(locale_filename);
- }
+ default:
break;
- }
- /* ignore */
- case G_FILE_MONITOR_EVENT_CHANGED:
- case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
- case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
- case G_FILE_MONITOR_EVENT_UNMOUNTED:
- return;
}
if (doc->priv->file_disk_status != FILE_OK)
{
@@ -545,7 +485,6 @@
{
#if defined(HAVE_GIO) && defined(USE_GIO_FILEMON)
gchar *locale_filename;
- GFile *file;
/* stop any previous monitoring */
document_stop_file_monitoring(doc);
@@ -554,7 +493,7 @@
if (locale_filename != NULL && g_file_test(locale_filename, G_FILE_TEST_EXISTS))
{
/* get a file monitor and connect to the 'changed' signal */
- file = g_file_new_for_path(locale_filename);
+ GFile *file = g_file_new_for_path(locale_filename);
doc->priv->monitor = g_file_monitor_file(file, G_FILE_MONITOR_NONE, NULL, NULL);
g_signal_connect(doc->priv->monitor, "changed",
G_CALLBACK(monitor_file_changed_cb), doc);
@@ -1444,17 +1383,8 @@
/* try to set the cursor to the position before reloading */
pos = sci_get_current_position(doc->editor->sci);
- new_doc = document_open_file_full(doc, NULL, pos, doc->readonly,
- doc->file_type, forced_enc);
-#if defined(HAVE_GIO) && defined(USE_GIO_FILEMON)
- if (new_doc != NULL)
- {
- doc->priv->file_disk_status = FILE_IGNORE;
- /* In case the reload operation didn't produce any events to ignore,
- * remove the ignore status. */
- g_timeout_add_seconds(3, monitor_reset_ignore, doc);
- }
-#endif
+ new_doc = document_open_file_full(doc, NULL, pos, doc->readonly, doc->file_type, forced_enc);
+
return (new_doc != NULL);
}
@@ -2774,11 +2704,8 @@
if (doc->changed)
color = &red;
#if defined(HAVE_GIO) && defined(USE_GIO_FILEMON)
- else if (doc->priv->file_disk_status == FILE_MISSING ||
- doc->priv->file_disk_status == FILE_CHANGED)
- {
+ else if (doc->priv->file_disk_status == FILE_CHANGED)
color = &orange;
- }
#endif
else if (doc->readonly)
color = &green;
@@ -2901,12 +2828,12 @@
want_reload = dialogs_show_question_full(NULL, _("_Reload"), GTK_STOCK_CANCEL,
_("Do you want to reload it?"),
- _("The file '%s' on the disk is more recent than\n"
- "the current buffer."), base_name);
+ _("The file '%s' on the disk is more recent than\nthe current buffer."),
+ base_name);
+
if (want_reload)
- {
document_reload_file(doc, NULL);
- }
+
g_free(base_name);
return want_reload;
}
@@ -2932,87 +2859,63 @@
}
-static time_t monitor_check_status_real(GeanyDocument *doc, gboolean force)
+/* Set force to force a disk check, otherwise it is ignored if there was a check
+ * in the last file_prefs.disk_check_timeout seconds.
+ * @return @c TRUE if the file has changed. */
+gboolean document_check_disk_status(GeanyDocument *doc, gboolean force)
{
- time_t t = 0;
+ gboolean ret = FALSE;
+ gboolean use_gio_filemon;
+ time_t cur_time = 0;
struct stat st;
gchar *locale_filename;
+ FileDiskStatus old_status;
- t = time(NULL);
+ g_return_val_if_fail(doc != NULL, FALSE);
- if (! force && doc->priv->last_check > (t - file_prefs.disk_check_timeout))
- return 0;
+ /* ignore remote files and documents that have never been saved to disk */
+ if (file_prefs.disk_check_timeout == 0 || doc->real_path == NULL || doc->priv->is_remote)
+ return FALSE;
- doc->priv->last_check = t;
+ use_gio_filemon = (doc->priv->monitor != NULL);
+ if (use_gio_filemon)
+ {
+ if (doc->priv->file_disk_status != FILE_CHANGED && ! force)
+ return FALSE;
+ }
+ else
+ {
+ cur_time = time(NULL);
+ if (! force && doc->priv->last_check > (cur_time - file_prefs.disk_check_timeout))
+ return FALSE;
+
+ doc->priv->last_check = cur_time;
+ }
+
locale_filename = utils_get_locale_from_utf8(doc->file_name);
if (g_stat(locale_filename, &st) != 0)
{
- doc->priv->file_disk_status = FILE_MISSING;
- return 0;
+ monitor_resave_missing_file(doc);
+ ret = TRUE;
}
- else if (G_UNLIKELY(doc->priv->mtime > t) || G_UNLIKELY(st.st_mtime > t))
+ else if (! use_gio_filemon && /* ignore these check when using GIO */
+ (G_UNLIKELY(doc->priv->mtime > cur_time) || G_UNLIKELY(st.st_mtime > cur_time)))
{
g_warning("%s: Something is wrong with the time stamps.", G_STRFUNC);
}
else if (doc->priv->mtime < st.st_mtime)
{
- doc->priv->file_disk_status = FILE_CHANGED;
- /* return st.st_mtime to set it after the file has been possibly reloaded */
- t = st.st_mtime;
+ monitor_reload_file(doc);
+ doc->priv->mtime = st.st_mtime;
+ ret = TRUE;
}
g_free(locale_filename);
- return t;
-}
-
-/* Set force to force a disk check, otherwise it is ignored if there was a check
- * in the last file_prefs.disk_check_timeout seconds.
- * @return @c TRUE if the file has changed. */
-gboolean document_check_disk_status(GeanyDocument *doc, gboolean force)
-{
- gboolean ret = FALSE;
- time_t t;
-
- if (file_prefs.disk_check_timeout == 0 || G_UNLIKELY(doc == NULL))
- return FALSE;
-
- /* ignore documents that have never been saved to disk and remote files */
- if (doc->real_path == NULL || doc->priv->is_remote)
- return FALSE;
-
-#if defined(HAVE_GIO) && defined(USE_GIO_FILEMON)
- /* when we saved a file recently, we want to ignore any changes */
- if (doc->priv->file_disk_status == FILE_IGNORE)
- {
- return FALSE;
- }
-#else
- /* check the file's mtime */
- t = monitor_check_status_real(doc, force);
-#endif
-
- switch (doc->priv->file_disk_status)
- {
- case FILE_CHANGED:
- {
- monitor_reload_file(doc);
- doc->priv->mtime = t;
- ret = TRUE;
- break;
- }
- case FILE_MISSING:
- {
- monitor_resave_missing_file(doc);
- ret = TRUE;
- break;
- }
- default:
- break;
- }
-
+ old_status = doc->priv->file_disk_status;
doc->priv->file_disk_status = FILE_OK;
- /*ui_update_tab_status(doc);*/
+ if (old_status != doc->priv->file_disk_status)
+ ui_update_tab_status(doc);
return ret;
}
Modified: trunk/src/documentprivate.h
===================================================================
--- trunk/src/documentprivate.h 2009-07-08 15:47:38 UTC (rev 3932)
+++ trunk/src/documentprivate.h 2009-07-08 22:20:17 UTC (rev 3933)
@@ -40,9 +40,7 @@
typedef enum
{
FILE_OK,
- FILE_CHANGED,
- FILE_MISSING,
- FILE_CREATED_PENDING,
+ FILE_CHANGED, /* also valid for deleted files */
FILE_IGNORE
}
FileDiskStatus;
@@ -76,10 +74,9 @@
gboolean colourise_needed; /* use document.c:queue_colourise() instead */
gint line_count; /* Number of lines in the document. */
gint symbol_list_sort_mode;
- /* indicates whether a file is on a remote filesystem, works only with GIO/GVFS */
+ /* indicates whether a file is on a remote filesystem, works only with GIO/GVfs */
gboolean is_remote;
- /* File status on disk of the document, can be 'FILE_CHANGED', 'FILE_MISSING' (deleted) or
- * 'FILE_OK' if there are no known changes */
+ /* File status on disk of the document */
FileDiskStatus file_disk_status;
/* Reference to a GFileMonitor object, only used when GIO file monitoring is used. */
gpointer monitor;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Commits
mailing list