[nautilus-actions] Review notifications bufferization
- From: Pierre Wieser <pwieser src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus-actions] Review notifications bufferization
- Date: Mon, 9 Aug 2010 22:11:02 +0000 (UTC)
commit 9119b5cd6d6e16b71197eedf36b5aa675c2eb5af
Author: Pierre Wieser <pwieser trychlos org>
Date: Tue Aug 10 00:09:54 2010 +0200
Review notifications bufferization
ChangeLog | 17 +++++++
src/core/na-ipivot-consumer.c | 81 +++++++++++++++++++------------
src/core/na-ipivot-consumer.h | 2 +-
src/core/na-pivot.c | 18 ++++---
src/io-desktop/nadp-desktop-provider.c | 24 ++++------
src/io-gconf/nagp-gconf-provider.c | 40 ++++++++++------
src/nact/nact-main-menubar-file.c | 8 ++-
src/nact/nact-main-window.c | 2 +
src/plugin-menu/nautilus-actions.c | 2 +
9 files changed, 123 insertions(+), 71 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 43faa3c..338059c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,22 @@
2010-08-09 Pierre Wieser <pwieser trychlos org>
+ Review notification bufferization.
+
+ * src/core/na-ipivot-consumer.c:
+ * src/core/na-ipivot-consumer.h
+ (na_ipivot_consumer_delay_notify): Removed function.
+ (na_ipivot_consumer_allow_notify): New function.
+
+ * src/nact/nact-main-menubar-file.c (nact_main_menubar_file_save_items):
+ * src/nact/nact-main-window.c (instance_init):
+ * src/plugin-menu/nautilus-actions.c (instance_init):
+ Updated accordingly.
+
+ * src/core/na-pivot.c (on_item_changed_timeout):
+ * src/io-desktop/nadp-desktop-provider.c (on_monitor_timeout):
+ * src/io-gconf/nagp-gconf-provider.c (config_path_changed_trigger_interface):
+ Review the code.
+
Fix XML import of localized vs. unlocalized profile label.
* src/api/na-ifactory-object-data.h:
diff --git a/src/core/na-ipivot-consumer.c b/src/core/na-ipivot-consumer.c
index 63d9c16..04c609d 100644
--- a/src/core/na-ipivot-consumer.c
+++ b/src/core/na-ipivot-consumer.c
@@ -128,34 +128,48 @@ interface_base_finalize( NAIPivotConsumerInterface *klass )
}
/**
- * na_ipivot_consumer_delay_notify:
+ * na_ipivot_consumer_allow_notify:
* @instance: the #NAIPivotConsumer instance.
+ * @allow: whether notifications are allowed for this consumer.
+ * @delay: delay in msec before actually allow the notifications;
+ * only considered when @allow is %TRUE.
*
- * Informs the #NAIPivotconsumer instance that the next notification
- * message should only be handled if a short delay has expired. This
- * let us to no be polluted by notifications that we create ourselves
- * (e.g. when saving actions).
+ * Set the notification flag for this consumer.
+ *
+ * When @allow is %FALSE, then all notifications from #NAPivot are blocked.
+ *
+ * Allowing notifications with a delay is useful in particular when saving
+ * the items list from NACT. As both I/O providers and NAPivot bufferize
+ * their individual notifications, NAIPivot consumers will only be
+ * triggered themselves after the sum of all burst timeouts.
+ * So, we reauthorize notifications at end of save code, with a delay
+ * which _should_ be greater that this sum...
*/
void
-na_ipivot_consumer_delay_notify( NAIPivotConsumer *instance )
+na_ipivot_consumer_allow_notify( NAIPivotConsumer *instance, gboolean allow, guint delay )
{
- static const gchar *thisfn = "na_ipivot_consumer_delay_notify";
- GTimeVal *last_delay;
+ static const gchar *thisfn = "na_ipivot_consumer_allow_notify";
+ GTimeVal *tval;
g_return_if_fail( NA_IS_IPIVOT_CONSUMER( instance ));
if( st_initialized && !st_finalized ){
- g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
+ g_debug( "%s: instance=%p, allow=%s, delay=%d", thisfn, ( void * ) instance, allow ? "True":"False", delay );
- last_delay = ( GTimeVal * ) g_object_get_data( G_OBJECT( instance ), "na-ipivot-consumer-delay-notify" );
+ g_object_set_data( G_OBJECT( instance ), "na-ipivot-consumer-allow-notify", GUINT_TO_POINTER( allow ));
- if( !last_delay ){
- last_delay = g_new0( GTimeVal, 1 );
- g_object_set_data( G_OBJECT( instance ), "na-ipivot-consumer-delay-notify", last_delay );
- }
+ if( allow ){
+ tval = ( GTimeVal * ) g_object_get_data( G_OBJECT( instance ), "na-ipivot-consumer-delay-notify" );
- g_get_current_time( last_delay );
+ if( !tval ){
+ tval = g_new0( GTimeVal, 1 );
+ g_object_set_data( G_OBJECT( instance ), "na-ipivot-consumer-delay-notify", tval );
+ }
+
+ g_get_current_time( tval );
+ g_time_val_add( tval, 1000*delay );
+ }
}
}
@@ -175,8 +189,11 @@ na_ipivot_consumer_notify_of_autosave_changed( NAIPivotConsumer *instance, gbool
if( st_initialized && !st_finalized ){
- if( NA_IPIVOT_CONSUMER_GET_INTERFACE( instance )->on_autosave_changed ){
- NA_IPIVOT_CONSUMER_GET_INTERFACE( instance )->on_autosave_changed( instance, enabled, period );
+ if( is_notify_allowed( instance )){
+
+ if( NA_IPIVOT_CONSUMER_GET_INTERFACE( instance )->on_autosave_changed ){
+ NA_IPIVOT_CONSUMER_GET_INTERFACE( instance )->on_autosave_changed( instance, enabled, period );
+ }
}
}
}
@@ -309,20 +326,22 @@ void na_ipivot_consumer_notify_of_mandatory_prefs_changed( NAIPivotConsumer *ins
static gboolean
is_notify_allowed( const NAIPivotConsumer *instance )
{
- static const gchar *thisfn = "na_ipivot_consumer_is_notify_allowed";
- GTimeVal *last_delay;
- GTimeVal now;
- gulong ecart;
-
- last_delay = ( GTimeVal * ) g_object_get_data( G_OBJECT( instance ), "na-ipivot-consumer-delay-notify" );
- if( !last_delay ){
- return( TRUE );
- }
+ gboolean allowed;
+ GTimeVal *tval, now;
+ glong ecart;
+
+ allowed = ( gboolean ) GPOINTER_TO_UINT( g_object_get_data( G_OBJECT( instance ), "na-ipivot-consumer-allow-notify" ));
- g_get_current_time( &now );
- ecart = 1000000 * ( now.tv_sec - last_delay->tv_sec );
- ecart += now.tv_usec - last_delay->tv_usec;
+ if( allowed ){
+ tval = ( GTimeVal * ) g_object_get_data( G_OBJECT( instance ), "na-ipivot-consumer-delay-notify" );
+
+ if( tval ){
+ g_get_current_time( &now );
+ ecart = G_USEC_PER_SEC * ( now.tv_sec - tval->tv_sec );
+ ecart += now.tv_usec - tval->tv_usec;
+ allowed = ( ecart > 0 );
+ }
+ }
- g_debug( "%s: ecart=%ld", thisfn, ecart );
- return( ecart > 2000000 );
+ return( allowed );
}
diff --git a/src/core/na-ipivot-consumer.h b/src/core/na-ipivot-consumer.h
index b4af8a2..be36c58 100644
--- a/src/core/na-ipivot-consumer.h
+++ b/src/core/na-ipivot-consumer.h
@@ -129,7 +129,7 @@ typedef struct {
GType na_ipivot_consumer_get_type( void );
-void na_ipivot_consumer_delay_notify( NAIPivotConsumer *instance );
+void na_ipivot_consumer_allow_notify( NAIPivotConsumer *instance, gboolean allow, guint delay );
void na_ipivot_consumer_notify_of_autosave_changed ( NAIPivotConsumer *instance, gboolean enabled, guint period );
void na_ipivot_consumer_notify_of_create_root_menu_changed( NAIPivotConsumer *instance, gboolean enabled );
diff --git a/src/core/na-pivot.c b/src/core/na-pivot.c
index 16f5f7b..22a3a79 100644
--- a/src/core/na-pivot.c
+++ b/src/core/na-pivot.c
@@ -91,8 +91,7 @@ enum {
static GObjectClass *st_parent_class = NULL;
-static gint st_timeout_msec = 100;
-static gint st_timeout_usec = 100000;
+static gint st_burst_timeout = 200; /* burst timeout in msec */
static GType register_type( void );
static void class_init( NAPivotClass *klass );
@@ -622,15 +621,14 @@ na_pivot_item_changed_handler( NAIIOProvider *provider, const gchar *id, NAPivot
if( !pivot->private->event_source_id ){
pivot->private->event_source_id =
- g_timeout_add( st_timeout_msec, ( GSourceFunc ) on_item_changed_timeout, pivot );
+ g_timeout_add( st_burst_timeout, ( GSourceFunc ) on_item_changed_timeout, pivot );
}
}
}
/*
* this timer is set when we receive the first event of a serie
- * we continue to loop until last event is at least one half of a
- * second old
+ * we continue to loop until last event is older that our burst timeout
*
* there is no race condition here as we are not multithreaded
* or .. is there ?
@@ -642,17 +640,21 @@ on_item_changed_timeout( NAPivot *pivot )
GTimeVal now;
gulong diff;
GList *ic;
+ gulong timeout_usec = 1000*st_burst_timeout;
g_return_val_if_fail( NA_IS_PIVOT( pivot ), FALSE );
- g_debug( "%s: pivot=%p", thisfn, pivot );
-
g_get_current_time( &now );
diff = time_val_diff( &now, &pivot->private->last_event );
- if( diff < st_timeout_usec ){
+ if( diff < timeout_usec ){
return( TRUE );
}
+ /* last individual notification is older that the st_burst_timeout
+ * so triggers the NAIIOProvider interface and destroys this timeout
+ */
+ g_debug( "%s: triggering NAIPivotConsumer interfaces", thisfn );
+
if( pivot->private->automatic_reload ){
na_pivot_load_items( pivot );
}
diff --git a/src/io-desktop/nadp-desktop-provider.c b/src/io-desktop/nadp-desktop-provider.c
index 0a198b5..6caefd3 100644
--- a/src/io-desktop/nadp-desktop-provider.c
+++ b/src/io-desktop/nadp-desktop-provider.c
@@ -54,8 +54,7 @@ extern NAIExporterFormat nadp_formats[];
static GType st_module_type = 0;
static GObjectClass *st_parent_class = NULL;
-static guint st_timeout_msec = 100;
-static guint st_timeout_usec = 100000;
+static guint st_burst_timeout = 100; /* burst timeout in msec */
static void class_init( NadpDesktopProviderClass *klass );
static void instance_init( GTypeInstance *instance, gpointer klass );
@@ -351,21 +350,15 @@ nadp_desktop_provider_add_monitor( NadpDesktopProvider *provider, const gchar *d
void
nadp_desktop_provider_on_monitor_event( NadpDesktopProvider *provider )
{
- static const gchar *thisfn = "nadp_desktop_provider_on_monitor_event";
- GTimeVal now;
-
g_return_if_fail( NADP_IS_DESKTOP_PROVIDER( provider ));
if( !provider->private->dispose_has_run ){
- g_get_current_time( &now );
- g_debug( "%s: time=%ld.%ld", thisfn, now.tv_sec, now.tv_usec );
-
g_get_current_time( &provider->private->last_event );
if( !provider->private->event_source_id ){
provider->private->event_source_id =
- g_timeout_add( st_timeout_msec, ( GSourceFunc ) on_monitor_timeout, provider );
+ g_timeout_add( st_burst_timeout, ( GSourceFunc ) on_monitor_timeout, provider );
}
}
}
@@ -395,17 +388,20 @@ on_monitor_timeout( NadpDesktopProvider *provider )
static const gchar *thisfn = "nadp_desktop_provider_on_monitor_timeout";
GTimeVal now;
gulong diff;
-
- g_debug( "%s", thisfn );
+ gulong timeout_usec = 1000*st_burst_timeout;
g_get_current_time( &now );
diff = time_val_diff( &now, &provider->private->last_event );
- if( diff < st_timeout_usec ){
- g_debug( "%s: unexpired timeout: returning True", thisfn );
+ if( diff < timeout_usec ){
return( TRUE );
}
- g_debug( "%s: expired timeout: advertising IIOProvider, returning False", thisfn );
+ /* last individual notification is older that the st_burst_timeout
+ * so triggers the NAIIOProvider interface and destroys this timeout
+ */
+ g_debug( "%s: triggering NAIIOProvider interface for provider=%p (%s)",
+ thisfn, ( void * ) provider, G_OBJECT_TYPE_NAME( provider ));
+
na_iio_provider_item_changed( NA_IIO_PROVIDER( provider ));
provider->private->event_source_id = 0;
return( FALSE );
diff --git a/src/io-gconf/nagp-gconf-provider.c b/src/io-gconf/nagp-gconf-provider.c
index 4022b8f..bf049aa 100644
--- a/src/io-gconf/nagp-gconf-provider.c
+++ b/src/io-gconf/nagp-gconf-provider.c
@@ -52,8 +52,7 @@ struct NagpGConfProviderClassPrivate {
static GType st_module_type = 0;
static GObjectClass *st_parent_class = NULL;
-static gint st_timeout_msec = 100;
-static gint st_timeout_usec = 100000;
+static gint st_burst_timeout = 100; /* burst timeout in msec */
static void class_init( NagpGConfProviderClass *klass );
static void instance_init( GTypeInstance *instance, gpointer klass );
@@ -308,11 +307,18 @@ install_monitors( NagpGConfProvider *provider )
* - first, GConf underlying subsystem advertises us, through the watch
* mechanism, of each and every modification ; this leads us to be
* triggered for each new/modified/deleted _entry_
- * - as we would trigger the NAIIOProvider interface only once for each
- * modified _object_, we install a timer in order to wait for all
- * entries have been modified, or another object is concerned
- * - as soon as one of the two previous conditions is met, we trigger
- * the NAIIOProvider interface with the corresponding object id
+ * - as we want trigger the NAIIOProvider interface only once for each
+ * update operation (i.e. once for each flow of individual notifications),
+ * then we install a timer in order to wait for all
+ * entries have been modified
+ * - when a [burst_timeout] reasonable delay has elapsed without having
+ * received any new individual notification, then we can assume that
+ * we have reached the end of the flow and that we can now trigger
+ * the NAIIOProvider interface
+ *
+ * Note that we used to try to send one notification per modified object.
+ * This cannot work as we are not sure at all that we will received
+ * individual notifications themselves grouped by object.
*/
static void
config_path_changed_cb( GConfClient *client, guint cnxn_id, GConfEntry *entry, NagpGConfProvider *provider )
@@ -327,7 +333,7 @@ config_path_changed_cb( GConfClient *client, guint cnxn_id, GConfEntry *entry, N
if( !provider->private->event_source_id ){
provider->private->event_source_id =
g_timeout_add(
- st_timeout_msec,
+ st_burst_timeout,
( GSourceFunc ) config_path_changed_trigger_interface,
provider );
}
@@ -336,29 +342,33 @@ config_path_changed_cb( GConfClient *client, guint cnxn_id, GConfEntry *entry, N
/*
* this timer is set when we receive the first event of a serie
- * we continue to loop until last event is at least one half of a
- * second old
+ * we continue to loop until last event is older that the st_burst_timeout
+ * delay (in msec)
* there is no race condition here as we are not multithreaded
* or .. is there ?
*/
static gboolean
config_path_changed_trigger_interface( NagpGConfProvider *provider )
{
- /*static const gchar *thisfn = "nagp_gconf_provider_config_path_changed_trigger_interface";*/
+ static const gchar *thisfn = "nagp_gconf_provider_config_path_changed_trigger_interface";
GTimeVal now;
gulong diff;
-
- /*g_debug( "%s: provider=%p", thisfn, ( void * ) provider );*/
+ gulong timeout_usec = 1000*st_burst_timeout;
g_get_current_time( &now );
diff = time_val_diff( &now, &provider->private->last_event );
- if( diff < st_timeout_usec ){
+ if( diff < timeout_usec ){
return( TRUE );
}
+ /* last individual notification is older that the st_burst_timeout
+ * so triggers the NAIIOProvider interface and destroys this timeout
+ */
+ g_debug( "%s: triggering NAIIOProvider interface for provider=%p (%s)",
+ thisfn, ( void * ) provider, G_OBJECT_TYPE_NAME( provider ));
+
na_iio_provider_item_changed( NA_IIO_PROVIDER( provider ));
provider->private->event_source_id = 0;
-
return( FALSE );
}
diff --git a/src/nact/nact-main-menubar-file.c b/src/nact/nact-main-menubar-file.c
index 7172419..b695702 100644
--- a/src/nact/nact-main-menubar-file.c
+++ b/src/nact/nact-main-menubar-file.c
@@ -267,6 +267,10 @@ nact_main_menubar_file_save_items( NactMainWindow *window )
g_debug( "%s: window=%p", thisfn, ( void * ) window );
+ /* get ride of notification messages of IOProviders
+ */
+ na_ipivot_consumer_allow_notify( NA_IPIVOT_CONSUMER( window ), FALSE, 0 );
+
/* remove deleted items
* so that new actions with same id do not risk to be deleted later
*/
@@ -317,9 +321,9 @@ nact_main_menubar_file_save_items( NactMainWindow *window )
g_signal_emit_by_name( window, MAIN_WINDOW_SIGNAL_UPDATE_ACTION_SENSITIVITIES, NULL );
}
- /* get ride of notification messages of IOProviders
+ /* restore NAPivot notifications
*/
- na_ipivot_consumer_delay_notify( NA_IPIVOT_CONSUMER( window ));
+ na_ipivot_consumer_allow_notify( NA_IPIVOT_CONSUMER( window ), TRUE, 1000 );
}
/*
diff --git a/src/nact/nact-main-window.c b/src/nact/nact-main-window.c
index 46c7937..f114d04 100644
--- a/src/nact/nact-main-window.c
+++ b/src/nact/nact-main-window.c
@@ -662,6 +662,8 @@ instance_init( GTypeInstance *instance, gpointer klass )
G_CALLBACK( on_tab_updatable_item_updated ));
self->private->dispose_has_run = FALSE;
+
+ na_ipivot_consumer_allow_notify( NA_IPIVOT_CONSUMER( instance ), TRUE, 0 );
}
static void
diff --git a/src/plugin-menu/nautilus-actions.c b/src/plugin-menu/nautilus-actions.c
index 3868696..a294261 100644
--- a/src/plugin-menu/nautilus-actions.c
+++ b/src/plugin-menu/nautilus-actions.c
@@ -193,6 +193,8 @@ instance_init( GTypeInstance *instance, gpointer klass )
self->private = g_new0( NautilusActionsPrivate, 1 );
self->private->dispose_has_run = FALSE;
+
+ na_ipivot_consumer_allow_notify( NA_IPIVOT_CONSUMER( instance ), TRUE, 0 );
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]