D-Bus
1.4.18
|
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 * 00022 */ 00023 00024 #include <config.h> 00025 #include "dbus-internals.h" 00026 #include "dbus-timeout.h" 00027 #include "dbus-list.h" 00028 00040 struct DBusTimeout 00041 { 00042 int refcount; 00043 int interval; 00045 DBusTimeoutHandler handler; 00046 void *handler_data; 00047 DBusFreeFunction free_handler_data_function; 00049 void *data; 00050 DBusFreeFunction free_data_function; 00051 unsigned int enabled : 1; 00052 }; 00053 00062 DBusTimeout* 00063 _dbus_timeout_new (int interval, 00064 DBusTimeoutHandler handler, 00065 void *data, 00066 DBusFreeFunction free_data_function) 00067 { 00068 DBusTimeout *timeout; 00069 00070 timeout = dbus_new0 (DBusTimeout, 1); 00071 if (timeout == NULL) 00072 return NULL; 00073 00074 timeout->refcount = 1; 00075 timeout->interval = interval; 00076 00077 timeout->handler = handler; 00078 timeout->handler_data = data; 00079 timeout->free_handler_data_function = free_data_function; 00080 00081 timeout->enabled = TRUE; 00082 00083 return timeout; 00084 } 00085 00092 DBusTimeout * 00093 _dbus_timeout_ref (DBusTimeout *timeout) 00094 { 00095 timeout->refcount += 1; 00096 00097 return timeout; 00098 } 00099 00106 void 00107 _dbus_timeout_unref (DBusTimeout *timeout) 00108 { 00109 _dbus_assert (timeout != NULL); 00110 _dbus_assert (timeout->refcount > 0); 00111 00112 timeout->refcount -= 1; 00113 if (timeout->refcount == 0) 00114 { 00115 dbus_timeout_set_data (timeout, NULL, NULL); /* call free_data_function */ 00116 00117 if (timeout->free_handler_data_function) 00118 (* timeout->free_handler_data_function) (timeout->handler_data); 00119 00120 dbus_free (timeout); 00121 } 00122 } 00123 00133 void 00134 _dbus_timeout_set_interval (DBusTimeout *timeout, 00135 int interval) 00136 { 00137 _dbus_assert (interval >= 0); 00138 00139 timeout->interval = interval; 00140 } 00141 00152 void 00153 _dbus_timeout_set_enabled (DBusTimeout *timeout, 00154 dbus_bool_t enabled) 00155 { 00156 timeout->enabled = enabled != FALSE; 00157 } 00158 00159 00176 struct DBusTimeoutList 00177 { 00178 DBusList *timeouts; 00180 DBusAddTimeoutFunction add_timeout_function; 00181 DBusRemoveTimeoutFunction remove_timeout_function; 00182 DBusTimeoutToggledFunction timeout_toggled_function; 00183 void *timeout_data; 00184 DBusFreeFunction timeout_free_data_function; 00185 }; 00186 00193 DBusTimeoutList* 00194 _dbus_timeout_list_new (void) 00195 { 00196 DBusTimeoutList *timeout_list; 00197 00198 timeout_list = dbus_new0 (DBusTimeoutList, 1); 00199 if (timeout_list == NULL) 00200 return NULL; 00201 00202 return timeout_list; 00203 } 00204 00210 void 00211 _dbus_timeout_list_free (DBusTimeoutList *timeout_list) 00212 { 00213 /* free timeout_data and remove timeouts as a side effect */ 00214 _dbus_timeout_list_set_functions (timeout_list, 00215 NULL, NULL, NULL, NULL, NULL); 00216 00217 _dbus_list_foreach (&timeout_list->timeouts, 00218 (DBusForeachFunction) _dbus_timeout_unref, 00219 NULL); 00220 _dbus_list_clear (&timeout_list->timeouts); 00221 00222 dbus_free (timeout_list); 00223 } 00224 00238 dbus_bool_t 00239 _dbus_timeout_list_set_functions (DBusTimeoutList *timeout_list, 00240 DBusAddTimeoutFunction add_function, 00241 DBusRemoveTimeoutFunction remove_function, 00242 DBusTimeoutToggledFunction toggled_function, 00243 void *data, 00244 DBusFreeFunction free_data_function) 00245 { 00246 /* Add timeouts with the new function, failing on OOM */ 00247 if (add_function != NULL) 00248 { 00249 DBusList *link; 00250 00251 link = _dbus_list_get_first_link (&timeout_list->timeouts); 00252 while (link != NULL) 00253 { 00254 DBusList *next = _dbus_list_get_next_link (&timeout_list->timeouts, 00255 link); 00256 00257 if (!(* add_function) (link->data, data)) 00258 { 00259 /* remove it all again and return FALSE */ 00260 DBusList *link2; 00261 00262 link2 = _dbus_list_get_first_link (&timeout_list->timeouts); 00263 while (link2 != link) 00264 { 00265 DBusList *next = _dbus_list_get_next_link (&timeout_list->timeouts, 00266 link2); 00267 00268 (* remove_function) (link2->data, data); 00269 00270 link2 = next; 00271 } 00272 00273 return FALSE; 00274 } 00275 00276 link = next; 00277 } 00278 } 00279 00280 /* Remove all current timeouts from previous timeout handlers */ 00281 00282 if (timeout_list->remove_timeout_function != NULL) 00283 { 00284 _dbus_list_foreach (&timeout_list->timeouts, 00285 (DBusForeachFunction) timeout_list->remove_timeout_function, 00286 timeout_list->timeout_data); 00287 } 00288 00289 if (timeout_list->timeout_free_data_function != NULL) 00290 (* timeout_list->timeout_free_data_function) (timeout_list->timeout_data); 00291 00292 timeout_list->add_timeout_function = add_function; 00293 timeout_list->remove_timeout_function = remove_function; 00294 timeout_list->timeout_toggled_function = toggled_function; 00295 timeout_list->timeout_data = data; 00296 timeout_list->timeout_free_data_function = free_data_function; 00297 00298 return TRUE; 00299 } 00300 00309 dbus_bool_t 00310 _dbus_timeout_list_add_timeout (DBusTimeoutList *timeout_list, 00311 DBusTimeout *timeout) 00312 { 00313 if (!_dbus_list_append (&timeout_list->timeouts, timeout)) 00314 return FALSE; 00315 00316 _dbus_timeout_ref (timeout); 00317 00318 if (timeout_list->add_timeout_function != NULL) 00319 { 00320 if (!(* timeout_list->add_timeout_function) (timeout, 00321 timeout_list->timeout_data)) 00322 { 00323 _dbus_list_remove_last (&timeout_list->timeouts, timeout); 00324 _dbus_timeout_unref (timeout); 00325 return FALSE; 00326 } 00327 } 00328 00329 return TRUE; 00330 } 00331 00339 void 00340 _dbus_timeout_list_remove_timeout (DBusTimeoutList *timeout_list, 00341 DBusTimeout *timeout) 00342 { 00343 if (!_dbus_list_remove (&timeout_list->timeouts, timeout)) 00344 _dbus_assert_not_reached ("Nonexistent timeout was removed"); 00345 00346 if (timeout_list->remove_timeout_function != NULL) 00347 (* timeout_list->remove_timeout_function) (timeout, 00348 timeout_list->timeout_data); 00349 00350 _dbus_timeout_unref (timeout); 00351 } 00352 00361 void 00362 _dbus_timeout_list_toggle_timeout (DBusTimeoutList *timeout_list, 00363 DBusTimeout *timeout, 00364 dbus_bool_t enabled) 00365 { 00366 enabled = !!enabled; 00367 00368 if (enabled == timeout->enabled) 00369 return; 00370 00371 timeout->enabled = enabled; 00372 00373 if (timeout_list->timeout_toggled_function != NULL) 00374 (* timeout_list->timeout_toggled_function) (timeout, 00375 timeout_list->timeout_data); 00376 } 00377 00415 int 00416 dbus_timeout_get_interval (DBusTimeout *timeout) 00417 { 00418 return timeout->interval; 00419 } 00420 00428 void* 00429 dbus_timeout_get_data (DBusTimeout *timeout) 00430 { 00431 return timeout->data; 00432 } 00433 00445 void 00446 dbus_timeout_set_data (DBusTimeout *timeout, 00447 void *data, 00448 DBusFreeFunction free_data_function) 00449 { 00450 if (timeout->free_data_function != NULL) 00451 (* timeout->free_data_function) (timeout->data); 00452 00453 timeout->data = data; 00454 timeout->free_data_function = free_data_function; 00455 } 00456 00471 dbus_bool_t 00472 dbus_timeout_handle (DBusTimeout *timeout) 00473 { 00474 return (* timeout->handler) (timeout->handler_data); 00475 } 00476 00477 00485 dbus_bool_t 00486 dbus_timeout_get_enabled (DBusTimeout *timeout) 00487 { 00488 return timeout->enabled; 00489 } 00490