Main Page | Data Structures | File List | Data Fields | Globals

timer-gtimeout.c

Go to the documentation of this file.
00001 /**
00002  * This file is part of alarmd
00003  *
00004  * Contact Person: David Weinehall <david.weinehall@nokia.com>
00005  *
00006  * Copyright (C) 2006 Nokia Corporation
00007  * alarmd and libalarm are free software; you can redistribute them
00008  * and/or modify them under the terms of the GNU Lesser General Public
00009  * License version 2.1 as published by the Free Software Foundation.
00010  *
00011  * alarmd and libalarm are distributed in the hope that they will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this software; if not, write to the Free
00018  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
00019  * 02110-1301 USA
00020  */
00021 
00022 #include <glib/gmain.h>
00023 #include <glib/gtypes.h>
00024 #include <time.h>
00025 #include <stdio.h>
00026 #include <osso-log.h>
00027 #include "include/timer-interface.h"
00028 #include "debug.h"
00029 
00030 static gboolean gtimeout_set_event(TimerPlugin *plugin, time_t wanted_time, TimerCallback cb, TimerCancel cancel, gpointer user_data);
00031 static gboolean gtimeout_remove_event(TimerPlugin *plugin);
00032 static time_t gtimeout_get_time(TimerPlugin *plugin);
00033 static void gtimeout_time_changed(TimerPlugin *plugin);
00034 static void gtimeout_plugin_deinit(TimerPlugin *plugin);
00035 
00036 typedef struct _GTimeoutTimerEvent GTimeoutTimerEvent;
00037 struct _GTimeoutTimerEvent {
00038         guint timer_id;
00039         time_t timer_time;
00040         TimerCallback cb;
00041         TimerCancel cancel;
00042         gpointer cb_data;
00043 
00044         TimerPlugin *plugin;
00045 };
00046 
00047 typedef struct _GTimeoutIdleEvent GTimeoutIdleEvent;
00048 struct _GTimeoutIdleEvent {
00049         TimerCallback cb;
00050         gpointer cb_data;
00051         gboolean delayed;
00052 };
00053 
00054 gboolean plugin_initialize(TimerPlugin *plugin)
00055 {
00056         ENTER_FUNC;
00057         plugin->remove_event = gtimeout_remove_event;
00058         plugin->get_time = gtimeout_get_time;
00059         plugin->plugin_deinit = gtimeout_plugin_deinit;
00060         plugin->set_event = gtimeout_set_event;
00061         plugin->time_changed = gtimeout_time_changed;
00062 
00063         plugin->can_power_up = FALSE;
00064         plugin->priority = 10;
00065         plugin->plugin_data = NULL;
00066 
00067         LEAVE_FUNC;
00068         return TRUE;
00069 }
00070 
00071 static gboolean _gtimeout_event_fire(gpointer event)
00072 {
00073         GTimeoutTimerEvent *ev = (GTimeoutTimerEvent *)event;
00074         ENTER_FUNC;
00075 
00076         ev->plugin->plugin_data = NULL;
00077 
00078         if (ev->cb) {
00079                 ev->cb(ev->cb_data, FALSE);
00080         }
00081 
00082         g_free(event);
00083 
00084         LEAVE_FUNC;
00085         return FALSE;
00086 }
00087 
00088 static gboolean _gtimeout_idle_event_fire(gpointer event) {
00089         GTimeoutIdleEvent *ev = event;
00090         ENTER_FUNC;
00091 
00092         if (ev->cb) {
00093                 ev->cb(ev->cb_data, ev->delayed);
00094         }
00095 
00096         g_free(event);
00097 
00098         LEAVE_FUNC;
00099         return FALSE;
00100 }
00101 
00102 static gboolean gtimeout_set_event(TimerPlugin *plugin, time_t wanted_time, TimerCallback cb, TimerCancel cancel, gpointer user_data)
00103 {
00104         GTimeoutTimerEvent *event = NULL;
00105         time_t time_now = time(NULL);
00106         ENTER_FUNC;
00107 
00108         DEBUG("wanted time = %lu", wanted_time);
00109 
00110         if (plugin == NULL || cb == NULL) {
00111                 DEBUG("plugin == NULL || cb == NULL");
00112                 LEAVE_FUNC;
00113                 return FALSE;
00114         }
00115 
00116         plugin->remove_event(plugin);
00117 
00118         if (time_now > wanted_time) {
00119                 GTimeoutIdleEvent *ev = g_new0(GTimeoutIdleEvent, 1);
00120                 ev->cb = cb;
00121                 ev->cb_data = user_data;
00122                 ev->delayed = time_now > wanted_time + 10 ? TRUE : FALSE;
00123                 g_idle_add(_gtimeout_idle_event_fire, ev);
00124 
00125                 LEAVE_FUNC;
00126                 return TRUE;
00127         }
00128 
00129         event = g_new0(GTimeoutTimerEvent, 1);
00130 
00131         event->timer_id = g_timeout_add((wanted_time - time_now) * 1000, _gtimeout_event_fire, event);
00132 
00133         if (event->timer_id == 0) {
00134                 ULOG_WARN_F("Adding timeout failed.");
00135                 g_free(event);
00136 
00137                 LEAVE_FUNC;
00138                 return FALSE;
00139         }
00140         
00141         event->timer_time = wanted_time;
00142         event->cb = cb;
00143         event->cancel = cancel;
00144         event->cb_data = user_data;
00145 
00146         event->plugin = plugin;
00147 
00148         plugin->plugin_data = (gpointer)event;
00149 
00150         LEAVE_FUNC;
00151         return TRUE;
00152 }
00153 
00154 static gboolean gtimeout_remove_event(TimerPlugin *plugin)
00155 {
00156         ENTER_FUNC;
00157         if (plugin && plugin->plugin_data) {
00158                 GTimeoutTimerEvent *event = (GTimeoutTimerEvent *)plugin->plugin_data;
00159 
00160                 g_source_remove(event->timer_id);
00161 
00162                 if (event->cancel) {
00163                         event->cancel(event->cb_data);
00164                 }
00165 
00166                 plugin->plugin_data = NULL;
00167 
00168                 g_free(event);
00169 
00170                 LEAVE_FUNC;
00171                 return TRUE;
00172         }
00173         
00174         LEAVE_FUNC;
00175         return FALSE;
00176 }
00177 
00178 static time_t gtimeout_get_time(TimerPlugin *plugin)
00179 {
00180         ENTER_FUNC;
00181         if (plugin->plugin_data) {
00182                 GTimeoutTimerEvent *event = (GTimeoutTimerEvent *)plugin->plugin_data;
00183 
00184                 LEAVE_FUNC;
00185                 return event->timer_time;
00186         }
00187         
00188         LEAVE_FUNC;
00189         return 0;
00190 }
00191 
00192 static void gtimeout_plugin_deinit(TimerPlugin *plugin)
00193 {
00194         ENTER_FUNC;
00195         plugin->remove_event(plugin);
00196         LEAVE_FUNC;
00197 }
00198 
00199 static void gtimeout_time_changed(TimerPlugin *plugin)
00200 {
00201         ENTER_FUNC;
00202         if (plugin->plugin_data) {
00203                 GTimeoutTimerEvent *event = (GTimeoutTimerEvent *)plugin->plugin_data;
00204                 time_t now = time(NULL);
00205                 g_source_remove(event->timer_id);
00206                 if (now > event->timer_time) {
00207                         plugin->plugin_data = NULL;
00208 
00209                         if (event->cb) {
00210                                 event->cb(event->cb_data, FALSE);
00211                         }
00212 
00213                         g_free(event);
00214                 } else {
00215                         event->timer_id = g_timeout_add((event->timer_time - now) * 1000, _gtimeout_event_fire, event);
00216                 }
00217         }
00218         LEAVE_FUNC;
00219 }

Generated on Thu Dec 21 18:23:30 2006 for Alarmd by  doxygen 1.4.2