X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;ds=sidebyside;f=dbind%2Fdbind.c;h=e154f8571a3a8c79f646c1b497cd841a52e79130;hb=3785cfb93aa4a29b70ffdd39686f14d2c8e26b0b;hp=a5da81d92366ae71d51bc7951ec173be8a9e4d7f;hpb=febc57fdd883c96a471a970f6801af9d5a5bdf92;p=platform%2Fupstream%2Fat-spi2-core.git diff --git a/dbind/dbind.c b/dbind/dbind.c index a5da81d..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; @@ -18,7 +38,6 @@ static int dbind_timeout = -1; typedef struct _SpiReentrantCallClosure { - GMainLoop *loop; DBusMessage *reply; } SpiReentrantCallClosure; @@ -28,41 +47,79 @@ set_reply (DBusPendingCall * pending, void *user_data) SpiReentrantCallClosure* closure = (SpiReentrantCallClosure *) user_data; closure->reply = dbus_pending_call_steal_reply (pending); - g_main_loop_quit (closure->loop); + 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; - - if (strcmp (dbus_message_get_destination (message), - dbus_bus_get_unique_name (bus)) != 0) - return dbus_connection_send_with_reply_and_block (bus, message, dbind_timeout, error); - - if (!dbus_connection_send_with_reply (bus, message, &pending, dbind_timeout)) - return NULL; - dbus_pending_call_set_notify (pending, set_reply, (void *) &closure, NULL); - closure.loop = g_main_loop_new (NULL, FALSE); - dbus_connection_setup_with_g_main(bus, NULL); + 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) + { + 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; + } - if (1) + closure = g_new0 (SpiReentrantCallClosure, 1); + closure->reply = NULL; + if (!dbus_connection_send_with_reply (bus, message, &pending, dbind_timeout) + || !pending) { - g_main_loop_run (closure.loop); + g_free (closure); + return NULL; } - else + dbus_pending_call_set_notify (pending, set_reply, (void *) closure, g_free); + + closure->reply = NULL; + gettimeofday (&tv, NULL); + dbus_pending_call_ref (pending); + while (!closure->reply) { - closure.reply = NULL; - while (!closure.reply) + if (!dbus_connection_read_write_dispatch (bus, dbind_timeout)) { - 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; } } - g_main_loop_unref (closure.loop); - return closure.reply; + ret = closure->reply; + dbus_pending_call_unref (pending); + return ret; } dbus_bool_t @@ -82,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; } @@ -104,8 +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); - dbus_set_error (err, name, g_strdup ("")); goto out; } /* demarshal */ @@ -113,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); } @@ -125,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; @@ -178,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, @@ -190,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; @@ -217,9 +277,6 @@ out: if (msg) dbus_message_unref (msg); - if (err == &real_err) - dbus_error_free (err); - return success; }