diff options
author | Mike Gorse <mgorse@novell.com> | 2011-05-22 21:53:36 -0500 |
---|---|---|
committer | Mike Gorse <mgorse@novell.com> | 2011-05-22 21:53:36 -0500 |
commit | 9fb1d178240b34b1f9037bb52e8695d708a6983e (patch) | |
tree | cdaf06a94487b377e27f2904351b2781432f8325 | |
parent | 78beee3d5f5f919fd2ec1ed99bef9a4126c0b56c (diff) | |
download | at-spi2-core-9fb1d178240b34b1f9037bb52e8695d708a6983e.tar.gz |
Dynamically allocate reentrant call closures
Putting reentrant call closures on the stack can be dangerous if set_reply
is called after the caller has timed out and returned, for instance, so better
to dynamically allocate them. This will hopefully fix some crashes and
hopefully not leak memory.
-rw-r--r-- | dbind/dbind.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/dbind/dbind.c b/dbind/dbind.c index ad349513..60b6fbfa 100644 --- a/dbind/dbind.c +++ b/dbind/dbind.c @@ -63,34 +63,41 @@ DBusMessage * dbind_send_and_allow_reentry (DBusConnection * bus, DBusMessage * message, DBusError *error) { DBusPendingCall *pending; - SpiReentrantCallClosure closure; + SpiReentrantCallClosure *closure; const char *unique_name = dbus_bus_get_unique_name (bus); const char *destination = dbus_message_get_destination (message); struct timeval tv; + DBusMessage *ret; if (unique_name && destination && strcmp (destination, unique_name) != 0) return dbus_connection_send_with_reply_and_block (bus, message, dbind_timeout, error); - closure.reply = NULL; + closure = g_new0 (SpiReentrantCallClosure, 1); + closure->reply = NULL; atspi_dbus_connection_setup_with_g_main(bus, NULL); if (!dbus_connection_send_with_reply (bus, message, &pending, dbind_timeout)) return NULL; if (!pending) return NULL; - dbus_pending_call_set_notify (pending, set_reply, (void *) &closure, NULL); + dbus_pending_call_set_notify (pending, set_reply, (void *) closure, g_free); - closure.reply = NULL; + closure->reply = NULL; gettimeofday (&tv, NULL); - while (!closure.reply) + dbus_pending_call_ref (pending); + while (!closure->reply) { - if (!dbus_connection_read_write_dispatch (bus, dbind_timeout)) - return NULL; -if (time_elapsed (&tv) > dbind_timeout) - return NULL; + if (!dbus_connection_read_write_dispatch (bus, dbind_timeout) || + time_elapsed (&tv) > dbind_timeout) + { + dbus_pending_call_unref (pending); + return NULL; + } } - return closure.reply; + ret = closure->reply; + dbus_pending_call_unref (pending); + return ret; } dbus_bool_t |