X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;ds=sidebyside;f=dbind%2Fdbind.c;h=e154f8571a3a8c79f646c1b497cd841a52e79130;hb=3785cfb93aa4a29b70ffdd39686f14d2c8e26b0b;hp=23046f2f31cfc1a7b945db6fd04aaef9b7f3f27c;hpb=850fb83e06e088487e26888e03445beb2cb3cd18;p=platform%2Fupstream%2Fat-spi2-core.git diff --git a/dbind/dbind.c b/dbind/dbind.c index 23046f2..e154f85 100644 --- a/dbind/dbind.c +++ b/dbind/dbind.c @@ -1,11 +1,31 @@ - +/* + * Copyright 2008-2011 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ #include #include +#include +#include #include #include "config.h" #include "dbind/dbind.h" +#include "atspi/atspi-gmain.h" static int dbind_timeout = -1; @@ -30,34 +50,76 @@ set_reply (DBusPendingCall * pending, void *user_data) dbus_pending_call_unref (pending); } +static gint +time_elapsed (struct timeval *origin) +{ + struct timeval tv; + + gettimeofday (&tv, NULL); + return (tv.tv_sec - origin->tv_sec) * 1000 + (tv.tv_usec - origin->tv_usec) / 1000; +} + 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; + static gboolean in_dispatch = FALSE; if (unique_name && destination && strcmp (destination, unique_name) != 0) - return dbus_connection_send_with_reply_and_block (bus, message, dbind_timeout, error); + { + ret = dbus_connection_send_with_reply_and_block (bus, message, + dbind_timeout, error); + if (g_main_depth () == 0 && !in_dispatch) + { + in_dispatch = TRUE; + while (dbus_connection_dispatch (bus) == DBUS_DISPATCH_DATA_REMAINS); + in_dispatch = FALSE; + } + return ret; + } - closure.reply = NULL; - dbus_connection_setup_with_g_main(bus, NULL); - if (!dbus_connection_send_with_reply (bus, message, &pending, dbind_timeout)) + closure = g_new0 (SpiReentrantCallClosure, 1); + closure->reply = NULL; + if (!dbus_connection_send_with_reply (bus, message, &pending, dbind_timeout) + || !pending) + { + g_free (closure); 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; - while (!closure.reply) + closure->reply = NULL; + gettimeofday (&tv, NULL); + dbus_pending_call_ref (pending); + while (!closure->reply) { if (!dbus_connection_read_write_dispatch (bus, dbind_timeout)) - return NULL; + { + //dbus_pending_call_set_notify (pending, NULL, NULL, NULL); + dbus_pending_call_cancel (pending); + dbus_pending_call_unref (pending); + return NULL; + } + if (time_elapsed (&tv) > dbind_timeout) + { + //dbus_pending_call_set_notify (pending, NULL, NULL, NULL); + dbus_pending_call_cancel (pending); + dbus_pending_call_unref (pending); + dbus_set_error_const (error, "org.freedesktop.DBus.Error.NoReply", + "timeout from dbind"); + return NULL; + } } - return closure.reply; + ret = closure->reply; + dbus_pending_call_unref (pending); + return ret; } dbus_bool_t @@ -77,11 +139,12 @@ dbind_method_call_reentrant_va (DBusConnection *cnx, const char *p; va_list args_demarshal; + dbus_error_init (&real_err); + va_copy (args_demarshal, args); if (opt_error) err = opt_error; else { - dbus_error_init (&real_err); err = &real_err; } @@ -99,7 +162,6 @@ dbind_method_call_reentrant_va (DBusConnection *cnx, if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) { - const char *name = dbus_message_get_error_name (reply); goto out; } /* demarshal */ @@ -107,6 +169,17 @@ dbind_method_call_reentrant_va (DBusConnection *cnx, { DBusMessageIter iter; dbus_message_iter_init (reply, &iter); + if (strcmp (p + 2, dbus_message_get_signature (reply)) != 0) + { + g_warning ("dbind: Call to \"%s\" returned signature %s; expected %s", + method, dbus_message_get_signature (reply), p + 2); + if (opt_error) + dbus_set_error (opt_error, DBUS_ERROR_INVALID_ARGS, + "Call to \"%s\" returned signature %s; expected %s", + method, dbus_message_get_signature (reply), + p + 2); + goto out; + } p = arg_types; dbind_any_demarshal_va (&iter, &p, args_demarshal); } @@ -119,8 +192,8 @@ out: if (reply) dbus_message_unref (reply); - if (err == &real_err) - dbus_error_free (err); + if (dbus_error_is_set (&real_err)) + dbus_error_free (&real_err); va_end (args_demarshal); return success; @@ -172,6 +245,7 @@ dbind_method_call_reentrant (DBusConnection *cnx, /*---------------------------------------------------------------------------*/ +/* TODO: opt_error is unused; should be removed */ dbus_bool_t dbind_emit_signal_va (DBusConnection *cnx, const char *path, @@ -184,16 +258,8 @@ dbind_emit_signal_va (DBusConnection *cnx, dbus_bool_t success = FALSE; DBusMessage *msg = NULL; DBusMessageIter iter; - DBusError *err, real_err; const char *p; - if (opt_error) - err = opt_error; - else { - dbus_error_init (&real_err); - err = &real_err; - } - msg = dbus_message_new_signal (path, interface, signal); if (!msg) goto out; @@ -211,9 +277,6 @@ out: if (msg) dbus_message_unref (msg); - if (err == &real_err) - dbus_error_free (err); - return success; }