diff options
author | Patrick Ohly <patrick.ohly@intel.com> | 2010-09-03 15:40:05 +0200 |
---|---|---|
committer | Patrick Ohly <patrick.ohly@intel.com> | 2010-09-03 15:40:05 +0200 |
commit | 9286d914c064f5e3966fee149224eeb78a7123c8 (patch) | |
tree | 95124723e413be1b371f25338394cca890334bdb | |
parent | a5e6f4840ba15bffce8b5188f0e8b866729c75fd (diff) |
EDS: workaround for D-Bus method timeouts (BMC #4026)
libecal/ebook implementation based on D-Bus (Evolution >= 2.30)
inevitably will run into D-Bus timeouts as the amount of data
increases.
This patch moves an earlier hack written for Maemo into the core
code and enables it by default, if the EDS backends are active.
It works by intercepting dbus_connection_send_with_reply()
and substituting timeout_milliseconds==-1 ("default timeout
of 25 seconds") with timeout_milliseconds=INT_MAX ("no timeout").
Setting SYNCEVOLUTION_DBUS_TIMEOUT to number of milliseconds
allows controlling the final timeout value.
-rw-r--r-- | configure-post.in | 12 | ||||
-rw-r--r-- | configure-pre.in | 1 | ||||
-rw-r--r-- | debian/dbus-wrapper.cpp | 57 | ||||
-rw-r--r-- | src/syncevo/eds_abi_wrapper.cpp | 44 | ||||
-rw-r--r-- | src/syncevolution.cpp | 12 |
5 files changed, 56 insertions, 70 deletions
diff --git a/configure-post.in b/configure-post.in index 54fa56bb..2f805f75 100644 --- a/configure-post.in +++ b/configure-post.in @@ -129,6 +129,17 @@ if test ! "$docdir"; then AC_SUBST(docdir) fi +AC_ARG_ENABLE(dbus-timeout-hack, + AS_HELP_STRING([--enable-dbus-timeout-hack], + [Enables code which overrides the default timeout in dbus_connection_send_with_reply() so that the method call never times out. Needed for libecal/ebook >= 2.30, so enabled by default if either of these is enabled.]), + [enable_dbus_timeout_hack=$enableval], + [if test $enable_ebook = "yes" || test $enable_ecal = "yes"; then + enable_dbus_timeout_hack="yes" + fi]) +if test $enable_dbus_timeout_hack = "yes"; then + AC_DEFINE(ENABLE_DBUS_TIMEOUT_HACK, 1, [overrides the default D-Bus timeout so that synchronous calls never time out]) +fi + AC_CONFIG_FILES(Makefile src/dbus/interfaces/Makefile src/gdbus/Makefile src/dbus/Makefile src/Makefile src/syncevo/Makefile src/syncevo/syncevolution.pc src/syncevo/configs/Makefile src/synthesis-includes/Makefile src/gtk-ui/Makefile po/Makefile.in test/Makefile src/dbus/syncevo-dbus.pc) AC_OUTPUT @@ -145,4 +156,5 @@ echo "Bluetooth transport: $have_bluetooth" echo "GNOME Bluetooth panel plugin: $enable_gnome_bluetooth_panel" echo "SHA-256: $have_sha" echo "API documentation: $enable_doc" +echo "D-Bus Timeout Hack: $enable_dbus_timeout_hack" echo diff --git a/configure-pre.in b/configure-pre.in index 72eede0f..0b97611b 100644 --- a/configure-pre.in +++ b/configure-pre.in @@ -93,7 +93,6 @@ AC_ARG_ENABLE(developer-mode, enable_developer_mode="$enableval", enable_developer_mode="no") # Maemo hacks: -# - set the (non-standard!) DBUS_DEFAULT_TIMEOUT # - wrap e_book_from_string() to fix invalid parameter # - don't use UTF-8 encoding in Perl script AC_ARG_ENABLE(maemo, diff --git a/debian/dbus-wrapper.cpp b/debian/dbus-wrapper.cpp deleted file mode 100644 index 1fffb7e4..00000000 --- a/debian/dbus-wrapper.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2008 Patrick Ohly - * - * 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) version 3. - * - * 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 <dlfcn.h> - -/** - * There are valid use cases where the (previously hard-coded) default - * timeout was too short. This function replaces _DBUS_DEFAULT_TIMEOUT_VALUE - * and - if set - interprets the content of DBUS_DEFAULT_TIMEOUT as - * number of milliseconds. - */ -static int _dbus_connection_default_timeout(void) -{ - const char *def = getenv("DBUS_DEFAULT_TIMEOUT"); - int timeout = 0; - - if (def) { - timeout = atoi(def); - } - if (timeout <= 0) { - /* the traditional _DBUS_DEFAULT_TIMEOUT_VALUE */ - timeout = 25 * 1000; - } -} - -extern "C" int -dbus_connection_send_with_reply (void *connection, - void *message, - void **pending_return, - int timeout_milliseconds) -{ - static typeof(dbus_connection_send_with_reply) *real_func; - - if (!real_func) { - real_func = (typeof(dbus_connection_send_with_reply) *)dlsym(RTLD_NEXT, "dbus_connection_send_with_reply"); - } - return real_func ? - real_func(connection, message, pending_return, - timeout_milliseconds == -1 ? _dbus_connection_default_timeout() : timeout_milliseconds) : - 0; -} diff --git a/src/syncevo/eds_abi_wrapper.cpp b/src/syncevo/eds_abi_wrapper.cpp index 2802b03b..d49343db 100644 --- a/src/syncevo/eds_abi_wrapper.cpp +++ b/src/syncevo/eds_abi_wrapper.cpp @@ -370,3 +370,47 @@ extern "C" void EDSAbiWrapperInit() extern "C" const char *EDSAbiWrapperInfo() { EDSAbiWrapperInit(); return lookupInfo.c_str(); } extern "C" const char *EDSAbiWrapperDebug() { EDSAbiWrapperInit(); return lookupDebug.c_str(); } +#ifdef ENABLE_DBUS_TIMEOUT_HACK +/** + * There are valid use cases where the (previously hard-coded) default + * timeout was too short. For example, libecal and libebook >= 2.30 + * implement their synchronous API with synchronous D-Bus method calls, + * which inevitably suffers from timeouts on slow hardware with large + * amount of data (MBC #4026). + * + * This function replaces _DBUS_DEFAULT_TIMEOUT_VALUE and - if set - + * interprets the content of SYNCEVOLUTION_DBUS_TIMEOUT as number of + * milliseconds. 0 disables timeouts, which is also the default if the + * env variable is not set. + */ +static int _dbus_connection_default_timeout(void) +{ + const char *def = getenv("SYNCEVOLUTION_DBUS_TIMEOUT"); + int timeout = 0; + + if (def) { + timeout = atoi(def); + } + if (timeout == 0) { + timeout = INT_MAX; + } + return timeout; +} + +extern "C" int +dbus_connection_send_with_reply (void *connection, + void *message, + void **pending_return, + int timeout_milliseconds) +{ + static typeof(dbus_connection_send_with_reply) *real_func; + + if (!real_func) { + real_func = (typeof(dbus_connection_send_with_reply) *)dlsym(RTLD_NEXT, "dbus_connection_send_with_reply"); + } + return real_func ? + real_func(connection, message, pending_return, + timeout_milliseconds == -1 ? _dbus_connection_default_timeout() : timeout_milliseconds) : + 0; +} +#endif // ENABLE_DBUS_TIMEOUT_HACK diff --git a/src/syncevolution.cpp b/src/syncevolution.cpp index 34f1ee46..14c11087 100644 --- a/src/syncevolution.cpp +++ b/src/syncevolution.cpp @@ -453,18 +453,6 @@ static void getEnvVars(map<string, string> &vars); extern "C" int main( int argc, char **argv ) { -#ifdef ENABLE_MAEMO - // EDS-DBus uses potentially long-running calls which may fail due - // to the default 25s timeout. Some of these can be replaced by - // their async version, but e_book_async_get_changes() still - // triggered it. - // - // The workaround for this is to link the binary against a libdbus - // which has the dbus-timeout.patch and thus let's users and - // the application increase the default timeout. - setenv("DBUS_DEFAULT_TIMEOUT", "600000", 0); -#endif - // Intercept stderr and route it through our logging. // stdout is printed normally. Deconstructing it when // leaving main() does one final processing of pending |