summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac2
-rw-r--r--src/syncevo/SyncConfig.cpp44
-rw-r--r--src/syncevo/SyncConfig.h2
-rw-r--r--src/syncevo/SyncContext.cpp44
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) {