dbus-timeout.c

00001 /* -*- mode: C; c-file-style: "gnu" -*- */
00002 /* dbus-timeout.c DBusTimeout implementation
00003  *
00004  * Copyright (C) 2003  CodeFactory AB
00005  *
00006  * Licensed under the Academic Free License version 2.1
00007  * 
00008  * This program is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  * 
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  */
00023 
00024 #include "dbus-internals.h"
00025 #include "dbus-timeout.h"
00026 #include "dbus-list.h"
00027 
00039 struct DBusTimeout
00040 {
00041   int refcount;                                
00042   int interval;                                
00044   DBusTimeoutHandler handler;                  
00045   void *handler_data;                          
00046   DBusFreeFunction free_handler_data_function; 
00048   void *data;                                  
00049   DBusFreeFunction free_data_function;         
00050   unsigned int enabled : 1;                    
00051 };
00052 
00061 DBusTimeout*
00062 _dbus_timeout_new (int                 interval,
00063                    DBusTimeoutHandler  handler,
00064                    void               *data,
00065                    DBusFreeFunction    free_data_function)
00066 {
00067   DBusTimeout *timeout;
00068 
00069   timeout = dbus_new0 (DBusTimeout, 1);
00070   if (timeout == NULL)
00071     return NULL;
00072   
00073   timeout->refcount = 1;
00074   timeout->interval = interval;
00075 
00076   timeout->handler = handler;
00077   timeout->handler_data = data;
00078   timeout->free_handler_data_function = free_data_function;
00079 
00080   timeout->enabled = TRUE;
00081   
00082   return timeout;
00083 }
00084 
00091 DBusTimeout *
00092 _dbus_timeout_ref (DBusTimeout *timeout)
00093 {
00094   timeout->refcount += 1;
00095 
00096   return timeout;
00097 }
00098 
00105 void
00106 _dbus_timeout_unref (DBusTimeout *timeout)
00107 {
00108   _dbus_assert (timeout != NULL);
00109   _dbus_assert (timeout->refcount > 0);
00110   
00111   timeout->refcount -= 1;
00112   if (timeout->refcount == 0)
00113     {
00114       dbus_timeout_set_data (timeout, NULL, NULL); /* call free_data_function */
00115 
00116       if (timeout->free_handler_data_function)
00117         (* timeout->free_handler_data_function) (timeout->handler_data);
00118       
00119       dbus_free (timeout);
00120     }
00121 }
00122 
00132 void
00133 _dbus_timeout_set_interval (DBusTimeout *timeout,
00134                             int          interval)
00135 {
00136   _dbus_assert (interval >= 0);
00137   
00138   timeout->interval = interval;
00139 }
00140 
00151 void
00152 _dbus_timeout_set_enabled (DBusTimeout  *timeout,
00153                            dbus_bool_t   enabled)
00154 {
00155   timeout->enabled = enabled != FALSE;
00156 }
00157 
00158 
00175 struct DBusTimeoutList
00176 {
00177   DBusList *timeouts; 
00179   DBusAddTimeoutFunction add_timeout_function;       
00180   DBusRemoveTimeoutFunction remove_timeout_function; 
00181   DBusTimeoutToggledFunction timeout_toggled_function; 
00182   void *timeout_data;                                
00183   DBusFreeFunction timeout_free_data_function;       
00184 };
00185 
00192 DBusTimeoutList*
00193 _dbus_timeout_list_new (void)
00194 {
00195   DBusTimeoutList *timeout_list;
00196 
00197   timeout_list = dbus_new0 (DBusTimeoutList, 1);
00198   if (timeout_list == NULL)
00199     return NULL;
00200 
00201   return timeout_list;
00202 }
00203 
00209 void
00210 _dbus_timeout_list_free (DBusTimeoutList *timeout_list)
00211 {
00212   /* free timeout_data and remove timeouts as a side effect */
00213   _dbus_timeout_list_set_functions (timeout_list,
00214                                     NULL, NULL, NULL, NULL, NULL);
00215 
00216   _dbus_list_foreach (&timeout_list->timeouts,
00217                       (DBusForeachFunction) _dbus_timeout_unref,
00218                       NULL);
00219   _dbus_list_clear (&timeout_list->timeouts);
00220 
00221   dbus_free (timeout_list);
00222 }
00223 
00237 dbus_bool_t
00238 _dbus_timeout_list_set_functions (DBusTimeoutList           *timeout_list,
00239                                   DBusAddTimeoutFunction     add_function,
00240                                   DBusRemoveTimeoutFunction  remove_function,
00241                                   DBusTimeoutToggledFunction toggled_function,
00242                                   void                      *data,
00243                                   DBusFreeFunction           free_data_function)
00244 {
00245   /* Add timeouts with the new function, failing on OOM */
00246   if (add_function != NULL)
00247     {
00248       DBusList *link;
00249       
00250       link = _dbus_list_get_first_link (&timeout_list->timeouts);
00251       while (link != NULL)
00252         {
00253           DBusList *next = _dbus_list_get_next_link (&timeout_list->timeouts,
00254                                                      link);
00255       
00256           if (!(* add_function) (link->data, data))
00257             {
00258               /* remove it all again and return FALSE */
00259               DBusList *link2;
00260               
00261               link2 = _dbus_list_get_first_link (&timeout_list->timeouts);
00262               while (link2 != link)
00263                 {
00264                   DBusList *next = _dbus_list_get_next_link (&timeout_list->timeouts,
00265                                                              link2);
00266 
00267                   (* remove_function) (link2->data, data);
00268                   
00269                   link2 = next;
00270                 }
00271 
00272               return FALSE;
00273             }
00274       
00275           link = next;
00276         }
00277     }
00278   
00279   /* Remove all current timeouts from previous timeout handlers */
00280 
00281   if (timeout_list->remove_timeout_function != NULL)
00282     {
00283       _dbus_list_foreach (&timeout_list->timeouts,
00284                           (DBusForeachFunction) timeout_list->remove_timeout_function,
00285                           timeout_list->timeout_data);
00286     }
00287 
00288   if (timeout_list->timeout_free_data_function != NULL)
00289     (* timeout_list->timeout_free_data_function) (timeout_list->timeout_data);
00290 
00291   timeout_list->add_timeout_function = add_function;
00292   timeout_list->remove_timeout_function = remove_function;
00293   timeout_list->timeout_toggled_function = toggled_function;
00294   timeout_list->timeout_data = data;
00295   timeout_list->timeout_free_data_function = free_data_function;
00296 
00297   return TRUE;
00298 }
00299 
00308 dbus_bool_t
00309 _dbus_timeout_list_add_timeout (DBusTimeoutList *timeout_list,
00310                                 DBusTimeout     *timeout)
00311 {
00312   if (!_dbus_list_append (&timeout_list->timeouts, timeout))
00313     return FALSE;
00314 
00315   _dbus_timeout_ref (timeout);
00316 
00317   if (timeout_list->add_timeout_function != NULL)
00318     {
00319       if (!(* timeout_list->add_timeout_function) (timeout,
00320                                                    timeout_list->timeout_data))
00321         {
00322           _dbus_list_remove_last (&timeout_list->timeouts, timeout);
00323           _dbus_timeout_unref (timeout);
00324           return FALSE;
00325         }
00326     }
00327 
00328   return TRUE;
00329 }
00330 
00338 void
00339 _dbus_timeout_list_remove_timeout (DBusTimeoutList *timeout_list,
00340                                    DBusTimeout     *timeout)
00341 {
00342   if (!_dbus_list_remove (&timeout_list->timeouts, timeout))
00343     _dbus_assert_not_reached ("Nonexistent timeout was removed");
00344 
00345   if (timeout_list->remove_timeout_function != NULL)
00346     (* timeout_list->remove_timeout_function) (timeout,
00347                                                timeout_list->timeout_data);
00348 
00349   _dbus_timeout_unref (timeout);
00350 }
00351 
00360 void
00361 _dbus_timeout_list_toggle_timeout (DBusTimeoutList           *timeout_list,
00362                                    DBusTimeout               *timeout,
00363                                    dbus_bool_t                enabled)
00364 {
00365   enabled = !!enabled;
00366   
00367   if (enabled == timeout->enabled)
00368     return;
00369 
00370   timeout->enabled = enabled;
00371   
00372   if (timeout_list->timeout_toggled_function != NULL)
00373     (* timeout_list->timeout_toggled_function) (timeout,
00374                                                 timeout_list->timeout_data);
00375 }
00376 
00414 int
00415 dbus_timeout_get_interval (DBusTimeout *timeout)
00416 {
00417   return timeout->interval;
00418 }
00419 
00427 void*
00428 dbus_timeout_get_data (DBusTimeout *timeout)
00429 {
00430   return timeout->data;
00431 }
00432 
00444 void
00445 dbus_timeout_set_data (DBusTimeout      *timeout,
00446                        void             *data,
00447                        DBusFreeFunction  free_data_function)
00448 {
00449   if (timeout->free_data_function != NULL)
00450     (* timeout->free_data_function) (timeout->data);
00451 
00452   timeout->data = data;
00453   timeout->free_data_function = free_data_function;
00454 }
00455 
00470 dbus_bool_t
00471 dbus_timeout_handle (DBusTimeout *timeout)
00472 {
00473   return (* timeout->handler) (timeout->handler_data);
00474 }
00475 
00476 
00484 dbus_bool_t
00485 dbus_timeout_get_enabled (DBusTimeout *timeout)
00486 {
00487   return timeout->enabled;
00488 }
00489 

Generated on Fri Sep 21 18:12:13 2007 for D-Bus by  doxygen 1.5.1