2003-10-28 Havoc Pennington <hp@redhat.com>

* bus/expirelist.c (do_expiration_with_current_time): detect
	failure of the expire_func due to OOM

	* bus/connection.c (bus_pending_reply_expired): return FALSE on OOM

	* bus/dispatch.c (check_send_exit_to_service): fix to handle the
	NoReply error that's now created by the bus when the service exits
This commit is contained in:
Havoc Pennington 2003-10-28 23:51:24 +00:00
parent e11ae72466
commit bebc830fc4
5 changed files with 92 additions and 31 deletions

View file

@ -1,3 +1,13 @@
2003-10-28 Havoc Pennington <hp@redhat.com>
* bus/expirelist.c (do_expiration_with_current_time): detect
failure of the expire_func due to OOM
* bus/connection.c (bus_pending_reply_expired): return FALSE on OOM
* bus/dispatch.c (check_send_exit_to_service): fix to handle the
NoReply error that's now created by the bus when the service exits
2003-10-28 Havoc Pennington <hp@redhat.com> 2003-10-28 Havoc Pennington <hp@redhat.com>
* dbus/dbus-message.c (_dbus_message_test): enable and fix the * dbus/dbus-message.c (_dbus_message_test): enable and fix the

View file

@ -80,9 +80,9 @@ typedef struct
int stamp; /**< connections->stamp last time we were traversed */ int stamp; /**< connections->stamp last time we were traversed */
} BusConnectionData; } BusConnectionData;
static void bus_pending_reply_expired (BusExpireList *list, static dbus_bool_t bus_pending_reply_expired (BusExpireList *list,
DBusList *link, DBusList *link,
void *data); void *data);
static void bus_connection_drop_pending_replies (BusConnections *connections, static void bus_connection_drop_pending_replies (BusConnections *connections,
DBusConnection *connection); DBusConnection *connection);
@ -1392,7 +1392,7 @@ bus_pending_reply_send_no_reply (BusConnections *connections,
return retval; return retval;
} }
static void static dbus_bool_t
bus_pending_reply_expired (BusExpireList *list, bus_pending_reply_expired (BusExpireList *list,
DBusList *link, DBusList *link,
void *data) void *data)
@ -1414,20 +1414,22 @@ bus_pending_reply_expired (BusExpireList *list,
transaction = bus_transaction_new (connections->context); transaction = bus_transaction_new (connections->context);
if (transaction == NULL) if (transaction == NULL)
return; return FALSE;
if (!bus_pending_reply_send_no_reply (connections, if (!bus_pending_reply_send_no_reply (connections,
transaction, transaction,
pending)) pending))
{ {
bus_transaction_cancel_and_free (transaction); bus_transaction_cancel_and_free (transaction);
return; return FALSE;
} }
_dbus_list_remove_link (&connections->pending_replies->items, _dbus_list_remove_link (&connections->pending_replies->items,
link); link);
bus_pending_reply_free (pending); bus_pending_reply_free (pending);
bus_transaction_execute_and_free (transaction); bus_transaction_execute_and_free (transaction);
return TRUE;
} }
static void static void

View file

@ -415,16 +415,20 @@ warn_unexpected_real (DBusConnection *connection,
const char *function, const char *function,
int line) int line)
{ {
_dbus_warn ("%s:%d received message interface \"%s\" member \"%s\" error name \"%s\" on %p, expecting %s\n", if (message)
function, line, _dbus_warn ("%s:%d received message interface \"%s\" member \"%s\" error name \"%s\" on %p, expecting %s\n",
dbus_message_get_interface (message) ? function, line,
dbus_message_get_interface (message) : "(unset)", dbus_message_get_interface (message) ?
dbus_message_get_member (message) ? dbus_message_get_interface (message) : "(unset)",
dbus_message_get_member (message) : "(unset)", dbus_message_get_member (message) ?
dbus_message_get_error_name (message) ? dbus_message_get_member (message) : "(unset)",
dbus_message_get_error_name (message) : "(unset)", dbus_message_get_error_name (message) ?
connection, dbus_message_get_error_name (message) : "(unset)",
expected); connection,
expected);
else
_dbus_warn ("%s:%d received no message on %p, expecting %s\n",
function, line, connection, expected);
} }
#define warn_unexpected(connection, message, expected) \ #define warn_unexpected(connection, message, expected) \
@ -1428,12 +1432,6 @@ check_service_deactivated (BusContext *context,
if (csdd.failed) if (csdd.failed)
goto out; goto out;
if (!check_no_leftovers (context))
{
_dbus_warn ("Messages were left over after verifying results of service exiting\n");
goto out;
}
retval = TRUE; retval = TRUE;
@ -1519,6 +1517,13 @@ check_send_exit_to_service (BusContext *context,
message = pop_message_waiting_for_memory (connection); message = pop_message_waiting_for_memory (connection);
_dbus_assert (message != NULL); _dbus_assert (message != NULL);
if (dbus_message_get_reply_serial (message) != serial)
{
warn_unexpected (connection, message,
"error with the correct reply serial");
goto out;
}
if (!dbus_message_is_error (message, if (!dbus_message_is_error (message,
DBUS_ERROR_NO_MEMORY)) DBUS_ERROR_NO_MEMORY))
{ {
@ -1540,8 +1545,45 @@ check_send_exit_to_service (BusContext *context,
if (!check_service_deactivated (context, connection, if (!check_service_deactivated (context, connection,
service_name, base_service)) service_name, base_service))
goto out; goto out;
}
/* Should now have a NoReply error from the Exit() method
* call; it should have come after all the deactivation
* stuff.
*/
message = pop_message_waiting_for_memory (connection);
if (message == NULL)
{
warn_unexpected (connection, NULL,
"reply to Exit() method call");
goto out;
}
if (!dbus_message_is_error (message,
DBUS_ERROR_NO_REPLY))
{
warn_unexpected (connection, NULL,
"NoReply error from Exit() method call");
goto out;
}
if (dbus_message_get_reply_serial (message) != serial)
{
warn_unexpected (connection, message,
"error with the correct reply serial");
goto out;
}
_dbus_verbose ("Got error %s after test service exited\n",
dbus_message_get_error_name (message));
if (!check_no_leftovers (context))
{
_dbus_warn ("Messages were left over after %s\n",
_DBUS_FUNCTION_NAME);
goto out;
}
}
retval = TRUE; retval = TRUE;
out: out:

View file

@ -143,11 +143,16 @@ do_expiration_with_current_time (BusExpireList *list,
_dbus_verbose ("Expiring an item %p\n", item); _dbus_verbose ("Expiring an item %p\n", item);
/* If the expire function fails, we just end up expiring /* If the expire function fails, we just end up expiring
* this item next time we walk through the list. Which is in * this item next time we walk through the list. This would
* indeterminate time since we don't know what next_interval * be an indeterminate time normally, so we set up the
* will be. * next_interval to be "shortly" (just enough to avoid
* a busy loop)
*/ */
(* list->expire_func) (list, link, list->data); if (!(* list->expire_func) (list, link, list->data))
{
next_interval = _dbus_get_oom_wait ();
break;
}
} }
else else
{ {
@ -205,7 +210,7 @@ typedef struct
int expire_count; int expire_count;
} TestExpireItem; } TestExpireItem;
static void static dbus_bool_t
test_expire_func (BusExpireList *list, test_expire_func (BusExpireList *list,
DBusList *link, DBusList *link,
void *data) void *data)
@ -215,6 +220,8 @@ test_expire_func (BusExpireList *list,
t = (TestExpireItem*) link->data; t = (TestExpireItem*) link->data;
t->expire_count += 1; t->expire_count += 1;
return TRUE;
} }
static void static void

View file

@ -31,9 +31,9 @@
typedef struct BusExpireList BusExpireList; typedef struct BusExpireList BusExpireList;
typedef struct BusExpireItem BusExpireItem; typedef struct BusExpireItem BusExpireItem;
typedef void (* BusExpireFunc) (BusExpireList *list, typedef dbus_bool_t (* BusExpireFunc) (BusExpireList *list,
DBusList *link, DBusList *link,
void *data); void *data);
struct BusExpireList struct BusExpireList
{ {