diff options
Diffstat (limited to 'dbus/dbus-timeout.c')
-rw-r--r-- | dbus/dbus-timeout.c | 342 |
1 files changed, 342 insertions, 0 deletions
diff --git a/dbus/dbus-timeout.c b/dbus/dbus-timeout.c new file mode 100644 index 00000000..9aefbb40 --- /dev/null +++ b/dbus/dbus-timeout.c @@ -0,0 +1,342 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* dbus-timeout.c DBusTimeout implementation + * + * Copyright (C) 2003 CodeFactory AB + * + * Licensed under the Academic Free License version 1.2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "dbus-internals.h" +#include "dbus-timeout.h" +#include "dbus-list.h" + +/** + * @defgroup DBusTimeoutInternals DBusTimeout implementation details + * @ingroup DBusInternals + * @brief implementation details for DBusTimeout + * + * @{ + */ + +struct DBusTimeout +{ + int refcount; /**< Reference count */ + int interval; /**< Timeout interval in milliseconds. */ + + DBusTimeoutHandler handler; /**< Timeout handler. */ + void *handler_data; /**< Timeout handler data. */ + DBusFreeFunction free_handler_data_function; /**< Free the timeout handler data. */ + + void *data; /**< Application data. */ + DBusFreeFunction free_data_function; /**< Free the application data. */ +}; + +/** + * Creates a new DBusTimeout. + * @param interval the timeout interval in milliseconds. + * @param handler function to call when the timeout occurs. + * @param data data to pass to the handler + * @param free_data_function function to be called to free the data. + * @returns the new DBusTimeout object, + */ +DBusTimeout* +_dbus_timeout_new (int interval, + DBusTimeoutHandler handler, + void *data, + DBusFreeFunction free_data_function) +{ + DBusTimeout *timeout; + + timeout = dbus_new0 (DBusTimeout, 1); + timeout->refcount = 1; + timeout->interval = interval; + + timeout->handler_data = data; + timeout->free_handler_data_function = free_data_function; + + return timeout; +} + +/** + * Increments the reference count of a DBusTimeout object. + * + * @param timeout the timeout object. + */ +void +_dbus_timeout_ref (DBusTimeout *timeout) +{ + timeout->refcount += 1; +} + +/** + * Decrements the reference count of a DBusTimeout object + * and finalizes the object if the count reaches zero. + * + * @param timeout the timeout object. + */ +void +_dbus_timeout_unref (DBusTimeout *timeout) +{ + _dbus_assert (timeout != NULL); + _dbus_assert (timeout->refcount > 0); + + timeout->refcount -= 1; + if (timeout->refcount == 0) + { + dbus_timeout_set_data (timeout, NULL, NULL); /* call free_data_function */ + + if (timeout->free_handler_data_function) + (* timeout->free_handler_data_function) (timeout->handler_data); + + dbus_free (timeout); + } +} + +/** + * @typedef DBusTimeoutList + * + * Opaque data type representing a list of timeouts + * and a set of DBusAddTimeoutFunction/DBusRemoveTimeoutFunction. + * Automatically handles removing/re-adding timeouts + * when the DBusAddTimeoutFunction is updated or changed. + * Holds a reference count to each timeout. + * + */ + +/** + * DBusTimeoutList implementation details. All fields + * are private. + * + */ +struct DBusTimeoutList +{ + DBusList *timeouts; /**< Timeout objects. */ + + DBusAddTimeoutFunction add_timeout_function; /**< Callback for adding a timeout. */ + DBusRemoveTimeoutFunction remove_timeout_function; /**< Callback for removing a timeout. */ + void *timeout_data; /**< Data for timeout callbacks */ + DBusFreeFunction timeout_free_data_function; /**< Free function for timeout callback data */ +}; + +/** + * Creates a new timeout list. Returns #NULL if insufficient + * memory exists. + * + * @returns the new timeout list, or #NULL on failure. + */ +DBusTimeoutList* +_dbus_timeout_list_new (void) +{ + DBusTimeoutList *timeout_list; + + timeout_list = dbus_new0 (DBusTimeoutList, 1); + if (timeout_list == NULL) + return NULL; + + return timeout_list; +} + +/** + * Frees a DBusTimeoutList. + * + * @param timeout_list the timeout list. + */ +void +_dbus_timeout_list_free (DBusTimeoutList *timeout_list) +{ + /* free timeout_data and remove timeouts as a side effect */ + _dbus_timeout_list_set_functions (timeout_list, + NULL, NULL, NULL, NULL); + + _dbus_list_foreach (&timeout_list->timeouts, + (DBusForeachFunction) _dbus_timeout_unref, + NULL); + _dbus_list_clear (&timeout_list->timeouts); + + dbus_free (timeout_list); +} + +/** + * Sets the timeout functions. This function is the "backend" + * for dbus_connection_set_timeout_functions(). + * + * @param timeout_list the timeout list + * @param add_function the add timeout function. + * @param remove_function the remove timeout function. + * @param data the data for those functions. + * @param free_data_function the function to free the data. + * + */ +void +_dbus_timeout_list_set_functions (DBusTimeoutList *timeout_list, + DBusAddTimeoutFunction add_function, + DBusRemoveTimeoutFunction remove_function, + void *data, + DBusFreeFunction free_data_function) +{ + /* Remove all current timeouts from previous timeout handlers */ + + if (timeout_list->remove_timeout_function != NULL) + { + _dbus_list_foreach (&timeout_list->timeouts, + (DBusForeachFunction) timeout_list->remove_timeout_function, + timeout_list->timeout_data); + } + + if (timeout_list->timeout_free_data_function != NULL) + (* timeout_list->timeout_free_data_function) (timeout_list->timeout_data); + + timeout_list->add_timeout_function = add_function; + timeout_list->remove_timeout_function = remove_function; + timeout_list->timeout_data = data; + timeout_list->timeout_free_data_function = free_data_function; + + /* Re-add all pending timeouts */ + if (timeout_list->add_timeout_function != NULL) + { + _dbus_list_foreach (&timeout_list->timeouts, + (DBusForeachFunction) timeout_list->add_timeout_function, + timeout_list->timeout_data); + } +} + +/** + * Adds a new timeout to the timeout list, invoking the + * application DBusAddTimeoutFunction if appropriate. + * + * @param timeout_list the timeout list. + * @param timeout the timeout to add. + * @returns #TRUE on success, #FALSE If no memory. + */ +dbus_bool_t +_dbus_timeout_list_add_timeout (DBusTimeoutList *timeout_list, + DBusTimeout *timeout) +{ + if (!_dbus_list_append (&timeout_list->timeouts, timeout)) + return FALSE; + + _dbus_timeout_ref (timeout); + + if (timeout_list->add_timeout_function != NULL) + (* timeout_list->add_timeout_function) (timeout, + timeout_list->timeout_data); + + return TRUE; +} + +/** + * Removes a timeout from the watch list, invoking the + * application's DBusRemoveTimeoutFunction if appropriate. + * + * @param timeout_list the timeout list. + * @param timeout the timeout to remove. + */ +void +_dbus_timeout_list_remove_timeout (DBusTimeoutList *timeout_list, + DBusTimeout *timeout) +{ + if (!_dbus_list_remove (&timeout_list->timeouts, timeout)) + _dbus_assert_not_reached ("Nonexistent timeout was removed"); + + if (timeout_list->remove_timeout_function != NULL) + (* timeout_list->remove_timeout_function) (timeout, + timeout_list->timeout_data); + + _dbus_timeout_unref (timeout); +} + +/** @} */ + +/** + * @defgroup DBusTimeout DBusTimeout + * @ingroup DBus + * @brief Object representing a timeout + * + * Types and functions related to DBusTimeout. A timeout + * represents a timeout that the main loop needs to monitor, + * as in Qt's QTimer or GLib's g_timeout_add(). + * + * @{ + */ + + +/** + * @typedef DBusTimeout + * + * Opaque object representing a timeout. + */ + +/** + * Gets the timeout interval. + * @param timeout the DBusTimeout object. + * @returns the interval in milliseconds. + */ +int +dbus_timeout_get_interval (DBusTimeout *timeout) +{ + return timeout->interval; +} + +/** + * Gets data previously set with dbus_timeout_set_data() + * or #NULL if none. + * + * @param timeout the DBusTimeout object. + * @returns previously-set data. + */ +void* +dbus_timeout_get_data (DBusTimeout *timeout) +{ + return timeout->data; +} + +/** + * Sets data which can be retrieved with dbus_timeout_get_data(). + * Intended for use by the DBusAddTimeoutFunction and + * DBusRemoveTimeoutFunction to store their own data. For example with + * Qt you might store the QTimer for this timeout and with GLib + * you might store a g_timeout_add result id. + * + * @param timeout the DBusTimeout object. + * @param data the data. + * @param free_data_function function to be called to free the data. + */ +void +dbus_timeout_set_data (DBusTimeout *timeout, + void *data, + DBusFreeFunction free_data_function) +{ + if (timeout->free_data_function != NULL) + (* timeout->free_data_function) (timeout->data); + + timeout->data = data; + timeout->free_data_function = free_data_function; +} + +/** + * Calls the timeout handler for this timeout. + * This function should be called when the timeout + * occurs. + * + * @param timeout the DBusTimeout object. + */ +void +dbus_timeout_handle (DBusTimeout *timeout) +{ + (* timeout->handler) (timeout->handler_data); +} |