summaryrefslogtreecommitdiff
path: root/dbind
diff options
context:
space:
mode:
authorMike Gorse <mgorse@novell.com>2011-05-22 21:53:36 -0500
committerMike Gorse <mgorse@novell.com>2011-05-22 21:53:36 -0500
commit9fb1d178240b34b1f9037bb52e8695d708a6983e (patch)
treecdaf06a94487b377e27f2904351b2781432f8325 /dbind
parent78beee3d5f5f919fd2ec1ed99bef9a4126c0b56c (diff)
downloadat-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.c27
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