1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright (C) 2006-2007 Red Hat, Inc.
5 * SPDX-License-Identifier: LGPL-2.1-or-later
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General
18 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 * Author: Alexander Larsson <alexl@redhat.com>
25 #include "gioenumtypes.h"
26 #include "glocalfilemonitor.h"
27 #include "giomodule-priv.h"
30 #include "glocalfile.h"
31 #include "glib-private.h"
35 #define DEFAULT_RATE_LIMIT 800 * G_TIME_SPAN_MILLISECOND
36 #define VIRTUAL_CHANGES_DONE_DELAY 2 * G_TIME_SPAN_SECOND
38 /* GFileMonitorSource is a GSource responsible for emitting the changed
39 * signals in the owner-context of the GFileMonitor.
41 * It contains functionality for cross-thread queuing of events. It
42 * also handles merging of CHANGED events and emission of CHANGES_DONE
45 * We use the "priv" pointer in the external struct to store it.
47 struct _GFileMonitorSource {
51 GWeakRef instance_ref;
52 GFileMonitorFlags flags;
56 GSequence *pending_changes; /* sorted by ready time */
57 GHashTable *pending_changes_table;
62 /* PendingChange is a struct to keep track of a file that needs to have
63 * (at least) a CHANGES_DONE_HINT event sent for it in the near future.
65 * If 'dirty' is TRUE then a CHANGED event also needs to be sent.
67 * last_emission is the last time a CHANGED event was emitted. It is
68 * used to calculate the time to send the next event.
72 guint64 last_emission : 63;
76 /* QueuedEvent is a signal that will be sent immediately, as soon as the
77 * source gets a chance to dispatch. The existence of any queued event
78 * implies that the source is ready now.
82 GFileMonitorEvent event_type;
88 pending_change_get_ready_time (const PendingChange *change,
89 GFileMonitorSource *fms)
92 return change->last_emission + fms->rate_limit;
94 return change->last_emission + VIRTUAL_CHANGES_DONE_DELAY;
98 pending_change_compare_ready_time (gconstpointer a_p,
102 GFileMonitorSource *fms = user_data;
103 const PendingChange *a = a_p;
104 const PendingChange *b = b_p;
108 ready_time_a = pending_change_get_ready_time (a, fms);
109 ready_time_b = pending_change_get_ready_time (b, fms);
111 if (ready_time_a < ready_time_b)
114 return ready_time_a > ready_time_b;
118 pending_change_free (gpointer data)
120 PendingChange *change = data;
122 g_free (change->child);
124 g_slice_free (PendingChange, change);
128 queued_event_free (QueuedEvent *event)
130 g_object_unref (event->child);
132 g_object_unref (event->other);
134 g_slice_free (QueuedEvent, event);
138 g_file_monitor_source_get_ready_time (GFileMonitorSource *fms)
142 if (fms->event_queue.length)
145 iter = g_sequence_get_begin_iter (fms->pending_changes);
146 if (g_sequence_iter_is_end (iter))
149 return pending_change_get_ready_time (g_sequence_get (iter), fms);
153 g_file_monitor_source_update_ready_time (GFileMonitorSource *fms)
155 g_source_set_ready_time ((GSource *) fms, g_file_monitor_source_get_ready_time (fms));
158 static GSequenceIter *
159 g_file_monitor_source_find_pending_change (GFileMonitorSource *fms,
162 return g_hash_table_lookup (fms->pending_changes_table, child);
166 g_file_monitor_source_add_pending_change (GFileMonitorSource *fms,
170 PendingChange *change;
173 change = g_slice_new (PendingChange);
174 change->child = g_strdup (child);
175 change->last_emission = now;
176 change->dirty = FALSE;
178 iter = g_sequence_insert_sorted (fms->pending_changes, change, pending_change_compare_ready_time, fms);
179 g_hash_table_insert (fms->pending_changes_table, change->child, iter);
183 g_file_monitor_source_set_pending_change_dirty (GFileMonitorSource *fms,
186 PendingChange *change;
188 change = g_sequence_get (iter);
190 /* if it was already dirty then this change is 'uninteresting' */
194 change->dirty = TRUE;
196 g_sequence_sort_changed (iter, pending_change_compare_ready_time, fms);
202 g_file_monitor_source_get_pending_change_dirty (GFileMonitorSource *fms,
205 PendingChange *change;
207 change = g_sequence_get (iter);
209 return change->dirty;
213 g_file_monitor_source_remove_pending_change (GFileMonitorSource *fms,
217 /* must remove the hash entry first -- its key is owned by the data
218 * which will be freed when removing the sequence iter
220 g_hash_table_remove (fms->pending_changes_table, child);
221 g_sequence_remove (iter);
225 g_file_monitor_source_queue_event (GFileMonitorSource *fms,
226 GFileMonitorEvent event_type,
232 event = g_slice_new (QueuedEvent);
233 event->event_type = event_type;
234 if (child != NULL && fms->dirname != NULL)
235 event->child = g_local_file_new_from_dirname_and_basename (fms->dirname, child);
236 else if (child != NULL)
238 gchar *dirname = g_path_get_dirname (fms->filename);
239 event->child = g_local_file_new_from_dirname_and_basename (dirname, child);
242 else if (fms->dirname)
243 event->child = _g_local_file_new (fms->dirname);
244 else if (fms->filename)
245 event->child = _g_local_file_new (fms->filename);
246 event->other = other;
248 g_object_ref (other);
250 g_queue_push_tail (&fms->event_queue, event);
254 g_file_monitor_source_file_changed (GFileMonitorSource *fms,
258 GSequenceIter *pending;
259 gboolean interesting;
261 pending = g_file_monitor_source_find_pending_change (fms, child);
263 /* If there is no pending change, emit one and create a record,
264 * else: just mark the existing record as dirty.
268 g_file_monitor_source_queue_event (fms, G_FILE_MONITOR_EVENT_CHANGED, child, NULL);
269 g_file_monitor_source_add_pending_change (fms, child, now);
273 interesting = g_file_monitor_source_set_pending_change_dirty (fms, pending);
275 g_file_monitor_source_update_ready_time (fms);
281 g_file_monitor_source_file_changes_done (GFileMonitorSource *fms,
284 GSequenceIter *pending;
286 pending = g_file_monitor_source_find_pending_change (fms, child);
289 /* If it is dirty, make sure we push out the last CHANGED event */
290 if (g_file_monitor_source_get_pending_change_dirty (fms, pending))
291 g_file_monitor_source_queue_event (fms, G_FILE_MONITOR_EVENT_CHANGED, child, NULL);
293 g_file_monitor_source_queue_event (fms, G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, child, NULL);
294 g_file_monitor_source_remove_pending_change (fms, pending, child);
299 g_file_monitor_source_file_created (GFileMonitorSource *fms,
303 /* Unlikely, but if we have pending changes for this filename, make
304 * sure we flush those out first, before creating the new ones.
306 g_file_monitor_source_file_changes_done (fms, child);
308 /* Emit CREATE and add a pending changes record */
309 g_file_monitor_source_queue_event (fms, G_FILE_MONITOR_EVENT_CREATED, child, NULL);
310 g_file_monitor_source_add_pending_change (fms, child, event_time);
314 g_file_monitor_source_send_event (GFileMonitorSource *fms,
315 GFileMonitorEvent event_type,
319 /* always flush any pending changes before we queue a new event */
320 g_file_monitor_source_file_changes_done (fms, child);
321 g_file_monitor_source_queue_event (fms, event_type, child, other);
325 g_file_monitor_source_send_synthetic_created (GFileMonitorSource *fms,
328 g_file_monitor_source_file_changes_done (fms, child);
329 g_file_monitor_source_queue_event (fms, G_FILE_MONITOR_EVENT_CREATED, child, NULL);
330 g_file_monitor_source_queue_event (fms, G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, child, NULL);
333 #ifndef G_DISABLE_ASSERT
335 is_basename (const gchar *name)
337 if (name[0] == '.' && ((name[1] == '.' && name[2] == '\0') || name[1] == '\0'))
340 return !strchr (name, '/');
342 #endif /* !G_DISABLE_ASSERT */
345 g_file_monitor_source_handle_event (GFileMonitorSource *fms,
346 GFileMonitorEvent event_type,
348 const gchar *rename_to,
352 gboolean interesting = TRUE;
354 g_assert (!child || is_basename (child));
355 g_assert (!rename_to || is_basename (rename_to));
357 if (fms->basename && (!child || !g_str_equal (child, fms->basename))
358 && (!rename_to || !g_str_equal (rename_to, fms->basename)))
361 g_mutex_lock (&fms->lock);
365 * We process events even if the file monitor has already been disposed.
366 * The reason is that we must not take a reference to the instance here as
367 * destroying it from the event handling thread will lead to a deadlock when
368 * taking the lock in _ih_sub_cancel.
370 * This results in seemingly-unbounded growth of the `event_queue` with the
371 * calls to `g_file_monitor_source_queue_event()`. However, each of those sets
372 * the ready time on the #GSource, which means that it will be dispatched in
373 * a subsequent iteration of the #GMainContext it’s attached to. At that
374 * point, `g_file_monitor_source_dispatch()` will return %FALSE, and this will
375 * trigger finalisation of the source. That will clear the `event_queue`.
377 * If the source is no longer attached, this will return early to prevent
378 * unbounded queueing.
380 if (g_source_is_destroyed ((GSource *) fms))
382 g_mutex_unlock (&fms->lock);
388 case G_FILE_MONITOR_EVENT_CREATED:
389 g_assert (!other && !rename_to);
390 g_file_monitor_source_file_created (fms, child, event_time);
393 case G_FILE_MONITOR_EVENT_CHANGED:
394 g_assert (!other && !rename_to);
395 interesting = g_file_monitor_source_file_changed (fms, child, event_time);
398 case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
399 g_assert (!other && !rename_to);
400 g_file_monitor_source_file_changes_done (fms, child);
403 case G_FILE_MONITOR_EVENT_MOVED_IN:
404 g_assert (!rename_to);
405 if (fms->flags & G_FILE_MONITOR_WATCH_MOVES)
406 g_file_monitor_source_send_event (fms, G_FILE_MONITOR_EVENT_MOVED_IN, child, other);
408 g_file_monitor_source_send_synthetic_created (fms, child);
411 case G_FILE_MONITOR_EVENT_MOVED_OUT:
412 g_assert (!rename_to);
413 if (fms->flags & G_FILE_MONITOR_WATCH_MOVES)
414 g_file_monitor_source_send_event (fms, G_FILE_MONITOR_EVENT_MOVED_OUT, child, other);
415 else if (other && (fms->flags & G_FILE_MONITOR_SEND_MOVED))
416 g_file_monitor_source_send_event (fms, G_FILE_MONITOR_EVENT_MOVED, child, other);
418 g_file_monitor_source_send_event (fms, G_FILE_MONITOR_EVENT_DELETED, child, NULL);
421 case G_FILE_MONITOR_EVENT_RENAMED:
422 g_assert (!other && rename_to);
423 if (fms->flags & (G_FILE_MONITOR_WATCH_MOVES | G_FILE_MONITOR_SEND_MOVED))
426 const gchar *dirname;
427 gchar *allocated_dirname = NULL;
428 GFileMonitorEvent event;
430 event = (fms->flags & G_FILE_MONITOR_WATCH_MOVES) ? G_FILE_MONITOR_EVENT_RENAMED : G_FILE_MONITOR_EVENT_MOVED;
432 if (fms->dirname != NULL)
433 dirname = fms->dirname;
436 allocated_dirname = g_path_get_dirname (fms->filename);
437 dirname = allocated_dirname;
440 other_file = g_local_file_new_from_dirname_and_basename (dirname, rename_to);
441 g_file_monitor_source_file_changes_done (fms, rename_to);
442 g_file_monitor_source_send_event (fms, event, child, other_file);
444 g_object_unref (other_file);
445 g_free (allocated_dirname);
449 g_file_monitor_source_send_event (fms, G_FILE_MONITOR_EVENT_DELETED, child, NULL);
450 g_file_monitor_source_send_synthetic_created (fms, rename_to);
454 case G_FILE_MONITOR_EVENT_DELETED:
455 case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
456 case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
457 case G_FILE_MONITOR_EVENT_UNMOUNTED:
458 g_assert (!other && !rename_to);
459 g_file_monitor_source_send_event (fms, event_type, child, NULL);
462 case G_FILE_MONITOR_EVENT_MOVED:
463 /* was never available in this API */
465 g_assert_not_reached ();
468 g_file_monitor_source_update_ready_time (fms);
470 g_mutex_unlock (&fms->lock);
476 g_file_monitor_source_get_rate_limit (GFileMonitorSource *fms)
480 g_mutex_lock (&fms->lock);
481 rate_limit = fms->rate_limit;
482 g_mutex_unlock (&fms->lock);
488 g_file_monitor_source_set_rate_limit (GFileMonitorSource *fms,
493 g_mutex_lock (&fms->lock);
495 if (rate_limit != fms->rate_limit)
497 fms->rate_limit = rate_limit;
499 g_sequence_sort (fms->pending_changes, pending_change_compare_ready_time, fms);
500 g_file_monitor_source_update_ready_time (fms);
507 g_mutex_unlock (&fms->lock);
513 g_file_monitor_source_dispatch (GSource *source,
514 GSourceFunc callback,
517 GFileMonitorSource *fms = (GFileMonitorSource *) source;
521 GFileMonitor *instance = NULL;
523 /* make sure the monitor still exists */
524 instance = g_weak_ref_get (&fms->instance_ref);
525 if (instance == NULL)
528 now = g_source_get_time (source);
530 /* Acquire the lock once and grab all events in one go, handling the
531 * queued events first. This avoids strange possibilities in cases of
532 * long delays, such as CHANGED events coming before CREATED events.
534 * We do this by converting the applicable pending changes into queued
535 * events (after the ones already queued) and then stealing the entire
536 * event queue in one go.
538 g_mutex_lock (&fms->lock);
540 /* Create events for any pending changes that are due to fire */
541 while (!g_sequence_is_empty (fms->pending_changes))
543 GSequenceIter *iter = g_sequence_get_begin_iter (fms->pending_changes);
544 PendingChange *pending = g_sequence_get (iter);
546 /* We've gotten to a pending change that's not ready. Stop. */
547 if (pending_change_get_ready_time (pending, fms) > now)
552 /* It's time to send another CHANGED and update the record */
553 g_file_monitor_source_queue_event (fms, G_FILE_MONITOR_EVENT_CHANGED, pending->child, NULL);
554 pending->last_emission = now;
555 pending->dirty = FALSE;
557 g_sequence_sort_changed (iter, pending_change_compare_ready_time, fms);
561 /* It's time to send CHANGES_DONE and remove the pending record */
562 g_file_monitor_source_queue_event (fms, G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT, pending->child, NULL);
563 g_file_monitor_source_remove_pending_change (fms, iter, pending->child);
567 /* Steal the queue */
568 memcpy (&event_queue, &fms->event_queue, sizeof event_queue);
569 memset (&fms->event_queue, 0, sizeof fms->event_queue);
571 g_file_monitor_source_update_ready_time (fms);
573 g_mutex_unlock (&fms->lock);
574 g_clear_object (&instance);
576 /* We now have our list of events to deliver */
577 while ((event = g_queue_pop_head (&event_queue)))
579 /* an event handler could destroy 'instance', so check each time */
580 instance = g_weak_ref_get (&fms->instance_ref);
581 if (instance != NULL)
582 g_file_monitor_emit_event (instance, event->child, event->other, event->event_type);
584 g_clear_object (&instance);
585 queued_event_free (event);
592 g_file_monitor_source_dispose (GFileMonitorSource *fms)
598 g_mutex_lock (&fms->lock);
600 g_hash_table_iter_init (&iter, fms->pending_changes_table);
601 while (g_hash_table_iter_next (&iter, NULL, &seqiter))
603 g_hash_table_iter_remove (&iter);
604 g_sequence_remove (seqiter);
607 while ((event = g_queue_pop_head (&fms->event_queue)))
608 queued_event_free (event);
610 g_assert (g_sequence_is_empty (fms->pending_changes));
611 g_assert (g_hash_table_size (fms->pending_changes_table) == 0);
612 g_assert (fms->event_queue.length == 0);
613 g_weak_ref_set (&fms->instance_ref, NULL);
615 g_file_monitor_source_update_ready_time (fms);
617 g_source_destroy ((GSource *) fms);
619 g_mutex_unlock (&fms->lock);
623 g_file_monitor_source_finalize (GSource *source)
625 GFileMonitorSource *fms = (GFileMonitorSource *) source;
627 /* should already have been cleared in dispose of the monitor */
628 g_assert (g_weak_ref_get (&fms->instance_ref) == NULL);
629 g_weak_ref_clear (&fms->instance_ref);
631 g_assert (g_sequence_is_empty (fms->pending_changes));
632 g_assert (g_hash_table_size (fms->pending_changes_table) == 0);
633 g_assert (fms->event_queue.length == 0);
635 g_hash_table_unref (fms->pending_changes_table);
636 g_sequence_free (fms->pending_changes);
638 g_free (fms->dirname);
639 g_free (fms->basename);
640 g_free (fms->filename);
642 g_mutex_clear (&fms->lock);
646 str_hash0 (gconstpointer str)
648 return str ? g_str_hash (str) : 0;
652 str_equal0 (gconstpointer a,
655 return g_strcmp0 (a, b) == 0;
658 static GFileMonitorSource *
659 g_file_monitor_source_new (gpointer instance,
660 const gchar *filename,
661 gboolean is_directory,
662 GFileMonitorFlags flags)
664 static GSourceFuncs source_funcs = {
666 g_file_monitor_source_dispatch,
667 g_file_monitor_source_finalize,
670 GFileMonitorSource *fms;
673 source = g_source_new (&source_funcs, sizeof (GFileMonitorSource));
674 fms = (GFileMonitorSource *) source;
676 g_source_set_static_name (source, "GFileMonitorSource");
678 g_mutex_init (&fms->lock);
679 g_weak_ref_init (&fms->instance_ref, instance);
680 fms->pending_changes = g_sequence_new (pending_change_free);
681 fms->pending_changes_table = g_hash_table_new (str_hash0, str_equal0);
682 fms->rate_limit = DEFAULT_RATE_LIMIT;
687 fms->dirname = g_strdup (filename);
688 fms->basename = NULL;
689 fms->filename = NULL;
691 else if (flags & G_FILE_MONITOR_WATCH_HARD_LINKS)
694 fms->basename = NULL;
695 fms->filename = g_strdup (filename);
699 fms->dirname = g_path_get_dirname (filename);
700 fms->basename = g_path_get_basename (filename);
701 fms->filename = NULL;
707 G_DEFINE_ABSTRACT_TYPE (GLocalFileMonitor, g_local_file_monitor, G_TYPE_FILE_MONITOR)
715 g_local_file_monitor_get_property (GObject *object, guint prop_id,
716 GValue *value, GParamSpec *pspec)
718 GLocalFileMonitor *monitor = G_LOCAL_FILE_MONITOR (object);
721 g_assert (prop_id == PROP_RATE_LIMIT);
723 rate_limit = g_file_monitor_source_get_rate_limit (monitor->source);
724 rate_limit /= G_TIME_SPAN_MILLISECOND;
726 g_value_set_int (value, rate_limit);
730 g_local_file_monitor_set_property (GObject *object, guint prop_id,
731 const GValue *value, GParamSpec *pspec)
733 GLocalFileMonitor *monitor = G_LOCAL_FILE_MONITOR (object);
736 g_assert (prop_id == PROP_RATE_LIMIT);
738 rate_limit = g_value_get_int (value);
739 rate_limit *= G_TIME_SPAN_MILLISECOND;
741 if (g_file_monitor_source_set_rate_limit (monitor->source, rate_limit))
742 g_object_notify (object, "rate-limit");
747 g_local_file_monitor_mounts_changed (GUnixMountMonitor *mount_monitor,
750 GLocalFileMonitor *local_monitor = user_data;
751 GUnixMountEntry *mount;
755 /* Emulate unmount detection */
756 mount = g_unix_mount_at (local_monitor->source->dirname, NULL);
758 is_mounted = mount != NULL;
761 g_unix_mount_free (mount);
763 if (local_monitor->was_mounted != is_mounted)
765 if (local_monitor->was_mounted && !is_mounted)
767 file = g_file_new_for_path (local_monitor->source->dirname);
768 g_file_monitor_emit_event (G_FILE_MONITOR (local_monitor), file, NULL, G_FILE_MONITOR_EVENT_UNMOUNTED);
769 g_object_unref (file);
771 local_monitor->was_mounted = is_mounted;
777 g_local_file_monitor_start (GLocalFileMonitor *local_monitor,
778 const gchar *filename,
779 gboolean is_directory,
780 GFileMonitorFlags flags,
781 GMainContext *context)
783 GLocalFileMonitorClass *class = G_LOCAL_FILE_MONITOR_GET_CLASS (local_monitor);
784 GFileMonitorSource *source;
786 g_return_if_fail (G_IS_LOCAL_FILE_MONITOR (local_monitor));
788 g_assert (!local_monitor->source);
790 source = g_file_monitor_source_new (local_monitor, filename, is_directory, flags);
791 local_monitor->source = source; /* owns the ref */
793 if (is_directory && !class->mount_notify && (flags & G_FILE_MONITOR_WATCH_MOUNTS))
796 /*claim everything was mounted */
797 local_monitor->was_mounted = TRUE;
799 GUnixMountEntry *mount;
801 /* Emulate unmount detection */
803 mount = g_unix_mount_at (local_monitor->source->dirname, NULL);
805 local_monitor->was_mounted = mount != NULL;
808 g_unix_mount_free (mount);
810 local_monitor->mount_monitor = g_unix_mount_monitor_get ();
811 g_signal_connect_object (local_monitor->mount_monitor, "mounts-changed",
812 G_CALLBACK (g_local_file_monitor_mounts_changed), local_monitor,
817 g_source_attach ((GSource *) source, context);
819 G_LOCAL_FILE_MONITOR_GET_CLASS (local_monitor)->start (local_monitor,
820 source->dirname, source->basename, source->filename,
825 g_local_file_monitor_dispose (GObject *object)
827 GLocalFileMonitor *local_monitor = G_LOCAL_FILE_MONITOR (object);
829 g_file_monitor_source_dispose (local_monitor->source);
831 G_OBJECT_CLASS (g_local_file_monitor_parent_class)->dispose (object);
835 g_local_file_monitor_finalize (GObject *object)
837 GLocalFileMonitor *local_monitor = G_LOCAL_FILE_MONITOR (object);
839 g_source_unref ((GSource *) local_monitor->source);
841 G_OBJECT_CLASS (g_local_file_monitor_parent_class)->finalize (object);
845 g_local_file_monitor_init (GLocalFileMonitor* local_monitor)
849 static void g_local_file_monitor_class_init (GLocalFileMonitorClass *class)
851 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
853 gobject_class->get_property = g_local_file_monitor_get_property;
854 gobject_class->set_property = g_local_file_monitor_set_property;
855 gobject_class->dispose = g_local_file_monitor_dispose;
856 gobject_class->finalize = g_local_file_monitor_finalize;
858 g_object_class_override_property (gobject_class, PROP_RATE_LIMIT, "rate-limit");
861 static GLocalFileMonitor *
862 g_local_file_monitor_new (gboolean is_remote_fs,
863 gboolean is_directory,
866 GType type = G_TYPE_INVALID;
869 type = _g_io_module_get_default_type (G_NFS_FILE_MONITOR_EXTENSION_POINT_NAME,
870 "GIO_USE_FILE_MONITOR",
871 G_STRUCT_OFFSET (GLocalFileMonitorClass, is_supported));
873 /* Fallback rather to poll file monitor for remote files, see gfile.c. */
874 if (type == G_TYPE_INVALID && (!is_remote_fs || is_directory))
875 type = _g_io_module_get_default_type (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME,
876 "GIO_USE_FILE_MONITOR",
877 G_STRUCT_OFFSET (GLocalFileMonitorClass, is_supported));
879 if (type == G_TYPE_INVALID)
881 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
882 _("Unable to find default local file monitor type"));
886 return g_object_new (type, NULL);
890 g_local_file_monitor_new_for_path (const gchar *pathname,
891 gboolean is_directory,
892 GFileMonitorFlags flags,
895 GLocalFileMonitor *monitor;
896 gboolean is_remote_fs;
898 is_remote_fs = g_local_file_is_nfs_home (pathname);
900 monitor = g_local_file_monitor_new (is_remote_fs, is_directory, error);
903 g_local_file_monitor_start (monitor, pathname, is_directory, flags, g_main_context_get_thread_default ());
905 return G_FILE_MONITOR (monitor);
909 g_local_file_monitor_new_in_worker (const gchar *pathname,
910 gboolean is_directory,
911 GFileMonitorFlags flags,
912 GFileMonitorCallback callback,
914 GClosureNotify destroy_user_data,
917 GLocalFileMonitor *monitor;
918 gboolean is_remote_fs;
920 is_remote_fs = g_local_file_is_nfs_home (pathname);
922 monitor = g_local_file_monitor_new (is_remote_fs, is_directory, error);
927 g_signal_connect_data (monitor, "changed", G_CALLBACK (callback),
928 user_data, destroy_user_data, G_CONNECT_DEFAULT);
930 g_local_file_monitor_start (monitor, pathname, is_directory, flags, GLIB_PRIVATE_CALL(g_get_worker_context) ());
933 return G_FILE_MONITOR (monitor);