D-Bus 1.2.24
|
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 "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