Main Page | Modules | Data Structures | File List | Data Fields | Related Pages

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 1.2
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 
00090 void
00091 _dbus_timeout_ref (DBusTimeout *timeout)
00092 {
00093   timeout->refcount += 1;
00094 }
00095 
00102 void
00103 _dbus_timeout_unref (DBusTimeout *timeout)
00104 {
00105   _dbus_assert (timeout != NULL);
00106   _dbus_assert (timeout->refcount > 0);
00107   
00108   timeout->refcount -= 1;
00109   if (timeout->refcount == 0)
00110     {
00111       dbus_timeout_set_data (timeout, NULL, NULL); /* call free_data_function */
00112 
00113       if (timeout->free_handler_data_function)
00114         (* timeout->free_handler_data_function) (timeout->handler_data);
00115       
00116       dbus_free (timeout);
00117     }
00118 }
00119 
00129 void
00130 _dbus_timeout_set_interval (DBusTimeout *timeout,
00131                             int          interval)
00132 {
00133   _dbus_assert (interval >= 0);
00134   
00135   timeout->interval = interval;
00136 }
00137 
00148 void
00149 _dbus_timeout_set_enabled (DBusTimeout  *timeout,
00150                            dbus_bool_t   enabled)
00151 {
00152   timeout->enabled = enabled != FALSE;
00153 }
00154 
00155 
00172 struct DBusTimeoutList
00173 {
00174   DBusList *timeouts; 
00176   DBusAddTimeoutFunction add_timeout_function;       
00177   DBusRemoveTimeoutFunction remove_timeout_function; 
00178   DBusTimeoutToggledFunction timeout_toggled_function; 
00179   void *timeout_data;                                
00180   DBusFreeFunction timeout_free_data_function;       
00181 };
00182 
00189 DBusTimeoutList*
00190 _dbus_timeout_list_new (void)
00191 {
00192   DBusTimeoutList *timeout_list;
00193 
00194   timeout_list = dbus_new0 (DBusTimeoutList, 1);
00195   if (timeout_list == NULL)
00196     return NULL;
00197 
00198   return timeout_list;
00199 }
00200 
00206 void
00207 _dbus_timeout_list_free (DBusTimeoutList *timeout_list)
00208 {
00209   /* free timeout_data and remove timeouts as a side effect */
00210   _dbus_timeout_list_set_functions (timeout_list,
00211                                     NULL, NULL, NULL, NULL, NULL);
00212 
00213   _dbus_list_foreach (&timeout_list->timeouts,
00214                       (DBusForeachFunction) _dbus_timeout_unref,
00215                       NULL);
00216   _dbus_list_clear (&timeout_list->timeouts);
00217 
00218   dbus_free (timeout_list);
00219 }
00220 
00234 dbus_bool_t
00235 _dbus_timeout_list_set_functions (DBusTimeoutList           *timeout_list,
00236                                   DBusAddTimeoutFunction     add_function,
00237                                   DBusRemoveTimeoutFunction  remove_function,
00238                                   DBusTimeoutToggledFunction toggled_function,
00239                                   void                      *data,
00240                                   DBusFreeFunction           free_data_function)
00241 {
00242   /* Add timeouts with the new function, failing on OOM */
00243   if (add_function != NULL)
00244     {
00245       DBusList *link;
00246       
00247       link = _dbus_list_get_first_link (&timeout_list->timeouts);
00248       while (link != NULL)
00249         {
00250           DBusList *next = _dbus_list_get_next_link (&timeout_list->timeouts,
00251                                                      link);
00252       
00253           if (!(* add_function) (link->data, data))
00254             {
00255               /* remove it all again and return FALSE */
00256               DBusList *link2;
00257               
00258               link2 = _dbus_list_get_first_link (&timeout_list->timeouts);
00259               while (link2 != link)
00260                 {
00261                   DBusList *next = _dbus_list_get_next_link (&timeout_list->timeouts,
00262                                                              link2);
00263 
00264                   (* remove_function) (link2->data, data);
00265                   
00266                   link2 = next;
00267                 }
00268 
00269               return FALSE;
00270             }
00271       
00272           link = next;
00273         }
00274     }
00275   
00276   /* Remove all current timeouts from previous timeout handlers */
00277 
00278   if (timeout_list->remove_timeout_function != NULL)
00279     {
00280       _dbus_list_foreach (&timeout_list->timeouts,
00281                           (DBusForeachFunction) timeout_list->remove_timeout_function,
00282                           timeout_list->timeout_data);
00283     }
00284 
00285   if (timeout_list->timeout_free_data_function != NULL)
00286     (* timeout_list->timeout_free_data_function) (timeout_list->timeout_data);
00287 
00288   timeout_list->add_timeout_function = add_function;
00289   timeout_list->remove_timeout_function = remove_function;
00290   timeout_list->timeout_toggled_function = toggled_function;
00291   timeout_list->timeout_data = data;
00292   timeout_list->timeout_free_data_function = free_data_function;
00293 
00294   return TRUE;
00295 }
00296 
00305 dbus_bool_t
00306 _dbus_timeout_list_add_timeout (DBusTimeoutList *timeout_list,
00307                                 DBusTimeout     *timeout)
00308 {
00309   if (!_dbus_list_append (&timeout_list->timeouts, timeout))
00310     return FALSE;
00311 
00312   _dbus_timeout_ref (timeout);
00313 
00314   if (timeout_list->add_timeout_function != NULL)
00315     {
00316       if (!(* timeout_list->add_timeout_function) (timeout,
00317                                                    timeout_list->timeout_data))
00318         {
00319           _dbus_list_remove_last (&timeout_list->timeouts, timeout);
00320           _dbus_timeout_unref (timeout);
00321           return FALSE;
00322         }
00323     }
00324 
00325   return TRUE;
00326 }
00327 
00335 void
00336 _dbus_timeout_list_remove_timeout (DBusTimeoutList *timeout_list,
00337                                    DBusTimeout     *timeout)
00338 {
00339   if (!_dbus_list_remove (&timeout_list->timeouts, timeout))
00340     _dbus_assert_not_reached ("Nonexistent timeout was removed");
00341 
00342   if (timeout_list->remove_timeout_function != NULL)
00343     (* timeout_list->remove_timeout_function) (timeout,
00344                                                timeout_list->timeout_data);
00345 
00346   _dbus_timeout_unref (timeout);
00347 }
00348 
00357 void
00358 _dbus_timeout_list_toggle_timeout (DBusTimeoutList           *timeout_list,
00359                                    DBusTimeout               *timeout,
00360                                    dbus_bool_t                enabled)
00361 {
00362   enabled = !!enabled;
00363   
00364   if (enabled == timeout->enabled)
00365     return;
00366 
00367   timeout->enabled = enabled;
00368   
00369   if (timeout_list->timeout_toggled_function != NULL)
00370     (* timeout_list->timeout_toggled_function) (timeout,
00371                                                 timeout_list->timeout_data);
00372 }
00373 
00408 int
00409 dbus_timeout_get_interval (DBusTimeout *timeout)
00410 {
00411   return timeout->interval;
00412 }
00413 
00421 void*
00422 dbus_timeout_get_data (DBusTimeout *timeout)
00423 {
00424   return timeout->data;
00425 }
00426 
00438 void
00439 dbus_timeout_set_data (DBusTimeout      *timeout,
00440                        void             *data,
00441                        DBusFreeFunction  free_data_function)
00442 {
00443   if (timeout->free_data_function != NULL)
00444     (* timeout->free_data_function) (timeout->data);
00445 
00446   timeout->data = data;
00447   timeout->free_data_function = free_data_function;
00448 }
00449 
00464 dbus_bool_t
00465 dbus_timeout_handle (DBusTimeout *timeout)
00466 {
00467   return (* timeout->handler) (timeout->handler_data);
00468 }
00469 
00470 
00478 dbus_bool_t
00479 dbus_timeout_get_enabled (DBusTimeout *timeout)
00480 {
00481   return timeout->enabled;
00482 }
00483 

Generated on Tue Feb 10 18:14:09 2004 for D-BUS by doxygen 1.3.5