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 /dbind | |
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.
Diffstat (limited to 'dbind')
-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 |