diff options
author | Havoc Pennington <hp@redhat.com> | 2003-03-14 01:27:58 +0000 |
---|---|---|
committer | Havoc Pennington <hp@redhat.com> | 2003-03-14 01:27:58 +0000 |
commit | 3bea935316ff048e68dea6a26c2e8e9fd314477f (patch) | |
tree | 498e62121c89d78693070d04e6bc6a6462efe2a7 /dbus | |
parent | 81c30364c291045d556c88f6818033104e627b6e (diff) |
2003-03-13 Havoc Pennington <hp@redhat.com>
* dbus/dbus-timeout.c (_dbus_timeout_list_set_functions): handle
out of memory
* dbus/dbus-watch.c (_dbus_watch_list_set_functions): handle out
of memory
* dbus/dbus-connection.h: Make AddWatchFunction and
AddTimeoutFunction return a bool so they can fail on out-of-memory
* bus/bus.c (bus_context_new): set up timeout handlers
* bus/connection.c (bus_connections_setup_connection): set up
timeout handlers
* glib/dbus-gmain.c: adapt to the fact that set_functions stuff
can fail
* bus/bus.c (bus_context_new): adapt to changes
* bus/connection.c: adapt to changes
* test/watch.c: adapt to DBusWatch changes
* bus/dispatch.c (bus_dispatch_test): started adding this but
didn't finish
Diffstat (limited to 'dbus')
-rw-r--r-- | dbus/dbus-connection.c | 36 | ||||
-rw-r--r-- | dbus/dbus-connection.h | 54 | ||||
-rw-r--r-- | dbus/dbus-server.c | 22 | ||||
-rw-r--r-- | dbus/dbus-server.h | 45 | ||||
-rw-r--r-- | dbus/dbus-timeout.c | 58 | ||||
-rw-r--r-- | dbus/dbus-timeout.h | 2 | ||||
-rw-r--r-- | dbus/dbus-watch.c | 58 | ||||
-rw-r--r-- | dbus/dbus-watch.h | 2 |
8 files changed, 182 insertions, 95 deletions
diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index bfc27e2a..19fe717d 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -1810,31 +1810,44 @@ dbus_connection_dispatch_message (DBusConnection *connection) * * It is not allowed to reference a DBusWatch after it has been passed * to remove_function. + * + * If #FALSE is returned due to lack of memory, the failure may be due + * to a #FALSE return from the new add_function. If so, the + * add_function may have been called successfully one or more times, + * but the remove_function will also have been called to remove any + * successful adds. i.e. if #FALSE is returned the net result + * should be that dbus_connection_set_watch_functions() has no effect, + * but the add_function and remove_function may have been called. * * @param connection the connection. * @param add_function function to begin monitoring a new descriptor. * @param remove_function function to stop monitoring a descriptor. * @param data data to pass to add_function and remove_function. * @param free_data_function function to be called to free the data. + * @returns #FALSE on failure (no memory) */ -void +dbus_bool_t dbus_connection_set_watch_functions (DBusConnection *connection, DBusAddWatchFunction add_function, DBusRemoveWatchFunction remove_function, void *data, DBusFreeFunction free_data_function) { + dbus_bool_t retval; + dbus_mutex_lock (connection->mutex); /* ref connection for slightly better reentrancy */ _dbus_connection_ref_unlocked (connection); - _dbus_watch_list_set_functions (connection->watches, - add_function, remove_function, - data, free_data_function); + retval = _dbus_watch_list_set_functions (connection->watches, + add_function, remove_function, + data, free_data_function); dbus_mutex_unlock (connection->mutex); /* drop our paranoid refcount */ dbus_connection_unref (connection); + + return retval; } /** @@ -1855,25 +1868,30 @@ dbus_connection_set_watch_functions (DBusConnection *connection, * @param remove_function function to remove a timeout. * @param data data to pass to add_function and remove_function. * @param free_data_function function to be called to free the data. + * @returns #FALSE on failure (no memory) */ -void +dbus_bool_t dbus_connection_set_timeout_functions (DBusConnection *connection, DBusAddTimeoutFunction add_function, DBusRemoveTimeoutFunction remove_function, void *data, DBusFreeFunction free_data_function) { + dbus_bool_t retval; + dbus_mutex_lock (connection->mutex); /* ref connection for slightly better reentrancy */ _dbus_connection_ref_unlocked (connection); - _dbus_timeout_list_set_functions (connection->timeouts, - add_function, remove_function, - data, free_data_function); + retval = _dbus_timeout_list_set_functions (connection->timeouts, + add_function, remove_function, + data, free_data_function); dbus_mutex_unlock (connection->mutex); /* drop our paranoid refcount */ - dbus_connection_unref (connection); + dbus_connection_unref (connection); + + return retval; } /** diff --git a/dbus/dbus-connection.h b/dbus/dbus-connection.h index 6b480136..bf0983e6 100644 --- a/dbus/dbus-connection.h +++ b/dbus/dbus-connection.h @@ -56,17 +56,15 @@ typedef enum * can be present in current state). */ } DBusWatchFlags; -typedef void (* DBusAddWatchFunction) (DBusWatch *watch, - void *data); - -typedef void (* DBusRemoveWatchFunction) (DBusWatch *watch, - void *data); - -typedef void (* DBusWakeupMainFunction) (void *data); -typedef void (* DBusAddTimeoutFunction) (DBusTimeout *timeout, - void *data); -typedef void (* DBusRemoveTimeoutFunction) (DBusTimeout *timeout, - void *data); +typedef dbus_bool_t (* DBusAddWatchFunction) (DBusWatch *watch, + void *data); +typedef void (* DBusRemoveWatchFunction) (DBusWatch *watch, + void *data); +typedef void (* DBusWakeupMainFunction) (void *data); +typedef dbus_bool_t (* DBusAddTimeoutFunction) (DBusTimeout *timeout, + void *data); +typedef void (* DBusRemoveTimeoutFunction) (DBusTimeout *timeout, + void *data); DBusConnection* dbus_connection_open (const char *address, DBusResultCode *result); @@ -99,24 +97,24 @@ DBusMessage *dbus_connection_send_with_reply_and_block (DBusConnection *conn DBusError *error); +dbus_bool_t dbus_connection_set_watch_functions (DBusConnection *connection, + DBusAddWatchFunction add_function, + DBusRemoveWatchFunction remove_function, + void *data, + DBusFreeFunction free_data_function); +dbus_bool_t dbus_connection_set_timeout_functions (DBusConnection *connection, + DBusAddTimeoutFunction add_function, + DBusRemoveTimeoutFunction remove_function, + void *data, + DBusFreeFunction free_data_function); +void dbus_connection_set_wakeup_main_function (DBusConnection *connection, + DBusWakeupMainFunction wakeup_main_function, + void *data, + DBusFreeFunction free_data_function); +void dbus_connection_handle_watch (DBusConnection *connection, + DBusWatch *watch, + unsigned int condition); -void dbus_connection_set_watch_functions (DBusConnection *connection, - DBusAddWatchFunction add_function, - DBusRemoveWatchFunction remove_function, - void *data, - DBusFreeFunction free_data_function); -void dbus_connection_set_timeout_functions (DBusConnection *connection, - DBusAddTimeoutFunction add_function, - DBusRemoveTimeoutFunction remove_function, - void *data, - DBusFreeFunction free_data_function); -void dbus_connection_set_wakeup_main_function (DBusConnection *connection, - DBusWakeupMainFunction wakeup_main_function, - void *data, - DBusFreeFunction free_data_function); -void dbus_connection_handle_watch (DBusConnection *connection, - DBusWatch *watch, - unsigned int condition); diff --git a/dbus/dbus-server.c b/dbus/dbus-server.c index 0065e510..99a5a2af 100644 --- a/dbus/dbus-server.c +++ b/dbus/dbus-server.c @@ -392,19 +392,20 @@ dbus_server_set_new_connection_function (DBusServer *server, * @param remove_function function to stop monitoring a descriptor. * @param data data to pass to add_function and remove_function. * @param free_data_function function to be called to free the data. + * @returns #FALSE on failure (no memory) */ -void +dbus_bool_t dbus_server_set_watch_functions (DBusServer *server, DBusAddWatchFunction add_function, DBusRemoveWatchFunction remove_function, void *data, DBusFreeFunction free_data_function) { - _dbus_watch_list_set_functions (server->watches, - add_function, - remove_function, - data, - free_data_function); + return _dbus_watch_list_set_functions (server->watches, + add_function, + remove_function, + data, + free_data_function); } /** @@ -419,17 +420,18 @@ dbus_server_set_watch_functions (DBusServer *server, * @param remove_function function to remove a timeout. * @param data data to pass to add_function and remove_function. * @param free_data_function function to be called to free the data. + * @returns #FALSE on failure (no memory) */ -void +dbus_bool_t dbus_server_set_timeout_functions (DBusServer *server, DBusAddTimeoutFunction add_function, DBusRemoveTimeoutFunction remove_function, void *data, DBusFreeFunction free_data_function) { - _dbus_timeout_list_set_functions (server->timeouts, - add_function, remove_function, - data, free_data_function); + return _dbus_timeout_list_set_functions (server->timeouts, + add_function, remove_function, + data, free_data_function); } /** diff --git a/dbus/dbus-server.h b/dbus/dbus-server.h index fc3a57e7..6665335b 100644 --- a/dbus/dbus-server.h +++ b/dbus/dbus-server.h @@ -45,31 +45,28 @@ void dbus_server_ref (DBusServer *server); void dbus_server_unref (DBusServer *server); void dbus_server_disconnect (DBusServer *server); dbus_bool_t dbus_server_get_is_connected (DBusServer *server); +void dbus_server_set_new_connection_function (DBusServer *server, + DBusNewConnectionFunction function, + void *data, + DBusFreeFunction free_data_function); +dbus_bool_t dbus_server_set_watch_functions (DBusServer *server, + DBusAddWatchFunction add_function, + DBusRemoveWatchFunction remove_function, + void *data, + DBusFreeFunction free_data_function); +dbus_bool_t dbus_server_set_timeout_functions (DBusServer *server, + DBusAddTimeoutFunction add_function, + DBusRemoveTimeoutFunction remove_function, + void *data, + DBusFreeFunction free_data_function); +void dbus_server_handle_watch (DBusServer *server, + DBusWatch *watch, + unsigned int condition); +void dbus_server_set_max_connections (DBusServer *server, + int max_connections); +int dbus_server_get_max_connections (DBusServer *server); +int dbus_server_get_n_connections (DBusServer *server); -void dbus_server_set_new_connection_function (DBusServer *server, - DBusNewConnectionFunction function, - void *data, - DBusFreeFunction free_data_function); -void dbus_server_set_watch_functions (DBusServer *server, - DBusAddWatchFunction add_function, - DBusRemoveWatchFunction remove_function, - void *data, - DBusFreeFunction free_data_function); -void dbus_server_set_timeout_functions (DBusServer *server, - DBusAddTimeoutFunction add_function, - DBusRemoveTimeoutFunction remove_function, - void *data, - DBusFreeFunction free_data_function); -void dbus_server_handle_watch (DBusServer *server, - DBusWatch *watch, - unsigned int condition); - - -void dbus_server_set_max_connections (DBusServer *server, - int max_connections); -int dbus_server_get_max_connections (DBusServer *server); - -int dbus_server_get_n_connections (DBusServer *server); int dbus_server_allocate_data_slot (void); void dbus_server_free_data_slot (int slot); diff --git a/dbus/dbus-timeout.c b/dbus/dbus-timeout.c index 379aeee3..408de422 100644 --- a/dbus/dbus-timeout.c +++ b/dbus/dbus-timeout.c @@ -181,15 +181,50 @@ _dbus_timeout_list_free (DBusTimeoutList *timeout_list) * @param remove_function the remove timeout function. * @param data the data for those functions. * @param free_data_function the function to free the data. + * @returns #FALSE if no memory * */ -void +dbus_bool_t _dbus_timeout_list_set_functions (DBusTimeoutList *timeout_list, DBusAddTimeoutFunction add_function, DBusRemoveTimeoutFunction remove_function, void *data, DBusFreeFunction free_data_function) { + /* Add timeouts with the new function, failing on OOM */ + if (add_function != NULL) + { + DBusList *link; + + link = _dbus_list_get_first_link (&timeout_list->timeouts); + while (link != NULL) + { + DBusList *next = _dbus_list_get_next_link (&timeout_list->timeouts, + link); + + if (!(* add_function) (link->data, data)) + { + /* remove it all again and return FALSE */ + DBusList *link2; + + link2 = _dbus_list_get_first_link (&timeout_list->timeouts); + while (link2 != link) + { + DBusList *next = _dbus_list_get_next_link (&timeout_list->timeouts, + link2); + + (* remove_function) (link2->data, data); + + link2 = next; + } + + return FALSE; + } + + link = next; + } + } + /* Remove all current timeouts from previous timeout handlers */ if (timeout_list->remove_timeout_function != NULL) @@ -207,13 +242,7 @@ _dbus_timeout_list_set_functions (DBusTimeoutList *timeout_list, 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); - } + return TRUE; } /** @@ -234,14 +263,21 @@ _dbus_timeout_list_add_timeout (DBusTimeoutList *timeout_list, _dbus_timeout_ref (timeout); if (timeout_list->add_timeout_function != NULL) - (* timeout_list->add_timeout_function) (timeout, - timeout_list->timeout_data); + { + if (!(* timeout_list->add_timeout_function) (timeout, + timeout_list->timeout_data)) + { + _dbus_list_remove_last (&timeout_list->timeouts, timeout); + _dbus_timeout_unref (timeout); + return FALSE; + } + } return TRUE; } /** - * Removes a timeout from the watch list, invoking the + * Removes a timeout from the timeout list, invoking the * application's DBusRemoveTimeoutFunction if appropriate. * * @param timeout_list the timeout list. diff --git a/dbus/dbus-timeout.h b/dbus/dbus-timeout.h index b596bfa1..9de12e8f 100644 --- a/dbus/dbus-timeout.h +++ b/dbus/dbus-timeout.h @@ -44,7 +44,7 @@ void _dbus_timeout_unref (DBusTimeout *timeout); DBusTimeoutList *_dbus_timeout_list_new (void); void _dbus_timeout_list_free (DBusTimeoutList *timeout_list); -void _dbus_timeout_list_set_functions (DBusTimeoutList *timeout_list, +dbus_bool_t _dbus_timeout_list_set_functions (DBusTimeoutList *timeout_list, DBusAddTimeoutFunction add_function, DBusRemoveTimeoutFunction remove_function, void *data, diff --git a/dbus/dbus-watch.c b/dbus/dbus-watch.c index 681da939..ef2a0ed9 100644 --- a/dbus/dbus-watch.c +++ b/dbus/dbus-watch.c @@ -159,7 +159,7 @@ struct DBusWatchList DBusList *watches; /**< Watch objects. */ DBusAddWatchFunction add_watch_function; /**< Callback for adding a watch. */ - DBusAddWatchFunction remove_watch_function; /**< Callback for removing a watch. */ + DBusRemoveWatchFunction remove_watch_function; /**< Callback for removing a watch. */ void *watch_data; /**< Data for watch callbacks */ DBusFreeFunction watch_free_data_function; /**< Free function for watch callback data */ }; @@ -212,15 +212,50 @@ _dbus_watch_list_free (DBusWatchList *watch_list) * @param remove_function the remove watch function. * @param data the data for those functions. * @param free_data_function the function to free the data. + * @returns #FALSE if not enough memory * */ -void +dbus_bool_t _dbus_watch_list_set_functions (DBusWatchList *watch_list, DBusAddWatchFunction add_function, DBusRemoveWatchFunction remove_function, void *data, DBusFreeFunction free_data_function) { + /* Add watches with the new watch function, failing on OOM */ + if (add_function != NULL) + { + DBusList *link; + + link = _dbus_list_get_first_link (&watch_list->watches); + while (link != NULL) + { + DBusList *next = _dbus_list_get_next_link (&watch_list->watches, + link); + + if (!(* add_function) (link->data, data)) + { + /* remove it all again and return FALSE */ + DBusList *link2; + + link2 = _dbus_list_get_first_link (&watch_list->watches); + while (link2 != link) + { + DBusList *next = _dbus_list_get_next_link (&watch_list->watches, + link2); + + (* remove_function) (link2->data, data); + + link2 = next; + } + + return FALSE; + } + + link = next; + } + } + /* Remove all current watches from previous watch handlers */ if (watch_list->remove_watch_function != NULL) @@ -238,13 +273,7 @@ _dbus_watch_list_set_functions (DBusWatchList *watch_list, watch_list->watch_data = data; watch_list->watch_free_data_function = free_data_function; - /* Re-add all pending watches */ - if (watch_list->add_watch_function != NULL) - { - _dbus_list_foreach (&watch_list->watches, - (DBusForeachFunction) watch_list->add_watch_function, - watch_list->watch_data); - } + return TRUE; } /** @@ -265,8 +294,15 @@ _dbus_watch_list_add_watch (DBusWatchList *watch_list, _dbus_watch_ref (watch); if (watch_list->add_watch_function != NULL) - (* watch_list->add_watch_function) (watch, - watch_list->watch_data); + { + if (!(* watch_list->add_watch_function) (watch, + watch_list->watch_data)) + { + _dbus_list_remove_last (&watch_list->watches, watch); + _dbus_watch_unref (watch); + return FALSE; + } + } return TRUE; } diff --git a/dbus/dbus-watch.h b/dbus/dbus-watch.h index 869605ae..9d85737e 100644 --- a/dbus/dbus-watch.h +++ b/dbus/dbus-watch.h @@ -43,7 +43,7 @@ void _dbus_watch_sanitize_condition (DBusWatch *watch, DBusWatchList* _dbus_watch_list_new (void); void _dbus_watch_list_free (DBusWatchList *watch_list); -void _dbus_watch_list_set_functions (DBusWatchList *watch_list, +dbus_bool_t _dbus_watch_list_set_functions (DBusWatchList *watch_list, DBusAddWatchFunction add_function, DBusRemoveWatchFunction remove_function, void *data, |