diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/syncevo/SyncConfig.cpp | 44 | ||||
-rw-r--r-- | src/syncevo/SyncConfig.h | 2 | ||||
-rw-r--r-- | src/syncevo/SyncContext.cpp | 44 |
4 files changed, 87 insertions, 5 deletions
diff --git a/configure.ac b/configure.ac index be784937..9d831e68 100644 --- a/configure.ac +++ b/configure.ac @@ -25,7 +25,7 @@ SE_CHECK_FOR_STABLE_RELEASE # Minimum version of libsynthesis as defined in its # configure script and thus .pc files: -define([SYNTHESIS_MIN_VERSION], [3.4.0.16.8]) +define([SYNTHESIS_MIN_VERSION], [3.4.0.16.9]) # Line above is patched by gen-autotools.sh. Handle # both "yes" and "no". diff --git a/src/syncevo/SyncConfig.cpp b/src/syncevo/SyncConfig.cpp index 9631b2f9..382714aa 100644 --- a/src/syncevo/SyncConfig.cpp +++ b/src/syncevo/SyncConfig.cpp @@ -32,6 +32,7 @@ #include <syncevo/IniConfigNode.h> #include <syncevo/Cmdline.h> #include <syncevo/lcs.h> +#include <syncevo/ThreadSupport.h> #include <test.h> #include <synthesis/timeutil.h> @@ -1363,10 +1364,28 @@ static ConfigProperty syncPropSyncMLVersion("SyncMLVersion", "Instead or in adddition to the version, several keywords can\n" "be set in this property (separated by spaces or commas):\n" "\n" - "- NOCTCAP = avoid sending CtCap meta information\n" - "- NORESTART = disable the sync mode extension that SyncEvolution\n" + "- NOCTCAP - avoid sending CtCap meta information\n" + "- NORESTART - disable the sync mode extension that SyncEvolution\n" " client and server use to negotiate whether both sides support\n" " running multiple sync iterations in the same session\n" + "- REQUESTMAXTIME=<time> - override the rate at which the\n" + " SyncML server sends preliminary replies while preparing\n" + " local storages in the background. This helps to avoid timeouts\n" + " in the SyncML client. Depends on multithreading.\n" +#ifdef HAVE_THREAD_SUPPORT + // test-dbus.py checks for 'is thread-safe'! + " This SyncEvolution binary is thread-safe and thus this feature\n" + " is enabled by default for HTTP servers, with a delay of 2 minutes\n" + " between messages. Other servers (Bluetooth, local sync) should not\n" + " need preliminary replies and the feature is disabled, although\n" + " it can be enabled by setting the time explicitly.\n" +#else + " This SyncEvolution binary is not thread-safe and thus this feature\n" + " is disabled by default, although it can be enabled if absolutely\n" + " needed by setting the time explicitly.\n" +#endif + " <time> can be specified like other durations in the config,\n" + " for example as REQUESTMAXTIME=2m.\n" "\n" "Setting these flags should only be necessary as workaround for\n" "broken peers.\n" @@ -1968,6 +1987,27 @@ InitStateString SyncConfig::getSyncMLVersion() const { } return InitStateString("", flags.wasSet()); } +InitState<unsigned int> SyncConfig::getRequestMaxTime() const { + InitState<unsigned int> requestmaxtime; + InitState< std::set<std::string> > flags = getSyncMLFlags(); + BOOST_FOREACH(const std::string &flag, flags) { + size_t offset = flag.find('='); + if (offset != flag.npos) { + std::string key = flag.substr(0, offset); + if (boost::iequals(key, "RequestMaxTime")) { + std::string value = flag.substr(offset + 1); + unsigned int seconds; + std::string error; + if (!SecondsConfigProperty::parseDuration(value, error, seconds)) { + SE_THROW("invalid RequestMaxTime value in SyncMLVersion property: " + error); + } + requestmaxtime = seconds; + break; + } + } + } + return requestmaxtime; +} InitState< std::set<std::string> > SyncConfig::getSyncMLFlags() const { InitStateString value = syncPropSyncMLVersion.getProperty(*getNode(syncPropSyncMLVersion)); std::list<std::string> keywords; diff --git a/src/syncevo/SyncConfig.h b/src/syncevo/SyncConfig.h index f051d192..57126fb7 100644 --- a/src/syncevo/SyncConfig.h +++ b/src/syncevo/SyncConfig.h @@ -1514,6 +1514,8 @@ class SyncConfig { /** all flags that are set in the SyncMLVersion property, including the 1.0/1.1/1.2 versions */ virtual InitState< std::set<std::string> > getSyncMLFlags() const; + virtual InitState<unsigned int> getRequestMaxTime() const; + /** * An arbitrary name assigned to the peer configuration, * not necessarily unique. Can be used by a GUI instead diff --git a/src/syncevo/SyncContext.cpp b/src/syncevo/SyncContext.cpp index 148f8c68..a2b2b338 100644 --- a/src/syncevo/SyncContext.cpp +++ b/src/syncevo/SyncContext.cpp @@ -27,6 +27,7 @@ #include <syncevo/SyncSource.h> #include <syncevo/util.h> #include <syncevo/SuspendFlags.h> +#include <syncevo/ThreadSupport.h> #include <syncevo/SafeConfigNode.h> #include <syncevo/IniConfigNode.h> @@ -2429,7 +2430,45 @@ void SyncContext::getConfigXML(string &xml, string &configname) " <server type='plugin'>\n" " <plugin_module>SyncEvolution</plugin_module>\n" " <plugin_sessionauth>yes</plugin_sessionauth>\n" - " <plugin_deviceadmin>yes</plugin_deviceadmin>\n" + " <plugin_deviceadmin>yes</plugin_deviceadmin>\n"; + + InitState<unsigned int> configrequestmaxtime = getRequestMaxTime(); + unsigned int requestmaxtime; + if (configrequestmaxtime.wasSet()) { + // Explicitly set, use it regardless of the kind of sync. + // We allow this even if thread support was not available, + // because if a user enables it explicitly, it's probably + // for a good reason (= failing client), in which case + // risking multithreading issues is preferable. + requestmaxtime = configrequestmaxtime.get(); + } else if (m_remoteInitiated || m_localSync) { + // We initiated the sync (local sync, Bluetooth). The client + // should not time out, so there is no need for intermediate + // message sending. + // + // To avoid potential problems and get a single log file, + // avoid it and multithreading by default. + requestmaxtime = 0; + } else { + // We were contacted by an HTTP client. Reply to client + // not later than 120 seconds while storage initializes + // in a background thread. +#ifdef HAVE_THREAD_SUPPORT + requestmaxtime = 120; // default in seconds +#else + requestmaxtime = 0; +#endif + } + if (requestmaxtime) { + clientorserver << + " <multithread>yes</multithread>\n" + " <requestmaxtime>" << requestmaxtime << "</requestmaxtime>\n"; + } else { + clientorserver << + " <multithread>no</multithread>\n"; + } + + clientorserver << "\n" << sessioninitscript << " <sessiontimeout>300</sessiontimeout>\n" @@ -2454,6 +2493,7 @@ void SyncContext::getConfigXML(string &xml, string &configname) clientorserver << " <client type='plugin'>\n" " <binfilespath>$(binfilepath)</binfilespath>\n" + " <multithread>no</multithread>\n" " <defaultauth/>\n"; if (getRefreshSync()) { clientorserver << @@ -2511,7 +2551,7 @@ void SyncContext::getConfigXML(string &xml, string &configname) " <timestamp>yes</timestamp>\n" " <timestampall>yes</timestampall>\n" " <timedsessionlognames>no</timedsessionlognames>\n" - " <subthreadmode>suppress</subthreadmode>\n" + " <subthreadmode>separate</subthreadmode>\n" " <logsessionstoglobal>yes</logsessionstoglobal>\n" " <singlegloballog>yes</singlegloballog>\n"; if (logging) { |