[Xfce4-commits] <xfce4-panel:master> Revert "Use realtime POSIX timers for the clock."
Nick Schermer
noreply at xfce.org
Sun Mar 4 14:42:02 CET 2012
Updating branch refs/heads/master
to 0c3b236daacd12795f8598b7861fdf068c0a4199 (commit)
from b78da9cf1c7824739dff4c24b119e4a7c34e8553 (commit)
commit 0c3b236daacd12795f8598b7861fdf068c0a4199
Author: Nick Schermer <nick at xfce.org>
Date: Sun Mar 4 14:39:27 2012 +0100
Revert "Use realtime POSIX timers for the clock."
This reverts commit 07fe0a629b7b6092f2dfcaf4ef2dd2910f161a7c.
plugins/clock/clock.c | 151 +++++++++++++++++++++++++++++-------------------
1 files changed, 91 insertions(+), 60 deletions(-)
diff --git a/plugins/clock/clock.c b/plugins/clock/clock.c
index f84212b..2e38943 100644
--- a/plugins/clock/clock.c
+++ b/plugins/clock/clock.c
@@ -23,9 +23,6 @@
#ifdef HAVE_TIME_H
#include <time.h>
#endif
-#ifdef HAVE_SIGNAL_H
-#include <signal.h>
-#endif
#ifdef HAVE_MATH_H
#include <math.h>
#endif
@@ -74,6 +71,9 @@ static void clock_plugin_mode_changed (XfcePanelPlugin *p
static void clock_plugin_configure_plugin (XfcePanelPlugin *panel_plugin);
static void clock_plugin_set_mode (ClockPlugin *plugin);
static gboolean clock_plugin_tooltip (gpointer user_data);
+static gboolean clock_plugin_timeout_running (gpointer user_data);
+static void clock_plugin_timeout_destroyed (gpointer user_data);
+static gboolean clock_plugin_timeout_sync (gpointer user_data);
@@ -125,11 +125,11 @@ struct _ClockPlugin
struct _ClockPluginTimeout
{
+ guint interval;
GSourceFunc function;
gpointer data;
- guint interval;
- guint timer_idle;
- timer_t timer_id;
+ guint timeout_id;
+ guint restart : 1;
};
typedef struct
@@ -905,35 +905,62 @@ clock_plugin_tooltip (gpointer user_data)
static gboolean
-clock_plugin_timeout_expired_idle (gpointer data)
+clock_plugin_timeout_running (gpointer user_data)
{
- ClockPluginTimeout *timeout = data;
-
- timeout->timer_idle = 0;
+ ClockPluginTimeout *timeout = user_data;
+ gboolean result;
+ struct tm tm;
GDK_THREADS_ENTER ();
- (timeout->function) (timeout->data);
+ result = (timeout->function) (timeout->data);
GDK_THREADS_LEAVE ();
- return FALSE;
+ /* check if the timeout still runs in time if updating once a minute */
+ if (result && timeout->interval == CLOCK_INTERVAL_MINUTE)
+ {
+ /* sync again when we don't run on time */
+ clock_plugin_get_localtime (&tm);
+ timeout->restart = tm.tm_sec != 0;
+ }
+
+ return result && !timeout->restart;
}
static void
-clock_plugin_timeout_expired (sigval_t info)
+clock_plugin_timeout_destroyed (gpointer user_data)
{
- ClockPluginTimeout *timeout = info.sival_ptr;
+ ClockPluginTimeout *timeout = user_data;
+
+ timeout->timeout_id = 0;
+
+ if (G_UNLIKELY (timeout->restart))
+ clock_plugin_timeout_set_interval (timeout, timeout->interval);
+}
+
- panel_return_if_fail (GTK_IS_WIDGET (timeout->data));
- /* drop pending timeout */
- if (timeout->timer_idle != 0)
- g_source_remove (timeout->timer_idle);
+static gboolean
+clock_plugin_timeout_sync (gpointer user_data)
+{
+ ClockPluginTimeout *timeout = user_data;
- /* this function is called in a new thread, schedule
- * an update in the mainloop */
- timeout->timer_idle = g_idle_add (clock_plugin_timeout_expired_idle, timeout);
+ /* run the user function */
+ if ((timeout->function) (timeout->data))
+ {
+ /* start the real timeout */
+ timeout->timeout_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, timeout->interval,
+ clock_plugin_timeout_running, timeout,
+ clock_plugin_timeout_destroyed);
+ }
+ else
+ {
+ timeout->timeout_id = 0;
+ }
+
+ /* stop the sync timeout */
+ return FALSE;
}
@@ -944,25 +971,18 @@ clock_plugin_timeout_new (guint interval,
gpointer data)
{
ClockPluginTimeout *timeout;
- struct sigevent event;
panel_return_val_if_fail (interval > 0, NULL);
panel_return_val_if_fail (function != NULL, NULL);
timeout = g_slice_new0 (ClockPluginTimeout);
+ timeout->interval = 0;
timeout->function = function;
timeout->data = data;
+ timeout->timeout_id = 0;
+ timeout->restart = FALSE;
- event.sigev_notify = SIGEV_THREAD;
- event.sigev_notify_function = clock_plugin_timeout_expired;
- event.sigev_notify_attributes = NULL;
- event.sigev_value.sival_ptr = timeout;
-
- /* create the realtime timer */
- if (timer_create (CLOCK_REALTIME, &event, &timeout->timer_id) == 0)
- clock_plugin_timeout_set_interval (timeout, interval);
- else
- g_critical ("Failed to start realtime clock timeout");
+ clock_plugin_timeout_set_interval (timeout, interval);
return timeout;
}
@@ -973,42 +993,53 @@ void
clock_plugin_timeout_set_interval (ClockPluginTimeout *timeout,
guint interval)
{
- struct itimerspec itimer;
- GTimeVal current;
- gint flags = 0;
+ struct tm tm;
+ guint next_interval;
+ gboolean restart = timeout->restart;
- /* leave if the intervals are equal */
- if (timeout->interval == interval)
- return;
+ panel_return_if_fail (timeout != NULL);
+ panel_return_if_fail (interval > 0);
- /* set the interval timeout */
+ /* leave if nothing changed and we're not restarting */
+ if (!restart && timeout->interval == interval)
+ return;
timeout->interval = interval;
- itimer.it_interval.tv_sec = interval;
- itimer.it_interval.tv_nsec = 0;
+ timeout->restart = FALSE;
- if (interval >= CLOCK_INTERVAL_MINUTE)
- {
- g_get_current_time (¤t);
+ /* stop running timeout */
+ if (G_LIKELY (timeout->timeout_id != 0))
+ g_source_remove (timeout->timeout_id);
+ timeout->timeout_id = 0;
- /* sync to the next absolute time */
- itimer.it_value.tv_nsec = 0;
- itimer.it_value.tv_sec = current.tv_sec + 60 - (current.tv_sec % 60) + 1;
+ /* run function when not restarting, leave if it returns false */
+ if (!restart && !(timeout->function) (timeout->data))
+ return;
- flags = TIMER_ABSTIME;
+ /* get the seconds to the next internal */
+ if (interval == CLOCK_INTERVAL_MINUTE)
+ {
+ clock_plugin_get_localtime (&tm);
+ next_interval = 60 - tm.tm_sec;
}
else
{
- /* for the seconds timer */
- itimer.it_value.tv_nsec = 0;
- itimer.it_value.tv_sec = interval;
+ next_interval = 0;
}
- if (timer_settime (timeout->timer_id, flags, &itimer, NULL) != 0)
- g_critical ("Failed to set timer timeout");
-
- /* schedule the first update */
- if (timeout->timer_idle == 0)
- timeout->timer_idle = g_idle_add (clock_plugin_timeout_expired_idle, timeout);
+ if (next_interval > 0)
+ {
+ /* start the sync timeout */
+ timeout->timeout_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, next_interval,
+ clock_plugin_timeout_sync,
+ timeout, NULL);
+ }
+ else
+ {
+ /* directly start running the normal timeout */
+ timeout->timeout_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, interval,
+ clock_plugin_timeout_running, timeout,
+ clock_plugin_timeout_destroyed);
+ }
}
@@ -1018,9 +1049,9 @@ clock_plugin_timeout_free (ClockPluginTimeout *timeout)
{
panel_return_if_fail (timeout != NULL);
- timer_delete (timeout->timer_id);
- if (timeout->timer_idle != 0)
- g_source_remove (timeout->timer_idle);
+ timeout->restart = FALSE;
+ if (G_LIKELY (timeout->timeout_id != 0))
+ g_source_remove (timeout->timeout_id);
g_slice_free (ClockPluginTimeout, timeout);
}
More information about the Xfce4-commits
mailing list