X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgfilemonitor.c;h=c81f6fcb5bf4c9f98dbd6b63d286046e78e0eb0d;hb=51fac05d73f8363de821eb0d6940dedca13a8c0f;hp=6bad280477ae63ee8b458bbc3e2b9be526664a07;hpb=59f1f5465571bac403357b59cf7bfe2723356a37;p=platform%2Fupstream%2Fglib.git
diff --git a/gio/gfilemonitor.c b/gio/gfilemonitor.c
index 6bad280..c81f6fc 100644
--- a/gio/gfilemonitor.c
+++ b/gio/gfilemonitor.c
@@ -13,9 +13,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Public License along with this library; if not, see .
*
* Author: Alexander Larsson
*/
@@ -47,9 +45,9 @@ static void file_change_free (FileChange *change);
*
* To get informed about changes to the file or directory you are
* monitoring, connect to the #GFileMonitor::changed signal. The
- * signal will be emitted in the thread-default main
- * context of the thread that the monitor was created in
+ * signal will be emitted in the
+ * [thread-default main context][g-main-context-push-thread-default]
+ * of the thread that the monitor was created in
* (though if the global default main context is blocked, this may
* cause notifications to be blocked even if the thread-default
* context is still running).
@@ -62,11 +60,6 @@ enum {
LAST_SIGNAL
};
-/* work around a limitation of the aliasing foo */
-#undef g_file_monitor
-
-G_DEFINE_ABSTRACT_TYPE (GFileMonitor, g_file_monitor, G_TYPE_OBJECT);
-
typedef struct {
GFile *file;
guint32 last_sent_change_time; /* 0 == not sent */
@@ -81,6 +74,7 @@ struct _GFileMonitorPrivate {
/* Rate limiting change events */
GHashTable *rate_limiter;
+ GMutex mutex;
GSource *pending_file_change_source;
GSList *pending_file_changes; /* FileChange */
@@ -93,9 +87,15 @@ struct _GFileMonitorPrivate {
enum {
PROP_0,
PROP_RATE_LIMIT,
- PROP_CANCELLED
+ PROP_CANCELLED,
+ PROP_CONTEXT
};
+/* work around a limitation of the aliasing foo */
+#undef g_file_monitor
+
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GFileMonitor, g_file_monitor, G_TYPE_OBJECT)
+
static void
g_file_monitor_set_property (GObject *object,
guint prop_id,
@@ -112,6 +112,12 @@ g_file_monitor_set_property (GObject *object,
g_file_monitor_set_rate_limit (monitor, g_value_get_int (value));
break;
+ case PROP_CONTEXT:
+ monitor->priv->context = g_value_dup_boxed (value);
+ if (monitor->priv->context == NULL)
+ monitor->priv->context = g_main_context_ref_thread_default ();
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -176,6 +182,7 @@ g_file_monitor_finalize (GObject *object)
g_hash_table_destroy (monitor->priv->rate_limiter);
g_main_context_unref (monitor->priv->context);
+ g_mutex_clear (&monitor->priv->mutex);
G_OBJECT_CLASS (g_file_monitor_parent_class)->finalize (object);
}
@@ -195,8 +202,7 @@ g_file_monitor_dispose (GObject *object)
g_source_unref (priv->pending_file_change_source);
priv->pending_file_change_source = NULL;
}
- g_slist_foreach (priv->pending_file_changes, (GFunc) file_change_free, NULL);
- g_slist_free (priv->pending_file_changes);
+ g_slist_free_full (priv->pending_file_changes, (GDestroyNotify) file_change_free);
priv->pending_file_changes = NULL;
/* Make sure we cancel on last unref */
@@ -209,9 +215,7 @@ static void
g_file_monitor_class_init (GFileMonitorClass *klass)
{
GObjectClass *object_class;
-
- g_type_class_add_private (klass, sizeof (GFileMonitorPrivate));
-
+
object_class = G_OBJECT_CLASS (klass);
object_class->finalize = g_file_monitor_finalize;
object_class->dispose = g_file_monitor_dispose;
@@ -222,13 +226,13 @@ g_file_monitor_class_init (GFileMonitorClass *klass)
* GFileMonitor::changed:
* @monitor: a #GFileMonitor.
* @file: a #GFile.
- * @other_file: a #GFile or #NULL.
+ * @other_file: (allow-none): a #GFile or #NULL.
* @event_type: a #GFileMonitorEvent.
*
* Emitted when @file has been changed.
*
* If using #G_FILE_MONITOR_SEND_MOVED flag and @event_type is
- * #G_FILE_MONITOR_SEND_MOVED, @file will be set to a #GFile containing the
+ * #G_FILE_MONITOR_EVENT_MOVED, @file will be set to a #GFile containing the
* old path, and @other_file will be set to a #GFile containing the new path.
*
* In all the other cases, @other_file will be set to #NULL.
@@ -261,18 +265,24 @@ g_file_monitor_class_init (GFileMonitorClass *klass)
FALSE,
G_PARAM_READABLE|
G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
+
+ g_object_class_install_property (object_class,
+ PROP_CONTEXT,
+ g_param_spec_boxed ("context",
+ P_("Context"),
+ P_("The main context to dispatch from"),
+ G_TYPE_MAIN_CONTEXT, G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
}
static void
g_file_monitor_init (GFileMonitor *monitor)
{
- monitor->priv = G_TYPE_INSTANCE_GET_PRIVATE (monitor,
- G_TYPE_FILE_MONITOR,
- GFileMonitorPrivate);
+ monitor->priv = g_file_monitor_get_instance_private (monitor);
monitor->priv->rate_limit_msec = DEFAULT_RATE_LIMIT_MSECS;
monitor->priv->rate_limiter = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal,
NULL, (GDestroyNotify) rate_limiter_free);
- monitor->priv->context = g_main_context_ref_thread_default ();
+ g_mutex_init (&monitor->priv->mutex);
}
/**
@@ -375,7 +385,8 @@ emit_cb (gpointer data)
{
GFileMonitor *monitor = G_FILE_MONITOR (data);
GSList *pending, *iter;
-
+
+ g_mutex_lock (&monitor->priv->mutex);
pending = g_slist_reverse (monitor->priv->pending_file_changes);
monitor->priv->pending_file_changes = NULL;
if (monitor->priv->pending_file_change_source)
@@ -383,11 +394,13 @@ emit_cb (gpointer data)
g_source_unref (monitor->priv->pending_file_change_source);
monitor->priv->pending_file_change_source = NULL;
}
+ g_mutex_unlock (&monitor->priv->mutex);
g_object_ref (monitor);
for (iter = pending; iter; iter = iter->next)
{
FileChange *change = iter->data;
+
g_signal_emit (monitor, signals[CHANGED], 0,
change->child, change->other_file, change->event_type);
file_change_free (change);
@@ -419,6 +432,7 @@ emit_in_idle (GFileMonitor *monitor,
change->other_file = NULL;
change->event_type = event_type;
+ g_mutex_lock (&monitor->priv->mutex);
if (!priv->pending_file_change_source)
{
source = g_idle_source_new ();
@@ -429,10 +443,12 @@ emit_in_idle (GFileMonitor *monitor,
* pending idles.
*/
g_source_set_callback (source, emit_cb, monitor, NULL);
+ g_source_set_name (source, "[gio] emit_cb");
g_source_attach (source, monitor->priv->context);
}
/* We reverse this in the processor */
priv->pending_file_changes = g_slist_prepend (priv->pending_file_changes, change);
+ g_mutex_unlock (&monitor->priv->mutex);
}
static guint32
@@ -655,9 +671,8 @@ update_rate_limiter_timeout (GFileMonitor *monitor,
* has taken place. Should be called from file monitor
* implementations only.
*
- * The signal will be emitted from an idle handler (in the thread-default main
- * context).
+ * The signal will be emitted from an idle handler (in the
+ * [thread-default main context][g-main-context-push-thread-default]).
**/
void
g_file_monitor_emit_event (GFileMonitor *monitor,