summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Ohly <patrick.ohly@intel.com>2010-09-03 15:40:05 +0200
committerPatrick Ohly <patrick.ohly@intel.com>2010-09-03 15:40:05 +0200
commit9286d914c064f5e3966fee149224eeb78a7123c8 (patch)
tree95124723e413be1b371f25338394cca890334bdb
parenta5e6f4840ba15bffce8b5188f0e8b866729c75fd (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.in12
-rw-r--r--configure-pre.in1
-rw-r--r--debian/dbus-wrapper.cpp57
-rw-r--r--src/syncevo/eds_abi_wrapper.cpp44
-rw-r--r--src/syncevolution.cpp12
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