mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 03:16:17 +01:00
Send CHANGES_DONE_HINT on file moves if no IN_CLOSE_WRITE is emitted
This patch makes GFileMonitor to emit EVENT_CHANGES_DONE_HINT when EVENT_CREATED is emitted but the file is not opened for writing. On file moves across different mounted volumes, inotify will always emit IN_CREATE and IN_CLOSE_WRITE (plus other events). This translates into GIO's _EVENT_CREATED and _EVENT_CHANGES_DONE_HINT. On file moves across the same mounted volumes, inotify will emit IN_MOVED_FROM/IN_MOVED_TO which will be translated into _EVENT_DELETED/_EVENT_CREATED GIO's side. No _EVENT_CHANGES_DONE_HINT is emited afterwards. Under such circumstances a file indexer does not know when actually the file is ready to be indexed, either waiting too much or triggering the indexing twice. On small devices it's not advisable. Bug: https://bugzilla.gnome.org/show_bug.cgi?id=640077 Bug-NB: NB#219982 Reviewed-by: Simon McVittie <simon.mcvittie@collabora.co.uk> Reviewed-by: Tomas Bzatek <tbzatek@redhat.com>
This commit is contained in:
parent
83d0c8a739
commit
fd1e9938b3
@ -190,6 +190,30 @@ ih_event_callback (ik_event_t *event,
|
|||||||
g_file_monitor_emit_event (G_FILE_MONITOR (sub->user_data),
|
g_file_monitor_emit_event (G_FILE_MONITOR (sub->user_data),
|
||||||
child, other, eflags);
|
child, other, eflags);
|
||||||
|
|
||||||
|
/* For paired moves or moves whose mask has been changed from IN_MOVED_TO to
|
||||||
|
* IN_CREATE, notify also that it's probably the last change to the file,
|
||||||
|
* emitting CHANGES_DONE_HINT.
|
||||||
|
* The first (first part of the if's guard below) is the case of a normal
|
||||||
|
* move within the monitored tree and in the same mounted volume.
|
||||||
|
* The latter (second part of the guard) is the case of a move within the
|
||||||
|
* same mounted volume, but from a not monitored directory.
|
||||||
|
*
|
||||||
|
* It's not needed in cases like moves across mounted volumes as the IN_CREATE
|
||||||
|
* will be followed by a IN_MODIFY and IN_CLOSE_WRITE events.
|
||||||
|
* Also not needed if sub->pair_moves is set as EVENT_MOVED will be emitted
|
||||||
|
* instead of EVENT_CREATED which implies no further modification will be
|
||||||
|
* applied to the file
|
||||||
|
* See: https://bugzilla.gnome.org/show_bug.cgi?id=640077
|
||||||
|
*/
|
||||||
|
if ((!sub->pair_moves &&
|
||||||
|
event->is_second_in_pair && (event->mask & IN_MOVED_TO)) ||
|
||||||
|
(!ih_event_is_paired_move (event) &&
|
||||||
|
(event->original_mask & IN_MOVED_TO) && (event->mask & IN_CREATE)))
|
||||||
|
{
|
||||||
|
g_file_monitor_emit_event (G_FILE_MONITOR (sub->user_data),
|
||||||
|
child, NULL, G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT);
|
||||||
|
}
|
||||||
|
|
||||||
g_object_unref (child);
|
g_object_unref (child);
|
||||||
if (other)
|
if (other)
|
||||||
g_object_unref (other);
|
g_object_unref (other);
|
||||||
|
@ -516,6 +516,7 @@ ik_pair_events (ik_event_internal_t *event1,
|
|||||||
/* Pair the internal structures and the ik_event_t structures */
|
/* Pair the internal structures and the ik_event_t structures */
|
||||||
event1->pair = event2;
|
event1->pair = event2;
|
||||||
event1->event->pair = event2->event;
|
event1->event->pair = event2->event;
|
||||||
|
event2->event->is_second_in_pair = TRUE;
|
||||||
|
|
||||||
if (g_timeval_lt (&event1->hold_until, &event2->hold_until))
|
if (g_timeval_lt (&event1->hold_until, &event2->hold_until))
|
||||||
event1->hold_until = event2->hold_until;
|
event1->hold_until = event2->hold_until;
|
||||||
@ -634,7 +635,8 @@ ik_process_events (void)
|
|||||||
* the event masks */
|
* the event masks */
|
||||||
/* Changeing MOVED_FROM to DELETE and MOVED_TO to create lets us make
|
/* Changeing MOVED_FROM to DELETE and MOVED_TO to create lets us make
|
||||||
* the gaurantee that you will never see a non-matched MOVE event */
|
* the gaurantee that you will never see a non-matched MOVE event */
|
||||||
|
event->event->original_mask = event->event->mask;
|
||||||
|
|
||||||
if (event->event->mask & IN_MOVED_FROM)
|
if (event->event->mask & IN_MOVED_FROM)
|
||||||
{
|
{
|
||||||
event->event->mask = IN_DELETE|(event->event->mask & IN_ISDIR);
|
event->event->mask = IN_DELETE|(event->event->mask & IN_ISDIR);
|
||||||
|
@ -26,9 +26,17 @@
|
|||||||
typedef struct ik_event_s {
|
typedef struct ik_event_s {
|
||||||
gint32 wd;
|
gint32 wd;
|
||||||
guint32 mask;
|
guint32 mask;
|
||||||
|
guint32 original_mask;
|
||||||
guint32 cookie;
|
guint32 cookie;
|
||||||
guint32 len;
|
guint32 len;
|
||||||
char * name;
|
char * name;
|
||||||
|
/* TRUE if this event is the last element of a pair
|
||||||
|
* (e.g., MOVE_TO in a pair of MOVE_FROM, MOVE_TO events) */
|
||||||
|
gboolean is_second_in_pair;
|
||||||
|
/* if event1 and event2 are two paired events
|
||||||
|
* (e.g., MOVE_FROM and MOVE_TO events related to the same file move),
|
||||||
|
* then event1->pair == event2 and event2->pair == NULL.
|
||||||
|
* It will result also in event1->pair->is_second_in_pair == TRUE */
|
||||||
struct ik_event_s *pair;
|
struct ik_event_s *pair;
|
||||||
} ik_event_t;
|
} ik_event_t;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user