C++: replace boost::shared_ptr, boost::function, boost::bind

We can use std::shared_ptr and std::function instead now.

Lambdas are usually a better alternative to boost/std::bind. The
downside is the need to explicitly specify parameters completely. When
inlining callbacks entirely with lambdas, duplication of that
parameter list can be avoided.

Whenever possible, use std::make_shared to construct objects that are
tracked by std::shared_ptr.

Some objects need a std::weak_ptr during object destruction. For that
we have to use our own implementation of std::enable_shared_from_this,
with a matching creator function. The additional benefit is that we
can get rid of explicit static "create" methods by making that create
function a friend.

Signed-off-by: Patrick Ohly <patrick.ohly@intel.com>
This commit is contained in:
Patrick Ohly 2018-01-16 17:17:34 +01:00
parent d0c08bf0dd
commit 2fa3c3335a
154 changed files with 3278 additions and 3781 deletions

View File

@ -70,9 +70,9 @@ void ActiveSyncCalendarSource::beginSync(const std::string &lastToken, const std
size_t nextpos = value.find('/', pos + 1); size_t nextpos = value.find('/', pos + 1);
if (nextpos != value.npos) { if (nextpos != value.npos) {
std::string uid = m_escape.unescape(value.substr(pos + 1, nextpos - pos - 1)); std::string uid = m_escape.unescape(value.substr(pos + 1, nextpos - pos - 1));
boost::shared_ptr<Event> &eventptr = m_cache[easid]; std::shared_ptr<Event> &eventptr = m_cache[easid];
if (!eventptr) { if (!eventptr) {
eventptr = boost::shared_ptr<Event>(new Event); eventptr = std::make_shared<Event>();
} }
eventptr->m_easid = easid; eventptr->m_easid = easid;
eventptr->m_uid = uid; eventptr->m_uid = uid;
@ -220,7 +220,7 @@ void ActiveSyncCalendarSource::beginSync(const std::string &lastToken, const std
// old items + new (added to m_events above) - deleted (removed above) // old items + new (added to m_events above) - deleted (removed above)
for (const auto &entry: m_cache) { for (const auto &entry: m_cache) {
const std::string &easid = entry.first; const std::string &easid = entry.first;
const boost::shared_ptr<Event> &eventptr = entry.second; const std::shared_ptr<Event> &eventptr = entry.second;
for (const std::string &subid: eventptr->m_subids) { for (const std::string &subid: eventptr->m_subids) {
SE_LOG_DEBUG(getDisplayName(), "existing eas item %s = uid %s + rid %s", SE_LOG_DEBUG(getDisplayName(), "existing eas item %s = uid %s + rid %s",
easid.c_str(), eventptr->m_uid.c_str(), subid.c_str()); easid.c_str(), eventptr->m_uid.c_str(), subid.c_str());
@ -235,7 +235,7 @@ std::string ActiveSyncCalendarSource::endSync(bool success)
if (success) { if (success) {
for (const auto &entry: m_cache) { for (const auto &entry: m_cache) {
const std::string &easid = entry.first; const std::string &easid = entry.first;
const boost::shared_ptr<Event> &eventptr = entry.second; const std::shared_ptr<Event> &eventptr = entry.second;
std::stringstream buffer; std::stringstream buffer;
buffer << "//"; // use same format as in MapSyncSource, just in case - was '/' << m_escape.escape(ids.m_revision) << '/'; buffer << "//"; // use same format as in MapSyncSource, just in case - was '/' << m_escape.escape(ids.m_revision) << '/';
buffer << m_escape.escape(eventptr->m_uid) << '/'; buffer << m_escape.escape(eventptr->m_uid) << '/';
@ -324,12 +324,12 @@ ActiveSyncCalendarSource::Event &ActiveSyncCalendarSource::loadItem(Event &event
ActiveSyncCalendarSource::Event &ActiveSyncCalendarSource::setItemData(const std::string &easid, const std::string &data) ActiveSyncCalendarSource::Event &ActiveSyncCalendarSource::setItemData(const std::string &easid, const std::string &data)
{ {
boost::shared_ptr<Event> &eventptr = m_cache[easid]; std::shared_ptr<Event> &eventptr = m_cache[easid];
if (eventptr) { if (eventptr) {
eventptr->m_uid.clear(); eventptr->m_uid.clear();
eventptr->m_subids.clear(); eventptr->m_subids.clear();
} else { } else {
eventptr = boost::shared_ptr<Event>(new Event); eventptr = std::make_shared<Event>();
} }
Event &event = *eventptr; Event &event = *eventptr;
@ -408,7 +408,7 @@ SyncSourceRaw::InsertItemResult ActiveSyncCalendarSource::insertItem(const std::
const std::string &callerSubID = ids.second; const std::string &callerSubID = ids.second;
// parse new event // parse new event
boost::shared_ptr<Event> newEvent(new Event); auto newEvent = std::make_shared<Event>();
newEvent->m_calendar.set(icalcomponent_new_from_string((char *)item.c_str()), // hack for old libical newEvent->m_calendar.set(icalcomponent_new_from_string((char *)item.c_str()), // hack for old libical
"parsing iCalendar 2.0"); "parsing iCalendar 2.0");
icalcomponent *firstcomp = NULL; icalcomponent *firstcomp = NULL;

View File

@ -30,7 +30,7 @@
#include <syncevo/SmartPtr.h> #include <syncevo/SmartPtr.h>
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include <boost/shared_ptr.hpp> #include <memory>
#include <syncevo/declarations.h> #include <syncevo/declarations.h>
SE_BEGIN_CXX SE_BEGIN_CXX
@ -119,7 +119,7 @@ class ActiveSyncCalendarSource : public ActiveSyncCalFormatSource
* A cache of information about each merged item. Maps from * A cache of information about each merged item. Maps from
* easid to Event. * easid to Event.
*/ */
class EventCache : public std::map<std::string, boost::shared_ptr<Event> > class EventCache : public std::map<std::string, std::shared_ptr<Event> >
{ {
public: public:
EventCache() : m_initialized(false) {} EventCache() : m_initialized(false) {}
@ -141,7 +141,7 @@ class ActiveSyncCalendarSource : public ActiveSyncCalFormatSource
* On-disk representation of m_cache (without the item data). * On-disk representation of m_cache (without the item data).
* Format same as in MapSyncSource (code copied, refactor!). * Format same as in MapSyncSource (code copied, refactor!).
*/ */
boost::shared_ptr<ConfigNode> m_trackingNode; std::shared_ptr<ConfigNode> m_trackingNode;
}; };
SE_END_CXX SE_END_CXX

View File

@ -31,8 +31,6 @@
#include <syncevo/SmartPtr.h> #include <syncevo/SmartPtr.h>
#include <syncevo/GLibSupport.h> #include <syncevo/GLibSupport.h>
#include <boost/bind.hpp>
#include <string> #include <string>
#include <map> #include <map>
@ -135,7 +133,7 @@ class ActiveSyncSource :
// that we use a common prefix, so that we can use the key/value store // that we use a common prefix, so that we can use the key/value store
// also for other keys if the need ever arises). // also for other keys if the need ever arises).
m_itemNode(new PrefixConfigNode("item-", m_itemNode(new PrefixConfigNode("item-",
boost::shared_ptr<ConfigNode>(new SafeConfigNode(params.m_nodes.getTrackingNode())))), std::static_pointer_cast<ConfigNode>(std::make_shared<SafeConfigNode>(params.m_nodes.getTrackingNode())))),
m_context(params.m_context) m_context(params.m_context)
{ {
if (!m_context) { if (!m_context) {
@ -183,11 +181,11 @@ class ActiveSyncSource :
void findCollections(const std::string &account, bool force_update); void findCollections(const std::string &account, bool force_update);
std::string lookupFolder(const std::string &folder); std::string lookupFolder(const std::string &folder);
boost::shared_ptr<ConfigNode> m_itemNode; std::shared_ptr<ConfigNode> m_itemNode;
private: private:
/** "target-config@<context>" instance which holds our username == ActiveSync account ID */ /** "target-config@<context>" instance which holds our username == ActiveSync account ID */
boost::shared_ptr<SyncConfig> m_context; std::shared_ptr<SyncConfig> m_context;
/** account ID for libeas, must be set in "username" config property */ /** account ID for libeas, must be set in "username" config property */
std::string m_account; std::string m_account;
@ -208,7 +206,7 @@ class ActiveSyncSource :
* server-side IDs of all items, updated as changes are reported and/or are made; * server-side IDs of all items, updated as changes are reported and/or are made;
* NULL if not using change tracking * NULL if not using change tracking
*/ */
boost::shared_ptr<ConfigNode> m_ids; std::shared_ptr<ConfigNode> m_ids;
/** /**
* cache of all items, filled at begin of session and updated as * cache of all items, filled at begin of session and updated as

View File

@ -114,7 +114,7 @@ class ActiveSyncsTest : public CppUnit::TestFixture {
protected: protected:
void testInstantiate() { void testInstantiate() {
boost::shared_ptr<SyncSource> source; std::shared_ptr<SyncSource> source;
source.reset(SyncSource::createTestingSource("contacts", "ActiveSync Address Book", true)); source.reset(SyncSource::createTestingSource("contacts", "ActiveSync Address Book", true));
source.reset(SyncSource::createTestingSource("events", "ActiveSync Events", true)); source.reset(SyncSource::createTestingSource("events", "ActiveSync Events", true));
source.reset(SyncSource::createTestingSource("todos", "ActiveSync Todos", true)); source.reset(SyncSource::createTestingSource("todos", "ActiveSync Todos", true));
@ -218,17 +218,20 @@ static void updateConfigEAS(const RegisterSyncSourceTest */* me */,
// cannot run tests involving a second database: // cannot run tests involving a second database:
// wrap orginal source creation, set default database for // wrap orginal source creation, set default database for
// database #0 and refuse to return a source for database #1 // database #0 and refuse to return a source for database #1
config.m_createSourceA = boost::bind(createEASSource, config.m_createSourceA, config.m_createSourceA = [create=config.m_createSourceA] (ClientTest &client, const std::string &clientID, int source, bool isSourceA) {
_1, _2, _3, _4); return createEASSource(create, client, clientID, source, isSourceA);
config.m_createSourceB = boost::bind(createEASSource, config.m_createSourceB, };
_1, _2, _3, _4); config.m_createSourceB = [create=config.m_createSourceB] (ClientTest &client, const std::string &clientID, int source, bool isSourceA) {
return createEASSource(create, client, clientID, source, isSourceA);
config.m_dump = boost::bind(DumpItems, _1, _2, _3, };
config.m_dump = [type] (ClientTest &client, TestingSyncSource &source, const std::string &file) {
return DumpItems(client, source, file,
type == EAS_ITEM_CONTACT || type == EAS_ITEM_CONTACT ||
// need to read from our cache for Google Calendar, // need to read from our cache for Google Calendar,
// because it does not support Fetch // because it does not support Fetch
strcmp(getEnv("CLIENT_TEST_SERVER", ""), "googleeas") strcmp(getEnv("CLIENT_TEST_SERVER", ""), "googleeas")
); );
};
config.m_sourceLUIDsAreVolatile = true; config.m_sourceLUIDsAreVolatile = true;
// TODO: find out how ActiveSync/Exchange handle children without parent; // TODO: find out how ActiveSync/Exchange handle children without parent;
// at the moment, the child is stored as if it was a stand-alone event // at the moment, the child is stored as if it was a stand-alone event

View File

@ -147,14 +147,14 @@ class AkonadiTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
protected: protected:
static string addItem(boost::shared_ptr<TestingSyncSource> source, static string addItem(std::shared_ptr<TestingSyncSource> source,
string &data) { string &data) {
SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data); SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data);
return res.m_luid; return res.m_luid;
} }
void testInstantiate() { void testInstantiate() {
boost::shared_ptr<SyncSource> source; std::shared_ptr<SyncSource> source;
// source.reset(SyncSource::createTestingSource("addressbook", "addressbook", true)); // source.reset(SyncSource::createTestingSource("addressbook", "addressbook", true));
// source.reset(SyncSource::createTestingSource("addressbook", "contacts", true)); // source.reset(SyncSource::createTestingSource("addressbook", "contacts", true));
source.reset(SyncSource::createTestingSource("addressbook", "kde-contacts", true)); source.reset(SyncSource::createTestingSource("addressbook", "kde-contacts", true));
@ -180,25 +180,25 @@ protected:
// TODO: support default databases // TODO: support default databases
// void testOpenDefaultAddressBook() { // void testOpenDefaultAddressBook() {
// boost::shared_ptr<TestingSyncSource> source; // std::shared_ptr<TestingSyncSource> source;
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("contacts", "kde-contacts", true, NULL)); // source.reset((TestingSyncSource *)SyncSource::createTestingSource("contacts", "kde-contacts", true, NULL));
// CPPUNIT_ASSERT_NO_THROW(source->open()); // CPPUNIT_ASSERT_NO_THROW(source->open());
// } // }
// void testOpenDefaultCalendar() { // void testOpenDefaultCalendar() {
// boost::shared_ptr<TestingSyncSource> source; // std::shared_ptr<TestingSyncSource> source;
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "kde-calendar", true, NULL)); // source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "kde-calendar", true, NULL));
// CPPUNIT_ASSERT_NO_THROW(source->open()); // CPPUNIT_ASSERT_NO_THROW(source->open());
// } // }
// void testOpenDefaultTodo() { // void testOpenDefaultTodo() {
// boost::shared_ptr<TestingSyncSource> source; // std::shared_ptr<TestingSyncSource> source;
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("tasks", "kde-tasks", true, NULL)); // source.reset((TestingSyncSource *)SyncSource::createTestingSource("tasks", "kde-tasks", true, NULL));
// CPPUNIT_ASSERT_NO_THROW(source->open()); // CPPUNIT_ASSERT_NO_THROW(source->open());
// } // }
// void testOpenDefaultMemo() { // void testOpenDefaultMemo() {
// boost::shared_ptr<TestingSyncSource> source; // std::shared_ptr<TestingSyncSource> source;
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("memos", "kde-memos", true, NULL)); // source.reset((TestingSyncSource *)SyncSource::createTestingSource("memos", "kde-memos", true, NULL));
// CPPUNIT_ASSERT_NO_THROW(source->open()); // CPPUNIT_ASSERT_NO_THROW(source->open());
// } // }
@ -209,7 +209,7 @@ protected:
prefix = "SyncEvolution_Test_"; prefix = "SyncEvolution_Test_";
} }
boost::shared_ptr<TestingSyncSource> source; std::shared_ptr<TestingSyncSource> source;
source.reset((TestingSyncSource *)SyncSource::createTestingSource("eds_event", "kde-calendar", true, prefix)); source.reset((TestingSyncSource *)SyncSource::createTestingSource("eds_event", "kde-calendar", true, prefix));
CPPUNIT_ASSERT_NO_THROW(source->open()); CPPUNIT_ASSERT_NO_THROW(source->open());

View File

@ -39,10 +39,6 @@
#include <syncevo/util.h> #include <syncevo/util.h>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/bind.hpp>
#include <QtCore/QDebug> #include <QtCore/QDebug>
SE_BEGIN_CXX SE_BEGIN_CXX
@ -75,7 +71,7 @@ bool AkonadiSyncSource::isEmpty()
{ {
if (!GRunIsMain()) { if (!GRunIsMain()) {
bool result; bool result;
GRunInMain(boost::lambda::var(result) = boost::lambda::bind(&AkonadiSyncSource::isEmpty, this)); GRunInMain([this, &result] () { result = isEmpty(); });
return result; return result;
} }
@ -90,7 +86,7 @@ bool AkonadiSyncSource::isEmpty()
void AkonadiSyncSource::start() void AkonadiSyncSource::start()
{ {
if (!GRunIsMain()) { if (!GRunIsMain()) {
GRunInMain(boost::bind(&AkonadiSyncSource::start, this)); GRunInMain([this]() { start(); });
return; return;
} }
@ -117,7 +113,7 @@ SyncSource::Databases AkonadiSyncSource::getDatabases()
{ {
if (!GRunIsMain()) { if (!GRunIsMain()) {
Databases result; Databases result;
GRunInMain(boost::lambda::var(result) = boost::lambda::bind(&AkonadiSyncSource::getDatabases, this)); GRunInMain([this, &result] () { result = getDatabases(); });
return result; return result;
} }
@ -155,7 +151,7 @@ SyncSource::Databases AkonadiSyncSource::getDatabases()
void AkonadiSyncSource::open() void AkonadiSyncSource::open()
{ {
if (!GRunIsMain()) { if (!GRunIsMain()) {
GRunInMain(boost::bind(&AkonadiSyncSource::open, this)); GRunInMain([this] () { open(); });
return; return;
} }
@ -223,7 +219,7 @@ void AkonadiSyncSource::open()
void AkonadiSyncSource::listAllItems(SyncSourceRevisions::RevisionMap_t &revisions) void AkonadiSyncSource::listAllItems(SyncSourceRevisions::RevisionMap_t &revisions)
{ {
if (!GRunIsMain()) { if (!GRunIsMain()) {
GRunInMain(boost::bind(&AkonadiSyncSource::listAllItems, this, boost::ref(revisions))); GRunInMain([this, &revisions] () { listAllItems(revisions); });
return; return;
} }
@ -251,7 +247,7 @@ TrackingSyncSource::InsertItemResult AkonadiSyncSource::insertItem(const std::st
{ {
if (!GRunIsMain()) { if (!GRunIsMain()) {
InsertItemResult result; InsertItemResult result;
GRunInMain(boost::lambda::var(result) = boost::lambda::bind(&AkonadiSyncSource::insertItem, this, boost::cref(luid), boost::cref(data), raw)); GRunInMain([this, &result, &luid, &data, raw] () { return insertItem(luid, data, raw); });
return result; return result;
} }
@ -296,7 +292,7 @@ TrackingSyncSource::InsertItemResult AkonadiSyncSource::insertItem(const std::st
void AkonadiSyncSource::removeItem(const string &luid) void AkonadiSyncSource::removeItem(const string &luid)
{ {
if (!GRunIsMain()) { if (!GRunIsMain()) {
GRunInMain(boost::bind(&AkonadiSyncSource::removeItem, this, boost::cref(luid))); GRunInMain([this, &luid] () { removeItem(luid); });
return; return;
} }
@ -313,7 +309,7 @@ void AkonadiSyncSource::removeItem(const string &luid)
void AkonadiSyncSource::readItem(const std::string &luid, std::string &data, bool raw) void AkonadiSyncSource::readItem(const std::string &luid, std::string &data, bool raw)
{ {
if (!GRunIsMain()) { if (!GRunIsMain()) {
GRunInMain(boost::bind(&AkonadiSyncSource::readItem, this, boost::cref(luid), boost::ref(data), raw)); GRunInMain([this, &luid, &data, raw] () { readItem(luid, data, raw); });
return; return;
} }

View File

@ -180,14 +180,7 @@ SyncSource::Databases EvolutionCalendarSource::getDatabases()
return result; return result;
} }
#ifdef USE_EDS_CLIENT #ifndef USE_EDS_CLIENT
static EClient *newECalClient(ESource *source,
ECalClientSourceType ecalSourceType,
GError **gerror)
{
return E_CLIENT(e_cal_client_new(source, ecalSourceType, gerror));
}
#else
char *EvolutionCalendarSource::authenticate(const char *prompt, char *EvolutionCalendarSource::authenticate(const char *prompt,
const char *key) const char *key)
{ {
@ -214,15 +207,15 @@ void EvolutionCalendarSource::open()
// be others with similar problems and for local storage it is // be others with similar problems and for local storage it is
// a reasonably cheap operation (so no harm there). // a reasonably cheap operation (so no harm there).
for (int retries = 0; retries < 2; retries++) { for (int retries = 0; retries < 2; retries++) {
auto create = [type=sourceType()] (ESource *source, GError **gerror) {
return E_CLIENT(e_cal_client_new(source, type, gerror));
};
m_calendar.reset(E_CAL_CLIENT(openESource(sourceExtension(), m_calendar.reset(E_CAL_CLIENT(openESource(sourceExtension(),
m_type == EVOLUTION_CAL_SOURCE_TYPE_EVENTS ? e_source_registry_ref_builtin_calendar : m_type == EVOLUTION_CAL_SOURCE_TYPE_EVENTS ? e_source_registry_ref_builtin_calendar :
m_type == EVOLUTION_CAL_SOURCE_TYPE_TASKS ? e_source_registry_ref_builtin_task_list : m_type == EVOLUTION_CAL_SOURCE_TYPE_TASKS ? e_source_registry_ref_builtin_task_list :
m_type == EVOLUTION_CAL_SOURCE_TYPE_MEMOS ? e_source_registry_ref_builtin_memo_list : m_type == EVOLUTION_CAL_SOURCE_TYPE_MEMOS ? e_source_registry_ref_builtin_memo_list :
NULL, NULL,
boost::bind(newECalClient, create).get()));
_1,
sourceType(),
_2)).get()));
} }
#else #else
GErrorCXX gerror; GErrorCXX gerror;
@ -303,7 +296,7 @@ bool EvolutionCalendarSource::isEmpty()
#ifdef USE_EDS_CLIENT #ifdef USE_EDS_CLIENT
class ECalClientViewSyncHandler { class ECalClientViewSyncHandler {
public: public:
typedef boost::function<void(const GSList *list)> Process_t; typedef std::function<void(const GSList *list)> Process_t;
ECalClientViewSyncHandler(ECalClientViewCXX &view, ECalClientViewSyncHandler(ECalClientViewCXX &view,
const Process_t &process) : const Process_t &process) :
@ -316,10 +309,10 @@ class ECalClientViewSyncHandler {
// Listen for view signals // Listen for view signals
m_view.connectSignal<ECalClientView *, m_view.connectSignal<ECalClientView *,
const GSList *>()("objects-added", const GSList *>()("objects-added",
boost::bind(m_process, _2)); [this] (ECalClientView *, const GSList *list) { m_process(list); });
m_view.connectSignal<EBookClientView *, m_view.connectSignal<ECalClientView *,
const GError *>()("complete", const GError *>()("complete",
boost::bind(&ECalClientViewSyncHandler::completed, this, _2)); [this] (ECalClientView *, const GError *gerror) { completed(gerror); });
// Start the view // Start the view
e_cal_client_view_start (m_view, m_error); e_cal_client_view_start (m_view, m_error);
@ -360,21 +353,7 @@ class ECalClientViewSyncHandler {
// Possible error while watching the view // Possible error while watching the view
GErrorCXX m_error; GErrorCXX m_error;
}; };
#endif // USE_EDS_CLIENT
static void list_revisions(const GSList *objects, EvolutionCalendarSource::RevisionMap_t *revisions)
{
const GSList *l;
for (l = objects; l; l = l->next) {
icalcomponent *icomp = (icalcomponent*)l->data;
EvolutionCalendarSource::ItemID id = EvolutionCalendarSource::getItemID(icomp);
string luid = id.getLUID();
string modTime = EvolutionCalendarSource::getItemModTime(icomp);
(*revisions)[luid] = modTime;
}
}
#endif
void EvolutionCalendarSource::listAllItems(RevisionMap_t &revisions) void EvolutionCalendarSource::listAllItems(RevisionMap_t &revisions)
{ {
@ -389,7 +368,18 @@ void EvolutionCalendarSource::listAllItems(RevisionMap_t &revisions)
// TODO: Optimization: use set fields_of_interest (UID / REV / LAST-MODIFIED) // TODO: Optimization: use set fields_of_interest (UID / REV / LAST-MODIFIED)
ECalClientViewSyncHandler handler(viewPtr, boost::bind(list_revisions, _1, &revisions)); auto process = [&revisions] (const GSList *objects) {
const GSList *l;
for (l = objects; l; l = l->next) {
icalcomponent *icomp = (icalcomponent*)l->data;
EvolutionCalendarSource::ItemID id = EvolutionCalendarSource::getItemID(icomp);
string luid = id.getLUID();
string modTime = EvolutionCalendarSource::getItemModTime(icomp);
revisions[luid] = modTime;
}
};
ECalClientViewSyncHandler handler(viewPtr, process);
if (!handler.processSync(gerror)) { if (!handler.processSync(gerror)) {
throwError(SE_HERE, "watching view", gerror); throwError(SE_HERE, "watching view", gerror);
} }
@ -646,7 +636,7 @@ EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(co
// Recreate any children removed earlier: when we get here, // Recreate any children removed earlier: when we get here,
// the parent exists and we must update it. // the parent exists and we must update it.
for (boost::shared_ptr< eptr<icalcomponent> > &icalcomp: children) { for (std::shared_ptr< eptr<icalcomponent> > &icalcomp: children) {
if ( if (
#ifdef USE_EDS_CLIENT #ifdef USE_EDS_CLIENT
!e_cal_client_modify_object_sync(m_calendar, *icalcomp, !e_cal_client_modify_object_sync(m_calendar, *icalcomp,
@ -738,7 +728,7 @@ EvolutionCalendarSource::InsertItemResult EvolutionCalendarSource::insertItem(co
// Recreate any children removed earlier: when we get here, // Recreate any children removed earlier: when we get here,
// the parent exists and we must update it. // the parent exists and we must update it.
for (boost::shared_ptr< eptr<icalcomponent> > &icalcomp: children) { for (std::shared_ptr< eptr<icalcomponent> > &icalcomp: children) {
if ( if (
#ifdef USE_EDS_CLIENT #ifdef USE_EDS_CLIENT
!e_cal_client_modify_object_sync(m_calendar, *icalcomp, !e_cal_client_modify_object_sync(m_calendar, *icalcomp,
@ -858,7 +848,7 @@ void EvolutionCalendarSource::removeItem(const string &luid)
// recreate children // recreate children
bool first = true; bool first = true;
for (boost::shared_ptr< eptr<icalcomponent> > &icalcomp: children) { for (std::shared_ptr< eptr<icalcomponent> > &icalcomp: children) {
if (first) { if (first) {
char *uid; char *uid;

View File

@ -263,7 +263,7 @@ class EvolutionCalendarSource : public EvolutionSyncSource,
* will destroy the smart pointer, which then calls * will destroy the smart pointer, which then calls
* icalcomponent_free(). * icalcomponent_free().
*/ */
typedef list< boost::shared_ptr< eptr<icalcomponent> > > ICalComps_t; typedef list< std::shared_ptr< eptr<icalcomponent> > > ICalComps_t;
/** /**
* Utility function which extracts all icalcomponents with * Utility function which extracts all icalcomponents with

View File

@ -124,14 +124,14 @@ class EvolutionCalendarTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
protected: protected:
static string addItem(boost::shared_ptr<TestingSyncSource> source, static string addItem(std::shared_ptr<TestingSyncSource> source,
string &data) { string &data) {
SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data); SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data);
return res.m_luid; return res.m_luid;
} }
void testInstantiate() { void testInstantiate() {
boost::shared_ptr<TestingSyncSource> source; std::shared_ptr<TestingSyncSource> source;
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "calendar", true)); source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "calendar", true));
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "evolution-calendar", true)); source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "evolution-calendar", true));
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "Evolution Calendar:text/calendar", true)); source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "Evolution Calendar:text/calendar", true));
@ -148,19 +148,19 @@ protected:
} }
void testOpenDefaultCalendar() { void testOpenDefaultCalendar() {
boost::shared_ptr<TestingSyncSource> source; std::shared_ptr<TestingSyncSource> source;
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "evolution-calendar", true, NULL)); source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "evolution-calendar", true, NULL));
CPPUNIT_ASSERT_NO_THROW(source->open()); CPPUNIT_ASSERT_NO_THROW(source->open());
} }
void testOpenDefaultTodo() { void testOpenDefaultTodo() {
boost::shared_ptr<TestingSyncSource> source; std::shared_ptr<TestingSyncSource> source;
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "evolution-tasks", true, NULL)); source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "evolution-tasks", true, NULL));
CPPUNIT_ASSERT_NO_THROW(source->open()); CPPUNIT_ASSERT_NO_THROW(source->open());
} }
void testOpenDefaultMemo() { void testOpenDefaultMemo() {
boost::shared_ptr<TestingSyncSource> source; std::shared_ptr<TestingSyncSource> source;
source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "evolution-memos", true, NULL)); source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "evolution-memos", true, NULL));
CPPUNIT_ASSERT_NO_THROW(source->open()); CPPUNIT_ASSERT_NO_THROW(source->open());
} }
@ -171,7 +171,7 @@ protected:
prefix = "SyncEvolution_Test_"; prefix = "SyncEvolution_Test_";
} }
boost::shared_ptr<TestingSyncSource> source; std::shared_ptr<TestingSyncSource> source;
source.reset((TestingSyncSource *)SyncSource::createTestingSource("eds_event", "evolution-calendar", true, prefix)); source.reset((TestingSyncSource *)SyncSource::createTestingSource("eds_event", "evolution-calendar", true, prefix));
CPPUNIT_ASSERT_NO_THROW(source->open()); CPPUNIT_ASSERT_NO_THROW(source->open());

View File

@ -287,7 +287,7 @@ bool EvolutionContactSource::isEmpty()
#ifdef USE_EDS_CLIENT #ifdef USE_EDS_CLIENT
class EBookClientViewSyncHandler { class EBookClientViewSyncHandler {
public: public:
typedef boost::function<void (const GSList *list)> Process_t; typedef std::function<void (const GSList *list)> Process_t;
EBookClientViewSyncHandler(const EBookClientViewCXX &view, EBookClientViewSyncHandler(const EBookClientViewCXX &view,
const Process_t &process) : const Process_t &process) :
@ -299,10 +299,10 @@ class EBookClientViewSyncHandler {
// Listen for view signals // Listen for view signals
m_view.connectSignal<EBookClientView *, m_view.connectSignal<EBookClientView *,
const GSList *>()("objects-added", const GSList *>()("objects-added",
boost::bind(m_process, _2)); [this] (EBookClientView *, const GSList *list) { m_process(list); } );
m_view.connectSignal<EBookClientView *, m_view.connectSignal<EBookClientView *,
const GError *>()("complete", const GError *>()("complete",
boost::bind(&EBookClientViewSyncHandler::completed, this, _2)); [this] (EBookClientView *, const GError *gerror) { completed(gerror); });
// Start the view // Start the view
e_book_client_view_start (m_view, m_error); e_book_client_view_start (m_view, m_error);
@ -334,39 +334,12 @@ class EBookClientViewSyncHandler {
private: private:
// Process list callback // Process list callback
boost::function<void (const GSList *list)> m_process; std::function<void (const GSList *list)> m_process;
// View watched // View watched
EBookClientViewCXX m_view; EBookClientViewCXX m_view;
// Possible error while watching the view // Possible error while watching the view
GErrorCXX m_error; GErrorCXX m_error;
}; };
static void list_revisions(const GSList *contacts, EvolutionContactSource::RevisionMap_t *revisions)
{
const GSList *l;
for (l = contacts; l; l = l->next) {
EContact *contact = E_CONTACT(l->data);
if (!contact) {
SE_THROW("contact entry without data");
}
pair<string, string> revmapping;
const char *uid = (const char *)e_contact_get_const(contact,
E_CONTACT_UID);
if (!uid || !uid[0]) {
SE_THROW("contact entry without UID");
}
revmapping.first = uid;
const char *rev = (const char *)e_contact_get_const(contact,
E_CONTACT_REV);
if (!rev || !rev[0]) {
SE_THROW(string("contact entry without REV: ") + revmapping.first);
}
revmapping.second = rev;
revisions->insert(revmapping);
}
}
#endif #endif
void EvolutionContactSource::listAllItems(RevisionMap_t &revisions) void EvolutionContactSource::listAllItems(RevisionMap_t &revisions)
@ -399,7 +372,28 @@ void EvolutionContactSource::listAllItems(RevisionMap_t &revisions)
gerror.clear(); gerror.clear();
} }
EBookClientViewSyncHandler handler(viewPtr, boost::bind(list_revisions, _1, &revisions)); auto process = [&revisions] (const GSList *contacts) {
const GSList *l;
for (l = contacts; l; l = l->next) {
EContact *contact = E_CONTACT(l->data);
if (!contact) {
SE_THROW("contact entry without data");
}
const char *uid = (const char *)e_contact_get_const(contact,
E_CONTACT_UID);
if (!uid || !uid[0]) {
SE_THROW("contact entry without UID");
}
const char *rev = (const char *)e_contact_get_const(contact,
E_CONTACT_REV);
if (!rev || !rev[0]) {
SE_THROW(string("contact entry without REV: ") + uid);
}
revisions[uid] = rev;
}
};
EBookClientViewSyncHandler handler(viewPtr, process);
if (!handler.process(gerror)) { if (!handler.process(gerror)) {
throwError(SE_HERE, "watching view", gerror); throwError(SE_HERE, "watching view", gerror);
} }
@ -525,7 +519,7 @@ void EvolutionContactSource::getReadAheadOrder(ReadAheadOrder &order,
luids = m_nextLUIDs; luids = m_nextLUIDs;
} }
void EvolutionContactSource::checkCacheForError(boost::shared_ptr<ContactCache> &cache) void EvolutionContactSource::checkCacheForError(std::shared_ptr<ContactCache> &cache)
{ {
if (cache->m_gerror) { if (cache->m_gerror) {
GErrorCXX gerror; GErrorCXX gerror;
@ -541,7 +535,7 @@ void EvolutionContactSource::invalidateCachedContact(const std::string &luid)
invalidateCachedContact(m_contactCacheNext, luid); invalidateCachedContact(m_contactCacheNext, luid);
} }
void EvolutionContactSource::invalidateCachedContact(boost::shared_ptr<ContactCache> &cache, const std::string &luid) void EvolutionContactSource::invalidateCachedContact(std::shared_ptr<ContactCache> &cache, const std::string &luid)
{ {
if (cache) { if (cache) {
ContactCache::iterator it = cache->find(luid); ContactCache::iterator it = cache->find(luid);
@ -670,7 +664,7 @@ static int MaxBatchSize()
return maxBatchSize; return maxBatchSize;
} }
boost::shared_ptr<ContactCache> EvolutionContactSource::startReading(const std::string &luid, ReadingMode mode) std::shared_ptr<ContactCache> EvolutionContactSource::startReading(const std::string &luid, ReadingMode mode)
{ {
SE_LOG_DEBUG(getDisplayName(), "reading: %s contact %s", SE_LOG_DEBUG(getDisplayName(), "reading: %s contact %s",
mode == START ? "must read" : mode == START ? "must read" :
@ -764,7 +758,7 @@ boost::shared_ptr<ContactCache> EvolutionContactSource::startReading(const std::
m_readAheadOrder = READ_NONE; m_readAheadOrder = READ_NONE;
} }
boost::shared_ptr<ContactCache> cache; std::shared_ptr<ContactCache> cache;
if (size) { if (size) {
// Prepare parameter for EDS C call. Ownership of query instances is in uidQueries array. // Prepare parameter for EDS C call. Ownership of query instances is in uidQueries array.
boost::scoped_array<EBookQuery *> queries(new EBookQuery *[size]); boost::scoped_array<EBookQuery *> queries(new EBookQuery *[size]);
@ -789,24 +783,11 @@ boost::shared_ptr<ContactCache> EvolutionContactSource::startReading(const std::
} }
m_contactsFromDB += size; m_contactsFromDB += size;
m_contactQueries++; m_contactQueries++;
SYNCEVO_GLIB_CALL_ASYNC(e_book_client_get_contacts, auto process = [this, cachePtr=std::weak_ptr<ContactCache>(cache)] (gboolean success, GSList *contactsPtr, const GError *gerror) noexcept {
boost::bind(&EvolutionContactSource::completedRead,
this,
boost::weak_ptr<ContactCache>(cache),
_1, _2, _3),
m_addressbook, sexp, NULL);
SE_LOG_DEBUG(getDisplayName(), "reading: started contact read %s", cache->m_name.c_str());
}
return cache;
}
typedef GListCXX< EContact, GSList, GObjectDestructor<EContact> > ContactListCXX;
void EvolutionContactSource::completedRead(const boost::weak_ptr<ContactCache> &cachePtr, gboolean success, GSList *contactsPtr, const GError *gerror) throw()
{
try { try {
using ContactListCXX = GListCXX< EContact, GSList, GObjectDestructor<EContact> >;
ContactListCXX contacts(contactsPtr); // transfers ownership ContactListCXX contacts(contactsPtr); // transfers ownership
boost::shared_ptr<ContactCache> cache = cachePtr.lock(); std::shared_ptr<ContactCache> cache = cachePtr.lock();
if (!cache) { if (!cache) {
SE_LOG_DEBUG(getDisplayName(), "reading: contact read finished, results no longer needed: %s", gerror ? gerror->message : "<<successful>>"); SE_LOG_DEBUG(getDisplayName(), "reading: contact read finished, results no longer needed: %s", gerror ? gerror->message : "<<successful>>");
return; return;
@ -828,6 +809,12 @@ void EvolutionContactSource::completedRead(const boost::weak_ptr<ContactCache> &
} catch (...) { } catch (...) {
Exception::handle(HANDLE_EXCEPTION_FATAL); Exception::handle(HANDLE_EXCEPTION_FATAL);
} }
};
SYNCEVO_GLIB_CALL_ASYNC(e_book_client_get_contacts, process,
m_addressbook, sexp, NULL);
SE_LOG_DEBUG(getDisplayName(), "reading: started contact read %s", cache->m_name.c_str());
}
return cache;
} }
void EvolutionContactSource::logCacheStats(Logger::Level level) void EvolutionContactSource::logCacheStats(Logger::Level level)
@ -890,11 +877,11 @@ void EvolutionContactSource::readItem(const string &luid, std::string &item, boo
} }
#ifdef USE_EDS_CLIENT #ifdef USE_EDS_CLIENT
TrackingSyncSource::InsertItemResult EvolutionContactSource::checkBatchedInsert(const boost::shared_ptr<Pending> &pending) TrackingSyncSource::InsertItemResult EvolutionContactSource::checkBatchedInsert(const std::shared_ptr<Pending> &pending)
{ {
SE_LOG_DEBUG(pending->m_name, "checking operation: %s", pending->m_status == MODIFYING ? "waiting" : "inserted"); SE_LOG_DEBUG(pending->m_name, "checking operation: %s", pending->m_status == MODIFYING ? "waiting" : "inserted");
if (pending->m_status == MODIFYING) { if (pending->m_status == MODIFYING) {
return TrackingSyncSource::InsertItemResult(boost::bind(&EvolutionContactSource::checkBatchedInsert, this, pending)); return TrackingSyncSource::InsertItemResult([this, pending] () { return checkBatchedInsert(pending); });
} }
if (pending->m_gerror) { if (pending->m_gerror) {
pending->m_gerror.throwError(SE_HERE, pending->m_name); pending->m_gerror.throwError(SE_HERE, pending->m_name);
@ -903,8 +890,20 @@ TrackingSyncSource::InsertItemResult EvolutionContactSource::checkBatchedInsert(
return TrackingSyncSource::InsertItemResult(pending->m_uid, newrev, ITEM_OKAY); return TrackingSyncSource::InsertItemResult(pending->m_uid, newrev, ITEM_OKAY);
} }
void EvolutionContactSource::completedAdd(const boost::shared_ptr<PendingContainer_t> &batched, gboolean success, GSList *uids, const GError *gerror) throw() void EvolutionContactSource::flushItemChanges()
{ {
if (!m_batchedAdd.empty()) {
SE_LOG_DEBUG(getDisplayName(), "batch add of %d contacts starting", (int)m_batchedAdd.size());
m_numRunningOperations++;
GListCXX<EContact, GSList> contacts;
// Iterate backwards, push to front (cheaper for single-linked list) -> same order in the end.
for (const auto &pending: reverse(m_batchedAdd)) {
contacts.push_front(pending->m_contact.get());
}
// Transfer content without copying and then copy only the shared pointer.
auto batched = std::make_shared<PendingContainer_t>();
std::swap(*batched, m_batchedAdd);
auto process = [this, batched] (gboolean success, GSList *uids, const GError *gerror) noexcept {
try { try {
// The destructor ensures that the pending operations complete // The destructor ensures that the pending operations complete
// before destructing the instance, so our "this" pointer is // before destructing the instance, so our "this" pointer is
@ -941,10 +940,20 @@ void EvolutionContactSource::completedAdd(const boost::shared_ptr<PendingContain
} catch (...) { } catch (...) {
Exception::handle(HANDLE_EXCEPTION_FATAL); Exception::handle(HANDLE_EXCEPTION_FATAL);
} }
};
SYNCEVO_GLIB_CALL_ASYNC(e_book_client_add_contacts, process,
m_addressbook, contacts, NULL);
} }
if (!m_batchedUpdate.empty()) {
void EvolutionContactSource::completedUpdate(const boost::shared_ptr<PendingContainer_t> &batched, gboolean success, const GError *gerror) throw() SE_LOG_DEBUG(getDisplayName(), "batch update of %d contacts starting", (int)m_batchedUpdate.size());
{ m_numRunningOperations++;
GListCXX<EContact, GSList> contacts;
for (const auto &pending: reverse(m_batchedUpdate)) {
contacts.push_front(pending->m_contact.get());
}
auto batched = std::make_shared<PendingContainer_t>();
std::swap(*batched, m_batchedUpdate);
auto process = [this, batched] (gboolean success, const GError *gerror) noexcept {
try { try {
SE_LOG_DEBUG(getDisplayName(), "batch update of %d contacts completed", (int)batched->size()); SE_LOG_DEBUG(getDisplayName(), "batch update of %d contacts completed", (int)batched->size());
m_numRunningOperations--; m_numRunningOperations--;
@ -965,42 +974,8 @@ void EvolutionContactSource::completedUpdate(const boost::shared_ptr<PendingCont
} catch (...) { } catch (...) {
Exception::handle(HANDLE_EXCEPTION_FATAL); Exception::handle(HANDLE_EXCEPTION_FATAL);
} }
} };
SYNCEVO_GLIB_CALL_ASYNC(e_book_client_modify_contacts, process,
void EvolutionContactSource::flushItemChanges()
{
if (!m_batchedAdd.empty()) {
SE_LOG_DEBUG(getDisplayName(), "batch add of %d contacts starting", (int)m_batchedAdd.size());
m_numRunningOperations++;
GListCXX<EContact, GSList> contacts;
// Iterate backwards, push to front (cheaper for single-linked list) -> same order in the end.
for (const auto &pending: reverse(m_batchedAdd)) {
contacts.push_front(pending->m_contact.get());
}
// Transfer content without copying and then copy only the shared pointer.
boost::shared_ptr<PendingContainer_t> batched(new PendingContainer_t);
std::swap(*batched, m_batchedAdd);
SYNCEVO_GLIB_CALL_ASYNC(e_book_client_add_contacts,
boost::bind(&EvolutionContactSource::completedAdd,
this,
batched,
_1, _2, _3),
m_addressbook, contacts, NULL);
}
if (!m_batchedUpdate.empty()) {
SE_LOG_DEBUG(getDisplayName(), "batch update of %d contacts starting", (int)m_batchedUpdate.size());
m_numRunningOperations++;
GListCXX<EContact, GSList> contacts;
for (const auto &pending: reverse(m_batchedUpdate)) {
contacts.push_front(pending->m_contact.get());
}
boost::shared_ptr<PendingContainer_t> batched(new PendingContainer_t);
std::swap(*batched, m_batchedUpdate);
SYNCEVO_GLIB_CALL_ASYNC(e_book_client_modify_contacts,
boost::bind(&EvolutionContactSource::completedUpdate,
this,
batched,
_1, _2),
m_addressbook, contacts, NULL); m_addressbook, contacts, NULL);
} }
} }
@ -1055,7 +1030,7 @@ EvolutionContactSource::insertItem(const string &uid, const std::string &item, b
uid.empty() ? "add" : ("insert " + uid).c_str(), uid.empty() ? "add" : ("insert " + uid).c_str(),
m_asyncOpCounter++); m_asyncOpCounter++);
SE_LOG_DEBUG(name, "queueing for batched %s", uid.empty() ? "add" : "update"); SE_LOG_DEBUG(name, "queueing for batched %s", uid.empty() ? "add" : "update");
boost::shared_ptr<Pending> pending(new Pending); auto pending = std::make_shared<Pending>();
pending->m_name = name; pending->m_name = name;
pending->m_contact = contact; pending->m_contact = contact;
pending->m_uid = uid; pending->m_uid = uid;
@ -1066,7 +1041,7 @@ EvolutionContactSource::insertItem(const string &uid, const std::string &item, b
} }
// SyncSource is going to live longer than Synthesis // SyncSource is going to live longer than Synthesis
// engine, so using "this" is safe here. // engine, so using "this" is safe here.
return InsertItemResult(boost::bind(&EvolutionContactSource::checkBatchedInsert, this, pending)); return InsertItemResult([this, pending] () { return checkBatchedInsert(pending); });
break; break;
} }
#else #else

View File

@ -137,7 +137,7 @@ class EvolutionContactSource : public EvolutionSyncSource,
Pending() : m_status(MODIFYING) {} Pending() : m_status(MODIFYING) {}
}; };
typedef std::list< boost::shared_ptr<Pending> >PendingContainer_t; typedef std::list< std::shared_ptr<Pending> >PendingContainer_t;
/** /**
* Batched "contact add/update" operations. * Batched "contact add/update" operations.
@ -148,14 +148,12 @@ class EvolutionContactSource : public EvolutionSyncSource,
PendingContainer_t m_batchedUpdate; PendingContainer_t m_batchedUpdate;
InitState<int> m_numRunningOperations; InitState<int> m_numRunningOperations;
InsertItemResult checkBatchedInsert(const boost::shared_ptr<Pending> &pending); InsertItemResult checkBatchedInsert(const std::shared_ptr<Pending> &pending);
void completedAdd(const boost::shared_ptr<PendingContainer_t> &batched, gboolean success, /* const GStringListFreeCXX &uids */ GSList *uids, const GError *gerror) throw ();
void completedUpdate(const boost::shared_ptr<PendingContainer_t> &batched, gboolean success, const GError *gerror) throw ();
virtual void flushItemChanges(); virtual void flushItemChanges();
virtual void finishItemChanges(); virtual void finishItemChanges();
// Read-ahead of item data. // Read-ahead of item data.
boost::shared_ptr<ContactCache> m_contactCache, m_contactCacheNext; std::shared_ptr<ContactCache> m_contactCache, m_contactCacheNext;
int m_cacheMisses, m_cacheStalls; int m_cacheMisses, m_cacheStalls;
int m_contactReads; /**< number of readItemAsKey() calls */ int m_contactReads; /**< number of readItemAsKey() calls */
int m_contactsFromDB; /**< number of contacts requested from DB (including ones not found) */ int m_contactsFromDB; /**< number of contacts requested from DB (including ones not found) */
@ -164,9 +162,9 @@ class EvolutionContactSource : public EvolutionSyncSource,
ReadAheadOrder m_readAheadOrder; ReadAheadOrder m_readAheadOrder;
ReadAheadItems m_nextLUIDs; ReadAheadItems m_nextLUIDs;
void checkCacheForError(boost::shared_ptr<ContactCache> &cache); void checkCacheForError(std::shared_ptr<ContactCache> &cache);
void invalidateCachedContact(const std::string &luid); void invalidateCachedContact(const std::string &luid);
void invalidateCachedContact(boost::shared_ptr<ContactCache> &cache, const std::string &luid); void invalidateCachedContact(std::shared_ptr<ContactCache> &cache, const std::string &luid);
bool getContact(const string &luid, EContact **contact, GErrorCXX &gerror); bool getContact(const string &luid, EContact **contact, GErrorCXX &gerror);
bool getContactFromCache(const string &luid, EContact **contact, GErrorCXX &gerror); bool getContactFromCache(const string &luid, EContact **contact, GErrorCXX &gerror);
enum ReadingMode enum ReadingMode
@ -174,8 +172,7 @@ class EvolutionContactSource : public EvolutionSyncSource,
START, /**< luid is needed, must be read */ START, /**< luid is needed, must be read */
CONTINUE /**< luid is from old request, find next ones */ CONTINUE /**< luid is from old request, find next ones */
}; };
boost::shared_ptr<ContactCache> startReading(const std::string &luid, ReadingMode mode); std::shared_ptr<ContactCache> startReading(const std::string &luid, ReadingMode mode);
void completedRead(const boost::weak_ptr<ContactCache> &cachePtr, gboolean success, GSList *contactsPtr, const GError *gerror) throw();
void logCacheStats(Logger::Level level); void logCacheStats(Logger::Level level);
// Use the information provided to us to implement read-ahead efficiently. // Use the information provided to us to implement read-ahead efficiently.

View File

@ -77,7 +77,7 @@ class EvolutionContactTest : public CppUnit::TestFixture {
protected: protected:
void testInstantiate() { void testInstantiate() {
boost::shared_ptr<SyncSource> source; std::shared_ptr<SyncSource> source;
source.reset(SyncSource::createTestingSource("addressbook", "addressbook", true)); source.reset(SyncSource::createTestingSource("addressbook", "addressbook", true));
source.reset(SyncSource::createTestingSource("addressbook", "contacts", true)); source.reset(SyncSource::createTestingSource("addressbook", "contacts", true));
source.reset(SyncSource::createTestingSource("addressbook", "evolution-contacts", true)); source.reset(SyncSource::createTestingSource("addressbook", "evolution-contacts", true));
@ -94,8 +94,8 @@ protected:
void testImport() { void testImport() {
// this only tests that we can instantiate something under the type "addressbook"; // this only tests that we can instantiate something under the type "addressbook";
// it might not be an EvolutionContactSource // it might not be an EvolutionContactSource
boost::shared_ptr<EvolutionContactSource> source21(dynamic_cast<EvolutionContactSource *>(SyncSource::createTestingSource("evolutioncontactsource21", "evolution-contacts:text/x-vcard", true))); std::shared_ptr<EvolutionContactSource> source21(dynamic_cast<EvolutionContactSource *>(SyncSource::createTestingSource("evolutioncontactsource21", "evolution-contacts:text/x-vcard", true)));
boost::shared_ptr<EvolutionContactSource> source30(dynamic_cast<EvolutionContactSource *>(SyncSource::createTestingSource("evolutioncontactsource30", "Evolution Address Book:text/vcard", true))); std::shared_ptr<EvolutionContactSource> source30(dynamic_cast<EvolutionContactSource *>(SyncSource::createTestingSource("evolutioncontactsource30", "Evolution Address Book:text/vcard", true)));
string parsed; string parsed;
#if 0 #if 0

View File

@ -58,7 +58,7 @@ static void handleErrorCB(EClient */*client*/, const gchar *error_msg, gpointer
EClientCXX EvolutionSyncSource::openESource(const char *extension, EClientCXX EvolutionSyncSource::openESource(const char *extension,
ESource *(*refBuiltin)(ESourceRegistry *), ESource *(*refBuiltin)(ESourceRegistry *),
const boost::function<EClient *(ESource *, GError **gerror)> &newClient) const std::function<EClient *(ESource *, GError **gerror)> &newClient)
{ {
EClientCXX client; EClientCXX client;
GErrorCXX gerror; GErrorCXX gerror;

View File

@ -71,7 +71,7 @@ class EvolutionSyncSource : public TrackingSyncSource
ESource *(*getDef)(ESourceRegistry *)); ESource *(*getDef)(ESourceRegistry *));
EClientCXX openESource(const char *extension, EClientCXX openESource(const char *extension,
ESource *(*refBuiltin)(ESourceRegistry *), ESource *(*refBuiltin)(ESourceRegistry *),
const boost::function<EClient *(ESource *, GError **gerror)> &newClient); const std::function<EClient *(ESource *, GError **gerror)> &newClient);
// Implementation of SyncSource calls which only works when using EDS Client API // Implementation of SyncSource calls which only works when using EDS Client API
// and EDS > 3.4. Older EDS has no way of creating sources easily (or at all). // and EDS > 3.4. Older EDS has no way of creating sources easily (or at all).

View File

@ -88,7 +88,7 @@ class FileSyncSourceUnitTest : public CppUnit::TestFixture {
protected: protected:
void testInstantiate() { void testInstantiate() {
boost::shared_ptr<SyncSource> source; std::shared_ptr<SyncSource> source;
source.reset(SyncSource::createTestingSource("file", "file:text/vcard:3.0", true)); source.reset(SyncSource::createTestingSource("file", "file:text/vcard:3.0", true));
source.reset(SyncSource::createTestingSource("file", "file:text/plain:1.0", true)); source.reset(SyncSource::createTestingSource("file", "file:text/plain:1.0", true));
source.reset(SyncSource::createTestingSource("file", "Files in one directory:text/x-vcard:2.1", true)); source.reset(SyncSource::createTestingSource("file", "Files in one directory:text/x-vcard:2.1", true));

View File

@ -36,11 +36,11 @@ public:
" using an account created and managed with GNOME Control Center.") " using an account created and managed with GNOME Control Center.")
{} {}
virtual boost::shared_ptr<AuthProvider> create(const InitStateString &username, virtual std::shared_ptr<AuthProvider> create(const InitStateString &username,
const InitStateString &password) const InitStateString &password)
{ {
// Returning NULL if not enabled... // Returning NULL if not enabled...
boost::shared_ptr<AuthProvider> provider; std::shared_ptr<AuthProvider> provider;
#ifdef USE_GOA #ifdef USE_GOA
provider = createGOAAuthProvider(username, password); provider = createGOAAuthProvider(username, password);
#endif #endif

View File

@ -74,7 +74,7 @@ class GOAManager : private GDBusCXX::DBusRemoteObject
* (the unique user visible string). The account must support OAuth2, * (the unique user visible string). The account must support OAuth2,
* otherwise an error is thrown. * otherwise an error is thrown.
*/ */
boost::shared_ptr<GOAAccount> lookupAccount(const std::string &representationID); std::shared_ptr<GOAAccount> lookupAccount(const std::string &representationID);
}; };
class GOAAccount class GOAAccount
@ -97,7 +97,7 @@ GOAManager::GOAManager(const GDBusCXX::DBusConnectionPtr &conn) :
{ {
} }
boost::shared_ptr<GOAAccount> GOAManager::lookupAccount(const std::string &username) std::shared_ptr<GOAAccount> GOAManager::lookupAccount(const std::string &username)
{ {
SE_LOG_DEBUG(NULL, "Looking up all accounts in GNOME Online Accounts, searching for '%s'.", username.c_str()); SE_LOG_DEBUG(NULL, "Looking up all accounts in GNOME Online Accounts, searching for '%s'.", username.c_str());
ManagedObjects objects = m_getManagedObjects(); ManagedObjects objects = m_getManagedObjects();
@ -172,7 +172,7 @@ boost::shared_ptr<GOAAccount> GOAManager::lookupAccount(const std::string &usern
username.c_str())); username.c_str()));
} }
boost::shared_ptr<GOAAccount> account(new GOAAccount(getConnection(), accountPath)); auto account = std::make_shared<GOAAccount>(getConnection(), accountPath);
return account; return account;
} }
@ -187,10 +187,10 @@ GOAAccount::GOAAccount(const GDBusCXX::DBusConnectionPtr &conn,
class GOAAuthProvider : public AuthProvider class GOAAuthProvider : public AuthProvider
{ {
boost::shared_ptr<GOAAccount> m_account; std::shared_ptr<GOAAccount> m_account;
public: public:
GOAAuthProvider(const boost::shared_ptr<GOAAccount> &account) : GOAAuthProvider(const std::shared_ptr<GOAAccount> &account) :
m_account(account) m_account(account)
{} {}
@ -208,7 +208,7 @@ public:
virtual std::string getUsername() const { return ""; } virtual std::string getUsername() const { return ""; }
}; };
boost::shared_ptr<AuthProvider> createGOAAuthProvider(const InitStateString &username, std::shared_ptr<AuthProvider> createGOAAuthProvider(const InitStateString &username,
const InitStateString &password) const InitStateString &password)
{ {
// Because we share the connection, hopefully this won't be too expensive. // Because we share the connection, hopefully this won't be too expensive.
@ -222,8 +222,8 @@ boost::shared_ptr<AuthProvider> createGOAAuthProvider(const InitStateString &use
} }
GOAManager manager(conn); GOAManager manager(conn);
boost::shared_ptr<GOAAccount> account = manager.lookupAccount(username); std::shared_ptr<GOAAccount> account = manager.lookupAccount(username);
boost::shared_ptr<AuthProvider> provider(new GOAAuthProvider(account)); auto provider = std::make_shared<GOAAuthProvider>(account);
return provider; return provider;
} }

View File

@ -21,13 +21,13 @@
#include <syncevo/util.h> #include <syncevo/util.h>
#include <boost/shared_ptr.hpp> #include <memory>
#include <syncevo/declarations.h> #include <syncevo/declarations.h>
SE_BEGIN_CXX SE_BEGIN_CXX
class AuthProvider; class AuthProvider;
boost::shared_ptr<AuthProvider> createGOAAuthProvider(const InitStateString &username, std::shared_ptr<AuthProvider> createGOAAuthProvider(const InitStateString &username,
const InitStateString &password); const InitStateString &password);
SE_END_CXX SE_END_CXX

View File

@ -126,7 +126,7 @@ class KCalExtendedSourceUnitTest : public CppUnit::TestFixture {
protected: protected:
void testInstantiate() { void testInstantiate() {
boost::shared_ptr<SyncSource> source; std::shared_ptr<SyncSource> source;
source.reset(SyncSource::createTestingSource("KCalExtended", "KCalExtended:text/calendar:2.0", true)); source.reset(SyncSource::createTestingSource("KCalExtended", "KCalExtended:text/calendar:2.0", true));
} }
}; };

View File

@ -115,7 +115,7 @@ class MaemoCalendarSourceUnitTest : public CppUnit::TestFixture {
protected: protected:
void testInstantiate() { void testInstantiate() {
boost::shared_ptr<SyncSource> source; std::shared_ptr<SyncSource> source;
source.reset(SyncSource::createTestingSource("calendar", "calendar", true)); source.reset(SyncSource::createTestingSource("calendar", "calendar", true));
source.reset(SyncSource::createTestingSource("calendar", "maemo-events", true)); source.reset(SyncSource::createTestingSource("calendar", "maemo-events", true));
source.reset(SyncSource::createTestingSource("calendar", "Maemo Calendar:text/calendar", true)); source.reset(SyncSource::createTestingSource("calendar", "Maemo Calendar:text/calendar", true));

View File

@ -31,7 +31,7 @@ SE_BEGIN_CXX
class RefreshTokenAuthProvider : public AuthProvider class RefreshTokenAuthProvider : public AuthProvider
{ {
boost::shared_ptr<HTTPTransportAgent> m_agent; std::shared_ptr<HTTPTransportAgent> m_agent;
std::string m_tokenHost; std::string m_tokenHost;
std::string m_tokenPath; std::string m_tokenPath;
std::string m_scope; std::string m_scope;
@ -47,6 +47,13 @@ public:
const char* clientID, const char* clientID,
const char* clientSecret, const char* clientSecret,
const char* refreshToken) : const char* refreshToken) :
m_agent(
#ifdef ENABLE_LIBSOUP
make_weak_shared::make<SoupTransportAgent>(static_cast<GMainLoop *>(NULL))
#elif defined(ENABLE_LIBCURL)
std::make_shared<CurlTransportAgent>()
#endif
),
m_tokenHost(tokenHost), m_tokenHost(tokenHost),
m_tokenPath(tokenPath), m_tokenPath(tokenPath),
m_scope(scope), m_scope(scope),
@ -54,12 +61,6 @@ public:
m_clientSecret(clientSecret), m_clientSecret(clientSecret),
m_refreshToken(refreshToken) m_refreshToken(refreshToken)
{ {
#ifdef ENABLE_LIBSOUP
m_agent = SoupTransportAgent::create(static_cast<GMainLoop *>(NULL));
#elif defined(ENABLE_LIBCURL)
boost::shared_ptr<CurlTransportAgent> agent(new CurlTransportAgent());
m_agent = agent;
#endif
} }
virtual bool methodIsSupported(AuthMethod method) const { return method == AUTH_METHOD_OAUTH2; } virtual bool methodIsSupported(AuthMethod method) const { return method == AUTH_METHOD_OAUTH2; }
@ -158,11 +159,11 @@ public:
virtual std::string getUsername() const { return ""; } virtual std::string getUsername() const { return ""; }
}; };
boost::shared_ptr<AuthProvider> createOAuth2AuthProvider(const InitStateString &username, std::shared_ptr<AuthProvider> createOAuth2AuthProvider(const InitStateString &username,
const InitStateString &password) const InitStateString &password)
{ {
// Expected content of parameter GVariant. // Expected content of parameter GVariant.
boost::shared_ptr<GVariantType> hashtype(g_variant_type_new("a{ss}"), g_variant_type_free); std::shared_ptr<GVariantType> hashtype(g_variant_type_new("a{ss}"), g_variant_type_free);
// 'username' is the part after oauth2: which we can parse directly. // 'username' is the part after oauth2: which we can parse directly.
GErrorCXX gerror; GErrorCXX gerror;
@ -207,7 +208,7 @@ boost::shared_ptr<AuthProvider> createOAuth2AuthProvider(const InitStateString &
if (password.empty()) { if (password.empty()) {
SE_THROW("need refresh token provided as password"); SE_THROW("need refresh token provided as password");
} }
boost::shared_ptr<AuthProvider> provider(new RefreshTokenAuthProvider(tokenHost, tokenPath, scope, clientID, clientSecret, password.c_str())); auto provider = std::make_shared<RefreshTokenAuthProvider>(tokenHost, tokenPath, scope, clientID, clientSecret, password.c_str());
return provider; return provider;
} }

View File

@ -21,13 +21,13 @@
#include <syncevo/util.h> #include <syncevo/util.h>
#include <boost/shared_ptr.hpp> #include <memory>
#include <syncevo/declarations.h> #include <syncevo/declarations.h>
SE_BEGIN_CXX SE_BEGIN_CXX
class AuthProvider; class AuthProvider;
boost::shared_ptr<AuthProvider> createOAuth2AuthProvider(const InitStateString &username, std::shared_ptr<AuthProvider> createOAuth2AuthProvider(const InitStateString &username,
const InitStateString &password); const InitStateString &password);
SE_END_CXX SE_END_CXX

View File

@ -41,10 +41,10 @@ public:
" 'Scope', 'ClientID', 'ClientSecret'\n") " 'Scope', 'ClientID', 'ClientSecret'\n")
{} {}
virtual boost::shared_ptr<AuthProvider> create(const InitStateString &username, virtual std::shared_ptr<AuthProvider> create(const InitStateString &username,
const InitStateString &password) const InitStateString &password)
{ {
boost::shared_ptr<AuthProvider> provider; std::shared_ptr<AuthProvider> provider;
provider = createOAuth2AuthProvider(username, password); provider = createOAuth2AuthProvider(username, password);
return provider; return provider;
} }

View File

@ -45,7 +45,6 @@
#include "gdbus-cxx-bridge.h" #include "gdbus-cxx-bridge.h"
#include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/predicate.hpp>
#include <boost/bind.hpp>
#include <synthesis/SDK_util.h> #include <synthesis/SDK_util.h>
@ -226,7 +225,7 @@ class PullAll
uint16_t m_numContacts; // Number of existing contacts, according to GetSize() or after downloading. uint16_t m_numContacts; // Number of existing contacts, according to GetSize() or after downloading.
uint16_t m_currentContact; // Numbered starting with zero according to discovery in addVCards. uint16_t m_currentContact; // Numbered starting with zero according to discovery in addVCards.
boost::shared_ptr<PbapSession> m_session; // Only set when there is a transfer ongoing. std::shared_ptr<PbapSession> m_session; // Only set when there is a transfer ongoing.
size_t m_tmpFileOffset; // Number of bytes already parsed. size_t m_tmpFileOffset; // Number of bytes already parsed.
uint16_t m_transferOffset; // First contact requested as part of current transfer. uint16_t m_transferOffset; // First contact requested as part of current transfer.
uint16_t m_initialOffset; // First contact request by first transfer. uint16_t m_initialOffset; // First contact request by first transfer.
@ -269,15 +268,16 @@ PullAll::~PullAll()
{ {
} }
class PbapSession : private boost::noncopyable { class PbapSession : private boost::noncopyable, public enable_weak_from_this<PbapSession> {
public: public:
static boost::shared_ptr<PbapSession> create(PbapSyncSource &parent); // Construct via make_weak_shared.
friend make_weak_shared;
void initSession(const std::string &address, const std::string &format); void initSession(const std::string &address, const std::string &format);
typedef std::map<std::string, pcrecpp::StringPiece> Content; typedef std::map<std::string, pcrecpp::StringPiece> Content;
boost::shared_ptr<PullAll> startPullAll(const PullParams &pullParams); std::shared_ptr<PullAll> startPullAll(const PullParams &pullParams);
void continuePullAll(PullAll &state); void continuePullAll(PullAll &state);
void checkForError(); // Throws exception if transfer failed. void checkForError(); // Throws exception if transfer failed.
Timespec transferComplete() const; Timespec transferComplete() const;
@ -290,7 +290,6 @@ private:
PbapSession(PbapSyncSource &parent); PbapSession(PbapSyncSource &parent);
PbapSyncSource &m_parent; PbapSyncSource &m_parent;
boost::weak_ptr<PbapSession> m_self;
std::unique_ptr<GDBusCXX::DBusRemoteObject> m_client; std::unique_ptr<GDBusCXX::DBusRemoteObject> m_client;
bool m_frozen; bool m_frozen;
enum { enum {
@ -335,8 +334,6 @@ private:
std::unique_ptr<GDBusCXX::SignalWatch<GDBusCXX::Path_t, std::string, std::string> > std::unique_ptr<GDBusCXX::SignalWatch<GDBusCXX::Path_t, std::string, std::string> >
m_errorSignal; m_errorSignal;
void errorCb(const GDBusCXX::Path_t &path, const std::string &error,
const std::string &msg);
// Bluez 5 // Bluez 5
typedef GDBusCXX::SignalWatch<GDBusCXX::Path_t, std::string, Params, std::vector<std::string> > PropChangedSignal_t; typedef GDBusCXX::SignalWatch<GDBusCXX::Path_t, std::string, Params, std::vector<std::string> > PropChangedSignal_t;
@ -349,7 +346,6 @@ private:
// new obexd API // new obexd API
typedef GDBusCXX::SignalWatch<GDBusCXX::Path_t> CompleteSignal_t; typedef GDBusCXX::SignalWatch<GDBusCXX::Path_t> CompleteSignal_t;
std::unique_ptr<CompleteSignal_t> m_completeSignal; std::unique_ptr<CompleteSignal_t> m_completeSignal;
void completeCb(const GDBusCXX::Path_t &path);
typedef GDBusCXX::SignalWatch<GDBusCXX::Path_t, std::string, boost::variant<int64_t> > PropertyChangedSignal_t; typedef GDBusCXX::SignalWatch<GDBusCXX::Path_t, std::string, boost::variant<int64_t> > PropertyChangedSignal_t;
std::unique_ptr<PropertyChangedSignal_t> m_propertyChangedSignal; std::unique_ptr<PropertyChangedSignal_t> m_propertyChangedSignal;
void propertyChangedCb(const GDBusCXX::Path_t &path, const std::string &name, const boost::variant<int64_t> &value); void propertyChangedCb(const GDBusCXX::Path_t &path, const std::string &name, const boost::variant<int64_t> &value);
@ -363,13 +359,6 @@ PbapSession::PbapSession(PbapSyncSource &parent) :
{ {
} }
boost::shared_ptr<PbapSession> PbapSession::create(PbapSyncSource &parent)
{
boost::shared_ptr<PbapSession> session(new PbapSession(parent));
session->m_self = session;
return session;
}
void PbapSession::propChangedCb(const GDBusCXX::Path_t &path, void PbapSession::propChangedCb(const GDBusCXX::Path_t &path,
const std::string &interface, const std::string &interface,
const Params &changed, const Params &changed,
@ -413,24 +402,6 @@ void PbapSession::propChangedCb(const GDBusCXX::Path_t &path,
} }
} }
void PbapSession::completeCb(const GDBusCXX::Path_t &path)
{
SE_LOG_DEBUG(NULL, "obexd transfer %s completed", path.c_str());
m_transfers[path] = Completion::now();
}
void PbapSession::errorCb(const GDBusCXX::Path_t &path,
const std::string &error,
const std::string &msg)
{
SE_LOG_DEBUG(NULL, "obexd transfer %s failed: %s %s",
path.c_str(), error.c_str(), msg.c_str());
Completion &completion = m_transfers[path];
completion.m_transferComplete = Timespec::monotonic();
completion.m_transferErrorCode = error;
completion.m_transferErrorMsg = msg;
}
void PbapSession::propertyChangedCb(const GDBusCXX::Path_t &path, void PbapSession::propertyChangedCb(const GDBusCXX::Path_t &path,
const std::string &name, const std::string &name,
const boost::variant<int64_t> &value) const boost::variant<int64_t> &value)
@ -598,7 +569,7 @@ void PbapSession::initSession(const std::string &address, const std::string &for
// pointer and ignore callback when the instance is already gone. // pointer and ignore callback when the instance is already gone.
// Should not happen with signals (destructing the class unregisters // Should not happen with signals (destructing the class unregisters
// the watch), but very well may happen in asynchronous method // the watch), but very well may happen in asynchronous method
// calls. Therefore maintain m_self and show how to use it here. // calls.
if (m_obexAPI == BLUEZ5) { if (m_obexAPI == BLUEZ5) {
// Bluez 5 // Bluez 5
m_propChangedSignal.reset(new PropChangedSignal_t m_propChangedSignal.reset(new PropChangedSignal_t
@ -607,7 +578,12 @@ void PbapSession::initSession(const std::string &address, const std::string &for
"org.freedesktop.DBus.Properties", "org.freedesktop.DBus.Properties",
"PropertiesChanged", "PropertiesChanged",
GDBusCXX::SignalFilter::SIGNAL_FILTER_PATH_PREFIX))); GDBusCXX::SignalFilter::SIGNAL_FILTER_PATH_PREFIX)));
m_propChangedSignal->activate(boost::bind(&PbapSession::propChangedCb, m_self, _1, _2, _3, _4)); m_propChangedSignal->activate([self=weak_from_this()] (const GDBusCXX::Path_t &path, const std::string &interface, const Params &changed, const std::vector<std::string> &invalidated) {
auto lock = self.lock();
if (lock) {
lock->propChangedCb(path, interface, changed, invalidated);
}
});
} else { } else {
// obexd >= 0.47 // obexd >= 0.47
m_completeSignal.reset(new CompleteSignal_t m_completeSignal.reset(new CompleteSignal_t
@ -616,7 +592,13 @@ void PbapSession::initSession(const std::string &address, const std::string &for
OBC_TRANSFER_INTERFACE_NEW, OBC_TRANSFER_INTERFACE_NEW,
"Complete", "Complete",
GDBusCXX::SignalFilter::SIGNAL_FILTER_PATH_PREFIX))); GDBusCXX::SignalFilter::SIGNAL_FILTER_PATH_PREFIX)));
m_completeSignal->activate(boost::bind(&PbapSession::completeCb, m_self, _1)); m_completeSignal->activate([self=weak_from_this()] (const GDBusCXX::Path_t &path) {
auto lock = self.lock();
SE_LOG_DEBUG(NULL, "obexd transfer %s completed", path.c_str());
if (lock) {
lock->m_transfers[path] = Completion::now();
}
});
// same for error // same for error
m_errorSignal.reset(new GDBusCXX::SignalWatch<GDBusCXX::Path_t, std::string, std::string> m_errorSignal.reset(new GDBusCXX::SignalWatch<GDBusCXX::Path_t, std::string, std::string>
@ -625,7 +607,17 @@ void PbapSession::initSession(const std::string &address, const std::string &for
OBC_TRANSFER_INTERFACE_NEW, OBC_TRANSFER_INTERFACE_NEW,
"Error", "Error",
GDBusCXX::SignalFilter::SIGNAL_FILTER_PATH_PREFIX))); GDBusCXX::SignalFilter::SIGNAL_FILTER_PATH_PREFIX)));
m_errorSignal->activate(boost::bind(&PbapSession::errorCb, m_self, _1, _2, _3)); m_errorSignal->activate([self=weak_from_this()] (const GDBusCXX::Path_t &path, const std::string &error, const std::string &msg) {
auto lock = self.lock();
SE_LOG_DEBUG(NULL, "obexd transfer %s failed: %s %s",
path.c_str(), error.c_str(), msg.c_str());
if (lock) {
Completion &completion = lock->m_transfers[path];
completion.m_transferComplete = Timespec::monotonic();
completion.m_transferErrorCode = error;
completion.m_transferErrorMsg = msg;
}
});
// and property changes // and property changes
m_propertyChangedSignal.reset(new PropertyChangedSignal_t(GDBusCXX::SignalFilter(m_client->getConnection(), m_propertyChangedSignal.reset(new PropertyChangedSignal_t(GDBusCXX::SignalFilter(m_client->getConnection(),
@ -633,7 +625,12 @@ void PbapSession::initSession(const std::string &address, const std::string &for
OBC_TRANSFER_INTERFACE_NEW, OBC_TRANSFER_INTERFACE_NEW,
"PropertyChanged", "PropertyChanged",
GDBusCXX::SignalFilter::SIGNAL_FILTER_PATH_PREFIX))); GDBusCXX::SignalFilter::SIGNAL_FILTER_PATH_PREFIX)));
m_propertyChangedSignal->activate(boost::bind(&PbapSession::propertyChangedCb, m_self, _1, _2, _3)); m_propertyChangedSignal->activate([self=weak_from_this()] (const GDBusCXX::Path_t &path, const std::string &interface , const boost::variant<int64_t> &value) {
auto lock = self.lock();
if (lock) {
lock->propertyChangedCb(path, interface, value);
}
});
} }
} else { } else {
// obexd < 0.47 // obexd < 0.47
@ -666,7 +663,7 @@ void PbapSession::initSession(const std::string &address, const std::string &for
Properties::const_iterator entry = Properties::const_iterator entry =
std::find_if(m_filterFields.begin(), std::find_if(m_filterFields.begin(),
m_filterFields.end(), m_filterFields.end(),
boost::bind(&boost::iequals<std::string,std::string>, _1, prop, std::locale())); [&prop] (const std::string &other) { return boost::iequals(other, prop, std::locale()); });
if (entry == m_filterFields.end()) { if (entry == m_filterFields.end()) {
m_parent.throwError(SE_HERE, StringPrintf("invalid property name in PBAP vCard format specification (databaseFormat): %s", m_parent.throwError(SE_HERE, StringPrintf("invalid property name in PBAP vCard format specification (databaseFormat): %s",
@ -687,7 +684,7 @@ void PbapSession::initSession(const std::string &address, const std::string &for
SE_LOG_DEBUG(NULL, "PBAP session initialized"); SE_LOG_DEBUG(NULL, "PBAP session initialized");
} }
boost::shared_ptr<PullAll> PbapSession::startPullAll(const PullParams &pullParams) std::shared_ptr<PullAll> PbapSession::startPullAll(const PullParams &pullParams)
{ {
resetTransfer(); resetTransfer();
blockOnFreeze(); blockOnFreeze();
@ -744,7 +741,7 @@ boost::shared_ptr<PullAll> PbapSession::startPullAll(const PullParams &pullParam
} }
} }
boost::shared_ptr<PullAll> state(new PullAll); auto state = std::make_shared<PullAll>();
state->m_pullParams = pullParams; state->m_pullParams = pullParams;
state->m_contentStartIndex = 0; state->m_contentStartIndex = 0;
state->m_currentContact = 0; state->m_currentContact = 0;
@ -812,7 +809,7 @@ boost::shared_ptr<PullAll> PbapSession::startPullAll(const PullParams &pullParam
// and the Synthesis engine will ignore the ID (src/sysync/binfileimplds.cpp: // and the Synthesis engine will ignore the ID (src/sysync/binfileimplds.cpp:
// "Record does not exist any more in database%s -> ignore"). // "Record does not exist any more in database%s -> ignore").
state->m_tmpFileOffset = 0; state->m_tmpFileOffset = 0;
state->m_session = m_self.lock(); state->m_session = shared_from_this();
state->m_filter = currentFilter; state->m_filter = currentFilter;
} else { } else {
// < 0.47 // < 0.47
@ -1135,10 +1132,15 @@ PbapSyncSource::PbapSyncSource(const SyncSourceParams &params) :
SyncSource(params) SyncSource(params)
{ {
SyncSourceSession::init(m_operations); SyncSourceSession::init(m_operations);
m_operations.m_readNextItem = boost::bind(&PbapSyncSource::readNextItem, this, _1, _2, _3); m_operations.m_readNextItem = [this] (sysync::ItemID aID,
m_operations.m_readItemAsKey = boost::bind(&PbapSyncSource::readItemAsKey, sysync::sInt32 *aStatus,
this, _1, _2); bool aFirst) {
m_session = PbapSession::create(*this); return readNextItem(aID, aStatus, aFirst);
};
m_operations.m_readItemAsKey = [this] (sysync::cItemID aID, sysync::KeyH aItemKey) {
return readItemAsKey(aID, aItemKey);
};
m_session = make_weak_shared::make<PbapSession>(*this);
const char *PBAPSyncMode = getenv("SYNCEVOLUTION_PBAP_SYNC"); const char *PBAPSyncMode = getenv("SYNCEVOLUTION_PBAP_SYNC");
m_PBAPSyncMode = !PBAPSyncMode ? PBAP_SYNC_INCREMENTAL : m_PBAPSyncMode = !PBAPSyncMode ? PBAP_SYNC_INCREMENTAL :
boost::iequals(PBAPSyncMode, "incremental") ? PBAP_SYNC_INCREMENTAL : boost::iequals(PBAPSyncMode, "incremental") ? PBAP_SYNC_INCREMENTAL :

View File

@ -65,8 +65,8 @@ class PbapSyncSource : virtual public SyncSource, virtual public SyncSourceSessi
virtual void readItemRaw(const std::string &luid, std::string &item); virtual void readItemRaw(const std::string &luid, std::string &item);
private: private:
boost::shared_ptr<PbapSession> m_session; std::shared_ptr<PbapSession> m_session;
boost::shared_ptr<PullAll> m_pullAll; std::shared_ptr<PullAll> m_pullAll;
enum PBAPSyncMode { enum PBAPSyncMode {
PBAP_SYNC_NORMAL, ///< Read contact data according to filter. PBAP_SYNC_NORMAL, ///< Read contact data according to filter.
PBAP_SYNC_TEXT, ///< Sync without reading photo data from phone and keeping local photos instead. PBAP_SYNC_TEXT, ///< Sync without reading photo data from phone and keeping local photos instead.

View File

@ -76,7 +76,7 @@ class QtContactsSourceUnitTest : public CppUnit::TestFixture {
protected: protected:
void testInstantiate() { void testInstantiate() {
boost::shared_ptr<SyncSource> source; std::shared_ptr<SyncSource> source;
source.reset(SyncSource::createTestingSource("qtcontacts", "qtcontacts:text/vcard:3.0", true)); source.reset(SyncSource::createTestingSource("qtcontacts", "qtcontacts:text/vcard:3.0", true));
source.reset(SyncSource::createTestingSource("qtcontacts", "QtContacts", true)); source.reset(SyncSource::createTestingSource("qtcontacts", "QtContacts", true));
} }

View File

@ -40,8 +40,6 @@
#include <syncevo/GVariantSupport.h> #include <syncevo/GVariantSupport.h>
#include <pcrecpp.h> #include <pcrecpp.h>
#include <boost/lambda/core.hpp>
SE_GOBJECT_TYPE(SignonAuthService) SE_GOBJECT_TYPE(SignonAuthService)
SE_GOBJECT_TYPE(SignonAuthSession) SE_GOBJECT_TYPE(SignonAuthSession)
SE_GOBJECT_TYPE(SignonIdentity) SE_GOBJECT_TYPE(SignonIdentity)
@ -210,10 +208,10 @@ static void StoreIdentityCB(SignonIdentity *self,
data->m_gerror = error; data->m_gerror = error;
} }
boost::shared_ptr<AuthProvider> createSignonAuthProvider(const InitStateString &username, std::shared_ptr<AuthProvider> createSignonAuthProvider(const InitStateString &username,
const InitStateString &password) const InitStateString &password)
{ {
boost::shared_ptr<AuthProvider> provider; std::shared_ptr<AuthProvider> provider;
// Split username into <account ID> and <service name>. // Split username into <account ID> and <service name>.
// Be flexible and allow leading/trailing white space. // Be flexible and allow leading/trailing white space.

View File

@ -34,8 +34,6 @@
#include <syncevo/GVariantSupport.h> #include <syncevo/GVariantSupport.h>
#include <pcrecpp.h> #include <pcrecpp.h>
#include <boost/lambda/core.hpp>
SE_GOBJECT_TYPE(SignonAuthService) SE_GOBJECT_TYPE(SignonAuthService)
SE_GOBJECT_TYPE(SignonAuthSession) SE_GOBJECT_TYPE(SignonAuthSession)
SE_GOBJECT_TYPE(SignonIdentity) SE_GOBJECT_TYPE(SignonIdentity)
@ -124,11 +122,11 @@ public:
virtual std::string getUsername() const { return ""; } virtual std::string getUsername() const { return ""; }
}; };
boost::shared_ptr<AuthProvider> createSignonAuthProvider(const InitStateString &username, std::shared_ptr<AuthProvider> createSignonAuthProvider(const InitStateString &username,
const InitStateString &password) const InitStateString &password)
{ {
// Expected content of parameter GVariant. // Expected content of parameter GVariant.
boost::shared_ptr<GVariantType> hashtype(g_variant_type_new("a{sv}"), g_variant_type_free); std::shared_ptr<GVariantType> hashtype(g_variant_type_new("a{sv}"), g_variant_type_free);
// 'username' is the part after signon: which we can parse directly. // 'username' is the part after signon: which we can parse directly.
GErrorCXX gerror; GErrorCXX gerror;
@ -179,7 +177,7 @@ boost::shared_ptr<AuthProvider> createSignonAuthProvider(const InitStateString &
SE_LOG_DEBUG(NULL, "using signond identity %d", signonID); SE_LOG_DEBUG(NULL, "using signond identity %d", signonID);
SignonAuthSessionCXX authSession(signon_identity_create_session(identity, method, gerror), TRANSFER_REF); SignonAuthSessionCXX authSession(signon_identity_create_session(identity, method, gerror), TRANSFER_REF);
boost::shared_ptr<AuthProvider> provider(new SignonAuthProvider(authSession, sessionData, mechanism)); auto provider = std::make_shared<SignonAuthProvider>(authSession, sessionData, mechanism);
return provider; return provider;
} }

View File

@ -21,7 +21,7 @@
#include <syncevo/util.h> #include <syncevo/util.h>
#include <boost/shared_ptr.hpp> #include <memory>
#include <syncevo/declarations.h> #include <syncevo/declarations.h>
SE_BEGIN_CXX SE_BEGIN_CXX
@ -35,7 +35,7 @@ SE_BEGIN_CXX
#endif #endif
class AuthProvider; class AuthProvider;
boost::shared_ptr<AuthProvider> createSignonAuthProvider(const InitStateString &username, std::shared_ptr<AuthProvider> createSignonAuthProvider(const InitStateString &username,
const InitStateString &password); const InitStateString &password);
SE_END_CXX SE_END_CXX

View File

@ -64,10 +64,10 @@ public:
#endif #endif
{} {}
virtual boost::shared_ptr<AuthProvider> create(const InitStateString &username, virtual std::shared_ptr<AuthProvider> create(const InitStateString &username,
const InitStateString &password) const InitStateString &password)
{ {
boost::shared_ptr<AuthProvider> provider; std::shared_ptr<AuthProvider> provider;
provider = createSignonAuthProvider(username, password); provider = createSignonAuthProvider(username, password);
return provider; return provider;
} }

View File

@ -25,8 +25,6 @@
#include <syncevo/SafeConfigNode.h> #include <syncevo/SafeConfigNode.h>
#include <SQLiteUtil.h> #include <SQLiteUtil.h>
#include <boost/bind.hpp>
#include <syncevo/declarations.h> #include <syncevo/declarations.h>
SE_BEGIN_CXX SE_BEGIN_CXX
@ -64,17 +62,17 @@ class SQLiteContactSource : public SyncSource,
SQLiteContactSource(const SyncSourceParams &params) : SQLiteContactSource(const SyncSourceParams &params) :
SyncSource(params), SyncSource(params),
m_trackingNode(new PrefixConfigNode("item-", m_trackingNode(new PrefixConfigNode("item-",
boost::shared_ptr<ConfigNode>(new SafeConfigNode(params.m_nodes.getTrackingNode())))) std::static_pointer_cast<ConfigNode>(std::make_shared<SafeConfigNode>(params.m_nodes.getTrackingNode()))))
{ {
SyncSourceSession::init(m_operations); SyncSourceSession::init(m_operations);
SyncSourceDelete::init(m_operations); SyncSourceDelete::init(m_operations);
SyncSourceRevisions::init(NULL, NULL, 1, m_operations); SyncSourceRevisions::init(NULL, NULL, 1, m_operations);
SyncSourceChanges::init(m_operations); SyncSourceChanges::init(m_operations);
m_operations.m_isEmpty = boost::bind(&SQLiteContactSource::isEmpty, this); m_operations.m_isEmpty = [this] () { return isEmpty(); };
m_operations.m_readItemAsKey = boost::bind(&SQLiteContactSource::readItemAsKey, this, _1, _2); m_operations.m_readItemAsKey = [this] (sysync::cItemID aID, sysync::KeyH aItemKey) { return readItemAsKey(aID, aItemKey); };
m_operations.m_insertItemAsKey = boost::bind(&SQLiteContactSource::insertItemAsKey, this, _1, (sysync::cItemID)NULL, _2); m_operations.m_insertItemAsKey = [this] (sysync::KeyH aItemKey, sysync::ItemID newID) { return insertItemAsKey(aItemKey, (sysync::cItemID)NULL, newID); };
m_operations.m_updateItemAsKey = boost::bind(&SQLiteContactSource::insertItemAsKey, this, _1, _2, _3); m_operations.m_updateItemAsKey = [this] (sysync::KeyH aItemKey, sysync::cItemID aID, sysync::ItemID newID) { return insertItemAsKey(aItemKey, aID, newID); };
SyncSourceLogging::init(InitList<std::string> ("N_FIRST")+"N_MIDDLE"+"N_LAST", ", ", m_operations); SyncSourceLogging::init(InitList<std::string> ("N_FIRST")+"N_MIDDLE"+"N_LAST", ", ", m_operations);
} }
@ -103,7 +101,7 @@ class SQLiteContactSource : public SyncSource,
virtual void listAllItems(RevisionMap_t &revisions); virtual void listAllItems(RevisionMap_t &revisions);
private: private:
/** encapsulates access to database */ /** encapsulates access to database */
boost::shared_ptr<ConfigNode> m_trackingNode; std::shared_ptr<ConfigNode> m_trackingNode;
SQLiteUtil m_sqlite; SQLiteUtil m_sqlite;
/** implements the m_isEmpty operation */ /** implements the m_isEmpty operation */

View File

@ -71,7 +71,7 @@ class EvolutionSQLiteContactsTest : public CppUnit::TestFixture {
protected: protected:
void testInstantiate() { void testInstantiate() {
boost::shared_ptr<SyncSource> source; std::shared_ptr<SyncSource> source;
source.reset(SyncSource::createTestingSource("contacts", "contacts", true)); source.reset(SyncSource::createTestingSource("contacts", "contacts", true));
source.reset(SyncSource::createTestingSource("contacts", "addressbook", true)); source.reset(SyncSource::createTestingSource("contacts", "addressbook", true));
source.reset(SyncSource::createTestingSource("contacts", "sqlite-contacts", true)); source.reset(SyncSource::createTestingSource("contacts", "sqlite-contacts", true));

View File

@ -87,14 +87,14 @@ class TDEAddressBookTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
protected: protected:
static string addItem(boost::shared_ptr<TestingSyncSource> source, static string addItem(std::shared_ptr<TestingSyncSource> source,
string &data) { string &data) {
SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data); SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data);
return res.m_luid; return res.m_luid;
} }
void testInstantiate() { void testInstantiate() {
boost::shared_ptr<SyncSource> source; std::shared_ptr<SyncSource> source;
// source.reset(SyncSource::createTestingSource("addressbook", "addressbook", true)); // source.reset(SyncSource::createTestingSource("addressbook", "addressbook", true));
// source.reset(SyncSource::createTestingSource("addressbook", "contacts", true)); // source.reset(SyncSource::createTestingSource("addressbook", "contacts", true));
source.reset(SyncSource::createTestingSource("addressbook", "tdepim-contacts", true)); source.reset(SyncSource::createTestingSource("addressbook", "tdepim-contacts", true));
@ -106,7 +106,7 @@ protected:
// TODO: support default databases // TODO: support default databases
// void testOpenDefaultAddressBook() { // void testOpenDefaultAddressBook() {
// boost::shared_ptr<TestingSyncSource> source; // std::shared_ptr<TestingSyncSource> source;
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("contacts", "kde-contacts", true, NULL)); // source.reset((TestingSyncSource *)SyncSource::createTestingSource("contacts", "kde-contacts", true, NULL));
// CPPUNIT_ASSERT_NO_THROW(source->open()); // CPPUNIT_ASSERT_NO_THROW(source->open());
// } // }

View File

@ -147,14 +147,14 @@ class TDECalendarTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
protected: protected:
static string addItem(boost::shared_ptr<TestingSyncSource> source, static string addItem(std::shared_ptr<TestingSyncSource> source,
string &data) { string &data) {
SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data); SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data);
return res.m_luid; return res.m_luid;
} }
void testInstantiate() { void testInstantiate() {
boost::shared_ptr<SyncSource> source; std::shared_ptr<SyncSource> source;
// source.reset(SyncSource::createTestingSource("addressbook", "addressbook", true)); // source.reset(SyncSource::createTestingSource("addressbook", "addressbook", true));
// source.reset(SyncSource::createTestingSource("addressbook", "contacts", true)); // source.reset(SyncSource::createTestingSource("addressbook", "contacts", true));
source.reset(SyncSource::createTestingSource("addressbook", "tdepim-contacts", true)); source.reset(SyncSource::createTestingSource("addressbook", "tdepim-contacts", true));
@ -180,19 +180,19 @@ protected:
// TODO: support default databases // TODO: support default databases
// void testOpenDefaultCalendar() { // void testOpenDefaultCalendar() {
// boost::shared_ptr<TestingSyncSource> source; // std::shared_ptr<TestingSyncSource> source;
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "tdepim-calendar", true, NULL)); // source.reset((TestingSyncSource *)SyncSource::createTestingSource("calendar", "tdepim-calendar", true, NULL));
// CPPUNIT_ASSERT_NO_THROW(source->open()); // CPPUNIT_ASSERT_NO_THROW(source->open());
// } // }
// void testOpenDefaultTodo() { // void testOpenDefaultTodo() {
// boost::shared_ptr<TestingSyncSource> source; // std::shared_ptr<TestingSyncSource> source;
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("tasks", "tdepim-tasks", true, NULL)); // source.reset((TestingSyncSource *)SyncSource::createTestingSource("tasks", "tdepim-tasks", true, NULL));
// CPPUNIT_ASSERT_NO_THROW(source->open()); // CPPUNIT_ASSERT_NO_THROW(source->open());
// } // }
// void testOpenDefaultMemo() { // void testOpenDefaultMemo() {
// boost::shared_ptr<TestingSyncSource> source; // std::shared_ptr<TestingSyncSource> source;
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("memos", "tdepim-memos", true, NULL)); // source.reset((TestingSyncSource *)SyncSource::createTestingSource("memos", "tdepim-memos", true, NULL));
// CPPUNIT_ASSERT_NO_THROW(source->open()); // CPPUNIT_ASSERT_NO_THROW(source->open());
// } // }
@ -203,7 +203,7 @@ protected:
prefix = "SyncEvolution_Test_"; prefix = "SyncEvolution_Test_";
} }
boost::shared_ptr<TestingSyncSource> source; std::shared_ptr<TestingSyncSource> source;
source.reset((TestingSyncSource *)SyncSource::createTestingSource("eds_event", "tdepim-calendar", true, prefix)); source.reset((TestingSyncSource *)SyncSource::createTestingSource("eds_event", "tdepim-calendar", true, prefix));
CPPUNIT_ASSERT_NO_THROW(source->open()); CPPUNIT_ASSERT_NO_THROW(source->open());

View File

@ -102,14 +102,14 @@ class TDENotesTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
protected: protected:
static string addItem(boost::shared_ptr<TestingSyncSource> source, static string addItem(std::shared_ptr<TestingSyncSource> source,
string &data) { string &data) {
SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data); SyncSourceRaw::InsertItemResult res = source->insertItemRaw("", data);
return res.m_luid; return res.m_luid;
} }
void testInstantiate() { void testInstantiate() {
boost::shared_ptr<SyncSource> source; std::shared_ptr<SyncSource> source;
// source.reset(SyncSource::createTestingSource("memos", "memos", true)); // source.reset(SyncSource::createTestingSource("memos", "memos", true));
source.reset(SyncSource::createTestingSource("memos", "tdepim-notes", true)); source.reset(SyncSource::createTestingSource("memos", "tdepim-notes", true));
@ -119,7 +119,7 @@ protected:
// TODO: support default databases // TODO: support default databases
// void testOpenDefaultMemo() { // void testOpenDefaultMemo() {
// boost::shared_ptr<TestingSyncSource> source; // std::shared_ptr<TestingSyncSource> source;
// source.reset((TestingSyncSource *)SyncSource::createTestingSource("memos", "tdepim-memos", true, NULL)); // source.reset((TestingSyncSource *)SyncSource::createTestingSource("memos", "tdepim-memos", true, NULL));
// CPPUNIT_ASSERT_NO_THROW(source->open()); // CPPUNIT_ASSERT_NO_THROW(source->open());
// } // }
@ -130,7 +130,7 @@ protected:
prefix = "SyncEvolution_Test_"; prefix = "SyncEvolution_Test_";
} }
boost::shared_ptr<TestingSyncSource> source; std::shared_ptr<TestingSyncSource> source;
source.reset((TestingSyncSource *)SyncSource::createTestingSource("eds_event", "tdepim-notes", true, prefix)); source.reset((TestingSyncSource *)SyncSource::createTestingSource("eds_event", "tdepim-notes", true, prefix));
CPPUNIT_ASSERT_NO_THROW(source->open()); CPPUNIT_ASSERT_NO_THROW(source->open());

View File

@ -11,7 +11,6 @@
#include "CalDAVSource.h" #include "CalDAVSource.h"
#include <boost/bind.hpp>
#include <boost/algorithm/string/replace.hpp> #include <boost/algorithm/string/replace.hpp>
#include <syncevo/declarations.h> #include <syncevo/declarations.h>
@ -42,7 +41,7 @@ static void removeSyncEvolutionExdateDetached(icalcomponent *parent)
} }
CalDAVSource::CalDAVSource(const SyncSourceParams &params, CalDAVSource::CalDAVSource(const SyncSourceParams &params,
const boost::shared_ptr<Neon::Settings> &settings) : const std::shared_ptr<Neon::Settings> &settings) :
WebDAVSource(params, settings) WebDAVSource(params, settings)
{ {
SyncSourceLogging::init(InitList<std::string>("SUMMARY") + "LOCATION", SyncSourceLogging::init(InitList<std::string>("SUMMARY") + "LOCATION",
@ -50,10 +49,16 @@ CalDAVSource::CalDAVSource(const SyncSourceParams &params,
m_operations); m_operations);
// override default backup/restore from base class with our own // override default backup/restore from base class with our own
// version // version
m_operations.m_backupData = boost::bind(&CalDAVSource::backupData, m_operations.m_backupData = [this] (const SyncSource::Operations::ConstBackupInfo &oldBackup,
this, _1, _2, _3); const SyncSource::Operations::BackupInfo &newBackup,
m_operations.m_restoreData = boost::bind(&CalDAVSource::restoreData, BackupReport &backupReport) {
this, _1, _2, _3); backupData(oldBackup, newBackup, backupReport);
};
m_operations.m_restoreData = [this] (const SyncSource::Operations::ConstBackupInfo &oldBackup,
bool dryrun,
SyncSourceReport &report) {
restoreData(oldBackup, dryrun, report);
};
} }
void CalDAVSource::listAllSubItems(SubRevisionMap_t &revisions) void CalDAVSource::listAllSubItems(SubRevisionMap_t &revisions)
@ -106,13 +111,14 @@ void CalDAVSource::listAllSubItems(SubRevisionMap_t &revisions)
while (true) { while (true) {
string data; string data;
Neon::XMLParser parser; Neon::XMLParser parser;
parser.initReportParser(boost::bind(&CalDAVSource::appendItem, this, auto process = [this, &revisions, &data] (const std::string &href, const std::string &etag, const std::string &status) {
boost::ref(revisions), return appendItem(revisions, href, etag, data);
_1, _2, boost::ref(data))); };
parser.initReportParser(process);
m_cache.clear(); m_cache.clear();
m_cache.m_initialized = false; m_cache.m_initialized = false;
parser.pushHandler(boost::bind(Neon::XMLParser::accept, "urn:ietf:params:xml:ns:caldav", "calendar-data", _2, _3), parser.pushHandler(Neon::XMLParser::accept("urn:ietf:params:xml:ns:caldav", "calendar-data"),
boost::bind(Neon::XMLParser::append, boost::ref(data), _2, _3)); Neon::XMLParser::append(data));
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser); Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
report.addHeader("Depth", "1"); report.addHeader("Depth", "1");
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\""); report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
@ -124,14 +130,6 @@ void CalDAVSource::listAllSubItems(SubRevisionMap_t &revisions)
m_cache.m_initialized = true; m_cache.m_initialized = true;
} }
void CalDAVSource::addResource(StringMap &items,
const std::string &href,
const std::string &etag)
{
std::string davLUID = path2luid(Neon::URI::parse(href).m_path);
items[davLUID] = ETag2Rev(etag);
}
void CalDAVSource::updateAllSubItems(SubRevisionMap_t &revisions) void CalDAVSource::updateAllSubItems(SubRevisionMap_t &revisions)
{ {
// list items to identify new, updated and removed ones // list items to identify new, updated and removed ones
@ -157,8 +155,11 @@ void CalDAVSource::updateAllSubItems(SubRevisionMap_t &revisions)
string data; string data;
Neon::XMLParser parser; Neon::XMLParser parser;
items.clear(); items.clear();
parser.initReportParser(boost::bind(&CalDAVSource::addResource, auto process = [this, &items] (const std::string &href, const std::string &etag, const std::string &status) {
this, boost::ref(items), _1, _2)); std::string davLUID = path2luid(Neon::URI::parse(href).m_path);
items[davLUID] = ETag2Rev(etag);
};
parser.initReportParser(process);
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser); Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
report.addHeader("Depth", "1"); report.addHeader("Depth", "1");
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\""); report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
@ -250,12 +251,15 @@ void CalDAVSource::updateAllSubItems(SubRevisionMap_t &revisions)
while (true) { while (true) {
string data; string data;
Neon::XMLParser parser; Neon::XMLParser parser;
parser.initReportParser(boost::bind(&CalDAVSource::appendMultigetResult, this, auto process = [this, &revisions, &results, &data] (const std::string &href, const std::string &etag, const std::string &status) {
boost::ref(revisions), // record which items were seen in the response...
boost::ref(results), results.insert(path2luid(href));
_1, _2, boost::ref(data))); // and store information about them
parser.pushHandler(boost::bind(Neon::XMLParser::accept, "urn:ietf:params:xml:ns:caldav", "calendar-data", _2, _3), return appendItem(revisions, href, etag, data);
boost::bind(Neon::XMLParser::append, boost::ref(data), _2, _3)); };
parser.initReportParser(process);
parser.pushHandler(Neon::XMLParser::accept("urn:ietf:params:xml:ns:caldav", "calendar-data"),
Neon::XMLParser::append(data));
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, Neon::Request report(*getSession(), "REPORT", getCalendar().m_path,
query, parser); query, parser);
report.addHeader("Depth", "1"); report.addHeader("Depth", "1");
@ -289,18 +293,6 @@ void CalDAVSource::updateAllSubItems(SubRevisionMap_t &revisions)
} }
} }
int CalDAVSource::appendMultigetResult(SubRevisionMap_t &revisions,
std::set<std::string> &luids,
const std::string &href,
const std::string &etag,
std::string &data)
{
// record which items were seen in the response...
luids.insert(path2luid(href));
// and store information about them
return appendItem(revisions, href, etag, data);
}
int CalDAVSource::appendItem(SubRevisionMap_t &revisions, int CalDAVSource::appendItem(SubRevisionMap_t &revisions,
const std::string &href, const std::string &href,
const std::string &etag, const std::string &etag,
@ -351,7 +343,7 @@ int CalDAVSource::appendItem(SubRevisionMap_t &revisions,
} }
if (!m_cache.m_initialized) { if (!m_cache.m_initialized) {
boost::shared_ptr<Event> event(new Event); auto event = std::make_shared<Event>();
event->m_DAVluid = davLUID; event->m_DAVluid = davLUID;
event->m_UID = uid; event->m_UID = uid;
event->m_etag = entry.m_revision; event->m_etag = entry.m_revision;
@ -376,7 +368,7 @@ int CalDAVSource::appendItem(SubRevisionMap_t &revisions,
void CalDAVSource::addSubItem(const std::string &luid, void CalDAVSource::addSubItem(const std::string &luid,
const SubRevisionEntry &entry) const SubRevisionEntry &entry)
{ {
boost::shared_ptr<Event> &event = m_cache[luid]; std::shared_ptr<Event> &event = m_cache[luid];
event.reset(new Event); event.reset(new Event);
event->m_DAVluid = luid; event->m_DAVluid = luid;
event->m_etag = entry.m_revision; event->m_etag = entry.m_revision;
@ -406,7 +398,7 @@ SubSyncSource::SubItemResult CalDAVSource::insertSubItem(const std::string &luid
SubItemResult subres; SubItemResult subres;
// parse new event // parse new event
boost::shared_ptr<Event> newEvent(new Event); auto newEvent = std::make_shared<Event>();
newEvent->m_calendar.set(icalcomponent_new_from_string((char *)item.c_str()), // hack for old libical newEvent->m_calendar.set(icalcomponent_new_from_string((char *)item.c_str()), // hack for old libical
"parsing iCalendar 2.0"); "parsing iCalendar 2.0");
@ -1062,20 +1054,6 @@ CalDAVSource::Event &CalDAVSource::loadItem(const std::string &davLUID)
return loadItem(event); return loadItem(event);
} }
int CalDAVSource::storeItem(const std::string &wantedLuid,
std::string &item,
std::string &data,
const std::string &href)
{
std::string luid = path2luid(Neon::URI::parse(href).m_path);
if (luid == wantedLuid) {
SE_LOG_DEBUG(NULL, "got item %s via REPORT fallback", luid.c_str());
item = data;
}
data.clear();
return 0;
}
CalDAVSource::Event &CalDAVSource::loadItem(Event &event) CalDAVSource::Event &CalDAVSource::loadItem(Event &event)
{ {
if (!event.m_calendar) { if (!event.m_calendar) {
@ -1111,8 +1089,8 @@ CalDAVSource::Event &CalDAVSource::loadItem(Event &event)
std::string href, etag; std::string href, etag;
item = ""; item = "";
parser.initReportParser(href, etag); parser.initReportParser(href, etag);
parser.pushHandler(boost::bind(Neon::XMLParser::accept, "urn:ietf:params:xml:ns:caldav", "calendar-data", _2, _3), parser.pushHandler(Neon::XMLParser::accept("urn:ietf:params:xml:ns:caldav", "calendar-data"),
boost::bind(Neon::XMLParser::append, boost::ref(item), _2, _3)); Neon::XMLParser::append(item));
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser); Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\""); report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
report.run(); report.run();
@ -1142,14 +1120,19 @@ CalDAVSource::Event &CalDAVSource::loadItem(Event &event)
while (true) { while (true) {
Neon::XMLParser parser; Neon::XMLParser parser;
std::string data; std::string data;
parser.initReportParser(boost::bind(&CalDAVSource::storeItem,
this, auto store = [this, &event, &item, &data] (const std::string &href, const std::string &etag, const std::string &status) {
boost::ref(event.m_DAVluid), std::string luid = path2luid(Neon::URI::parse(href).m_path);
boost::ref(item), if (luid == event.m_DAVluid) {
boost::ref(data), SE_LOG_DEBUG(NULL, "got item %s via REPORT fallback", luid.c_str());
_1)); item = data;
parser.pushHandler(boost::bind(Neon::XMLParser::accept, "urn:ietf:params:xml:ns:caldav", "calendar-data", _2, _3), }
boost::bind(Neon::XMLParser::append, boost::ref(data), _2, _3)); data.clear();
return 0;
};
parser.initReportParser(store);
parser.pushHandler(Neon::XMLParser::accept("urn:ietf:params:xml:ns:caldav", "calendar-data"),
Neon::XMLParser::append(data));
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser); Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
report.addHeader("Depth", "1"); report.addHeader("Depth", "1");
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\""); report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
@ -1365,30 +1348,7 @@ void CalDAVSource::backupData(const SyncSource::Operations::ConstBackupInfo &old
"</C:calendar-query>\n"; "</C:calendar-query>\n";
string data; string data;
Neon::XMLParser parser; Neon::XMLParser parser;
parser.initReportParser(boost::bind(&CalDAVSource::backupItem, this, auto process = [this, &cache, &data] (const std::string &href, const std::string &etag, const std::string &status) {
boost::ref(cache),
_1, _2, boost::ref(data)));
parser.pushHandler(boost::bind(Neon::XMLParser::accept, "urn:ietf:params:xml:ns:caldav", "calendar-data", _2, _3),
boost::bind(Neon::XMLParser::append, boost::ref(data), _2, _3));
Timespec deadline = createDeadline();
getSession()->startOperation("REPORT 'full calendar'", deadline);
while (true) {
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
report.addHeader("Depth", "1");
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
if (report.run()) {
break;
}
cache.reset();
}
cache.finalize(backupReport);
}
int CalDAVSource::backupItem(ItemCache &cache,
const std::string &href,
const std::string &etag,
std::string &data)
{
// detect and ignore empty items, like we do in appendItem() // detect and ignore empty items, like we do in appendItem()
eptr<icalcomponent> calendar(icalcomponent_new_from_string((char *)data.c_str()), // cast is a hack for broken definition in old libical eptr<icalcomponent> calendar(icalcomponent_new_from_string((char *)data.c_str()), // cast is a hack for broken definition in old libical
"iCalendar 2.0"); "iCalendar 2.0");
@ -1404,7 +1364,24 @@ int CalDAVSource::backupItem(ItemCache &cache,
// reset data for next item // reset data for next item
data.clear(); data.clear();
return 0; return 0;
};
parser.initReportParser(process);
parser.pushHandler(Neon::XMLParser::accept("urn:ietf:params:xml:ns:caldav", "calendar-data"),
Neon::XMLParser::append(data));
Timespec deadline = createDeadline();
getSession()->startOperation("REPORT 'full calendar'", deadline);
while (true) {
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
report.addHeader("Depth", "1");
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
if (report.run()) {
break;
} }
cache.reset();
}
cache.finalize(backupReport);
}
void CalDAVSource::restoreData(const SyncSource::Operations::ConstBackupInfo &oldBackup, void CalDAVSource::restoreData(const SyncSource::Operations::ConstBackupInfo &oldBackup,
bool dryrun, bool dryrun,

View File

@ -15,7 +15,7 @@
#include <syncevo/SmartPtr.h> #include <syncevo/SmartPtr.h>
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include <boost/shared_ptr.hpp> #include <memory>
#include <syncevo/declarations.h> #include <syncevo/declarations.h>
SE_BEGIN_CXX SE_BEGIN_CXX
@ -25,7 +25,7 @@ class CalDAVSource : public WebDAVSource,
public SyncSourceLogging public SyncSourceLogging
{ {
public: public:
CalDAVSource(const SyncSourceParams &params, const boost::shared_ptr<SyncEvo::Neon::Settings> &settings); CalDAVSource(const SyncSourceParams &params, const std::shared_ptr<SyncEvo::Neon::Settings> &settings);
/* implementation of SyncSourceSerialize interface */ /* implementation of SyncSourceSerialize interface */
virtual std::string getMimeType() const { return "text/calendar"; } virtual std::string getMimeType() const { return "text/calendar"; }
@ -160,7 +160,7 @@ class CalDAVSource : public WebDAVSource,
* again before parsing (depends on server preserving X- * again before parsing (depends on server preserving X-
* extensions, see Event::unescapeRecurrenceID()). * extensions, see Event::unescapeRecurrenceID()).
*/ */
class EventCache : public std::map<std::string, boost::shared_ptr<Event> > class EventCache : public std::map<std::string, std::shared_ptr<Event> >
{ {
public: public:
EventCache() : m_initialized(false) {} EventCache() : m_initialized(false) {}
@ -175,40 +175,15 @@ class CalDAVSource : public WebDAVSource,
std::string getSubDescription(Event &event, const string &subid); std::string getSubDescription(Event &event, const string &subid);
/** calback for multiget: same as appendItem, but also records luid of all responses */
int appendMultigetResult(SubRevisionMap_t &revisions,
std::set<std::string> &luids,
const std::string &href,
const std::string &etag,
std::string &data);
/** callback for listAllSubItems: parse and add new item */ /** callback for listAllSubItems: parse and add new item */
int appendItem(SubRevisionMap_t &revisions, int appendItem(SubRevisionMap_t &revisions,
const std::string &href, const std::string &href,
const std::string &etag, const std::string &etag,
std::string &data); std::string &data);
/** callback for backupData(): dump into backup */
int backupItem(ItemCache &cache,
const std::string &href,
const std::string &etag,
std::string &data);
/** callback for loadItem(): store right item from REPORT */
int storeItem(const std::string &wantedLuid,
std::string &item,
std::string &data,
const std::string &href);
/** add to m_cache */ /** add to m_cache */
void addSubItem(const std::string &luid, void addSubItem(const std::string &luid,
const SubRevisionEntry &entry); const SubRevisionEntry &entry);
/** store as luid + revision */
void addResource(StringMap &items,
const std::string &href,
const std::string &etag);
}; };
SE_END_CXX SE_END_CXX

View File

@ -14,7 +14,7 @@ SE_BEGIN_CXX
CalDAVVxxSource::CalDAVVxxSource(const std::string &content, CalDAVVxxSource::CalDAVVxxSource(const std::string &content,
const SyncSourceParams &params, const SyncSourceParams &params,
const boost::shared_ptr<Neon::Settings> &settings) : const std::shared_ptr<Neon::Settings> &settings) :
WebDAVSource(params, settings), WebDAVSource(params, settings),
m_content(content) m_content(content)
{ {

View File

@ -15,7 +15,7 @@
#include <syncevo/SmartPtr.h> #include <syncevo/SmartPtr.h>
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include <boost/shared_ptr.hpp> #include <memory>
#include <syncevo/declarations.h> #include <syncevo/declarations.h>
SE_BEGIN_CXX SE_BEGIN_CXX
@ -39,7 +39,7 @@ class CalDAVVxxSource : public WebDAVSource,
*/ */
CalDAVVxxSource(const std::string &content, CalDAVVxxSource(const std::string &content,
const SyncSourceParams &params, const SyncSourceParams &params,
const boost::shared_ptr<SyncEvo::Neon::Settings> &settings); const std::shared_ptr<SyncEvo::Neon::Settings> &settings);
/* implementation of SyncSourceSerialize interface */ /* implementation of SyncSourceSerialize interface */
virtual std::string getMimeType() const { virtual std::string getMimeType() const {

View File

@ -12,7 +12,7 @@ SE_BEGIN_CXX
// TODO: use EDS backend icalstrdup.c // TODO: use EDS backend icalstrdup.c
#define ical_strdup(_x) (_x) #define ical_strdup(_x) (_x)
typedef boost::shared_ptr<TransportStatusException> BatchReadFailure; typedef std::shared_ptr<TransportStatusException> BatchReadFailure;
class CardDAVCache : public std::map< std::string, boost::variant<std::string, BatchReadFailure> > class CardDAVCache : public std::map< std::string, boost::variant<std::string, BatchReadFailure> >
{ {
@ -20,7 +20,7 @@ class CardDAVCache : public std::map< std::string, boost::variant<std::string, B
CardDAVSource::CardDAVSource(const SyncSourceParams &params, CardDAVSource::CardDAVSource(const SyncSourceParams &params,
const boost::shared_ptr<Neon::Settings> &settings) : const std::shared_ptr<Neon::Settings> &settings) :
WebDAVSource(params, settings), WebDAVSource(params, settings),
m_readAheadOrder(READ_NONE), m_readAheadOrder(READ_NONE),
m_cacheMisses(0), m_cacheMisses(0),
@ -100,7 +100,7 @@ static size_t MaxBatchSize()
return maxBatchSize; return maxBatchSize;
} }
boost::shared_ptr<CardDAVCache> CardDAVSource::readBatch(const std::string &luid) std::shared_ptr<CardDAVCache> CardDAVSource::readBatch(const std::string &luid)
{ {
static size_t maxBatchSize = MaxBatchSize(); static size_t maxBatchSize = MaxBatchSize();
BatchLUIDs luids; BatchLUIDs luids;
@ -167,7 +167,7 @@ boost::shared_ptr<CardDAVCache> CardDAVSource::readBatch(const std::string &luid
break; break;
} }
boost::shared_ptr<CardDAVCache> cache; std::shared_ptr<CardDAVCache> cache;
if (m_readAheadOrder != READ_NONE && if (m_readAheadOrder != READ_NONE &&
!found) { !found) {
// The requested contact was not on our list. Consider this // The requested contact was not on our list. Consider this
@ -207,41 +207,7 @@ boost::shared_ptr<CardDAVCache> CardDAVSource::readBatch(const std::string &luid
// The purpose of that is two-fold: don't request data again that // The purpose of that is two-fold: don't request data again that
// we already got when resending, and detect missing 404 status errors // we already got when resending, and detect missing 404 status errors
// with Google. // with Google.
parser.initReportParser(boost::bind(&CardDAVSource::addItemToCache, this, auto process = [this, &luids, &data, &cache] (const std::string &href, const std::string &etag, const std::string &status) {
cache, boost::ref(luids),
_1, _2, boost::ref(data)));
parser.pushHandler(boost::bind(Neon::XMLParser::accept, "urn:ietf:params:xml:ns:carddav", "address-data", _2, _3),
boost::bind(Neon::XMLParser::append, boost::ref(data), _2, _3));
std::string request = query.str();
Neon::Request req(*getSession(), "REPORT", getCalendar().m_path,
request, parser);
req.addHeader("Depth", "0");
req.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
if (req.run()) {
// CardDAV servers must include a response for each requested item.
// Google CardDAV doesn't due that at the time of implementing the
// batched read. As a workaround assume that any remaining item
// isn't available.
for (const std::string *luid: luids) {
boost::shared_ptr<TransportStatusException> failure(new TransportStatusException(__FILE__,
__LINE__,
StringPrintf("%s: not contained in multiget response", luid->c_str()),
STATUS_NOT_FOUND));
(*cache)[*luid] = failure;
}
break;
}
}
}
return cache;
}
void CardDAVSource::addItemToCache(boost::shared_ptr<CardDAVCache> &cache,
BatchLUIDs &luids,
const std::string &href,
const std::string &etag,
std::string &data)
{
std::string luid = path2luid(href); std::string luid = path2luid(href);
// TODO: error checking // TODO: error checking
@ -273,6 +239,32 @@ void CardDAVSource::addItemToCache(boost::shared_ptr<CardDAVCache> &cache,
// reset data for next item // reset data for next item
data.clear(); data.clear();
};
parser.initReportParser(process);
parser.pushHandler(Neon::XMLParser::accept("urn:ietf:params:xml:ns:carddav", "address-data"),
Neon::XMLParser::append(data));
std::string request = query.str();
Neon::Request req(*getSession(), "REPORT", getCalendar().m_path,
request, parser);
req.addHeader("Depth", "0");
req.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
if (req.run()) {
// CardDAV servers must include a response for each requested item.
// Google CardDAV doesn't due that at the time of implementing the
// batched read. As a workaround assume that any remaining item
// isn't available.
for (const std::string *luid: luids) {
auto failure = std::make_shared<TransportStatusException>(__FILE__,
__LINE__,
StringPrintf("%s: not contained in multiget response", luid->c_str()),
STATUS_NOT_FOUND);
(*cache)[*luid] = failure;
}
break;
}
}
}
return cache;
} }
CardDAVSource::InsertItemResult CardDAVSource::insertItem(const string &luid, const std::string &item, bool raw) CardDAVSource::InsertItemResult CardDAVSource::insertItem(const string &luid, const std::string &item, bool raw)

View File

@ -15,7 +15,7 @@
#include <syncevo/SmartPtr.h> #include <syncevo/SmartPtr.h>
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include <boost/shared_ptr.hpp> #include <memory>
#include <syncevo/declarations.h> #include <syncevo/declarations.h>
SE_BEGIN_CXX SE_BEGIN_CXX
@ -26,7 +26,7 @@ class CardDAVSource : public WebDAVSource,
public SyncSourceLogging public SyncSourceLogging
{ {
public: public:
CardDAVSource(const SyncSourceParams &params, const boost::shared_ptr<SyncEvo::Neon::Settings> &settings); CardDAVSource(const SyncSourceParams &params, const std::shared_ptr<SyncEvo::Neon::Settings> &settings);
/* implementation of SyncSourceSerialize interface */ /* implementation of SyncSourceSerialize interface */
virtual std::string getMimeType() const { return "text/vcard"; } virtual std::string getMimeType() const { return "text/vcard"; }
@ -59,7 +59,7 @@ class CardDAVSource : public WebDAVSource,
private: private:
ReadAheadOrder m_readAheadOrder; ReadAheadOrder m_readAheadOrder;
ReadAheadItems m_nextLUIDs; ReadAheadItems m_nextLUIDs;
boost::shared_ptr<CardDAVCache> m_cardDAVCache; std::shared_ptr<CardDAVCache> m_cardDAVCache;
int m_cacheMisses; /**< number of times that we had to get a contact without using the cache */ int m_cacheMisses; /**< number of times that we had to get a contact without using the cache */
int m_contactReads; /**< number of readItem() calls */ int m_contactReads; /**< number of readItem() calls */
int m_contactsFromDB; /**< number of contacts requested from DB (including ones not found) */ int m_contactsFromDB; /**< number of contacts requested from DB (including ones not found) */
@ -68,13 +68,8 @@ class CardDAVSource : public WebDAVSource,
typedef std::vector<const std::string *> BatchLUIDs; typedef std::vector<const std::string *> BatchLUIDs;
void logCacheStats(Logger::Level level); void logCacheStats(Logger::Level level);
boost::shared_ptr<CardDAVCache> readBatch(const std::string &luid); std::shared_ptr<CardDAVCache> readBatch(const std::string &luid);
void invalidateCachedItem(const std::string &luid); void invalidateCachedItem(const std::string &luid);
void addItemToCache(boost::shared_ptr<CardDAVCache> &cache,
BatchLUIDs &luids,
const std::string &href,
const std::string &etag,
std::string &data);
void readItemInternal(const std::string &luid, std::string &item, bool raw); void readItemInternal(const std::string &luid, std::string &item, bool raw);
}; };

View File

@ -15,8 +15,6 @@
#include <list> #include <list>
#include <boost/algorithm/string/join.hpp> #include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/split.hpp> #include <boost/algorithm/string/split.hpp>
#include <boost/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <syncevo/util.h> #include <syncevo/util.h>
#include <syncevo/Logging.h> #include <syncevo/Logging.h>
@ -187,7 +185,7 @@ std::string Status2String(const ne_status *status)
status->reason_phrase ? status->reason_phrase : "\"\""); status->reason_phrase ? status->reason_phrase : "\"\"");
} }
Session::Session(const boost::shared_ptr<Settings> &settings) : Session::Session(const std::shared_ptr<Settings> &settings) :
m_forceAuthorizationOnce(AUTH_ON_DEMAND), m_forceAuthorizationOnce(AUTH_ON_DEMAND),
m_credentialsSent(false), m_credentialsSent(false),
m_settings(settings), m_settings(settings),
@ -285,9 +283,9 @@ Session::~Session()
ne_sock_exit(); ne_sock_exit();
} }
boost::shared_ptr<Session> Session::m_cachedSession; std::shared_ptr<Session> Session::m_cachedSession;
boost::shared_ptr<Session> Session::create(const boost::shared_ptr<Settings> &settings) std::shared_ptr<Session> Session::create(const std::shared_ptr<Settings> &settings)
{ {
URI uri = URI::parse(settings->getURL()); URI uri = URI::parse(settings->getURL());
if (m_cachedSession && if (m_cachedSession &&
@ -306,7 +304,7 @@ boost::shared_ptr<Session> Session::create(const boost::shared_ptr<Settings> &se
int Session::getCredentials(const char *realm, int attempt, char *username, char *password) noexcept int Session::getCredentials(const char *realm, int attempt, char *username, char *password) noexcept
{ {
try { try {
boost::shared_ptr<AuthProvider> authProvider = m_settings->getAuthProvider(); std::shared_ptr<AuthProvider> authProvider = m_settings->getAuthProvider();
if (authProvider && authProvider->methodIsSupported(AuthProvider::AUTH_METHOD_OAUTH2)) { if (authProvider && authProvider->methodIsSupported(AuthProvider::AUTH_METHOD_OAUTH2)) {
// We have to fail here because we cannot provide neon // We have to fail here because we cannot provide neon
// with a username/password combination. Instead we rely // with a username/password combination. Instead we rely
@ -335,7 +333,7 @@ int Session::getCredentials(const char *realm, int attempt, char *username, char
} }
void Session::forceAuthorization(ForceAuthorization forceAuthorization, void Session::forceAuthorization(ForceAuthorization forceAuthorization,
const boost::shared_ptr<AuthProvider> &authProvider) const std::shared_ptr<AuthProvider> &authProvider)
{ {
m_forceAuthorizationOnce = forceAuthorization; m_forceAuthorizationOnce = forceAuthorization;
m_authProvider = authProvider; m_authProvider = authProvider;
@ -444,11 +442,11 @@ void Session::propfindURI(const std::string &path, int depth,
startOperation("PROPFIND", deadline); startOperation("PROPFIND", deadline);
retry: retry:
boost::shared_ptr<ne_propfind_handler> handler; std::shared_ptr<ne_propfind_handler> handler;
int error; int error;
checkAuthorization(); checkAuthorization();
handler = boost::shared_ptr<ne_propfind_handler>(ne_propfind_create(m_session, path.c_str(), depth), handler = std::shared_ptr<ne_propfind_handler>(ne_propfind_create(m_session, path.c_str(), depth),
PropFindDeleter()); PropFindDeleter());
auto propsResult = [] (void *userdata, const ne_uri *uri, auto propsResult = [] (void *userdata, const ne_uri *uri,
const ne_prop_result_set *results) noexcept { const ne_prop_result_set *results) noexcept {
@ -806,16 +804,10 @@ XMLParser &XMLParser::pushHandler(const StartCB_t &start,
{ {
m_stack.push_back(Callbacks(start, data, end)); m_stack.push_back(Callbacks(start, data, end));
Callbacks &cb = m_stack.back(); Callbacks &cb = m_stack.back();
ne_xml_push_handler(m_parser,
startCB, dataCB, endCB,
&cb);
return *this;
}
int XMLParser::startCB(void *userdata, int parent, auto startCB = [] (void *userdata, int parent,
const char *nspace, const char *name, const char *nspace, const char *name,
const char **atts) const char **atts) noexcept {
{
Callbacks *cb = static_cast<Callbacks *>(userdata); Callbacks *cb = static_cast<Callbacks *>(userdata);
try { try {
return cb->m_start(parent, nspace, name, atts); return cb->m_start(parent, nspace, name, atts);
@ -824,11 +816,10 @@ int XMLParser::startCB(void *userdata, int parent,
SE_LOG_ERROR(NULL, "startCB %s %s failed", nspace, name); SE_LOG_ERROR(NULL, "startCB %s %s failed", nspace, name);
return -1; return -1;
} }
} };
int XMLParser::dataCB(void *userdata, int state, auto dataCB = [] (void *userdata, int state,
const char *cdata, size_t len) const char *cdata, size_t len) noexcept {
{
Callbacks *cb = static_cast<Callbacks *>(userdata); Callbacks *cb = static_cast<Callbacks *>(userdata);
try { try {
return cb->m_data ? return cb->m_data ?
@ -839,11 +830,10 @@ int XMLParser::dataCB(void *userdata, int state,
SE_LOG_ERROR(NULL, "dataCB failed"); SE_LOG_ERROR(NULL, "dataCB failed");
return -1; return -1;
} }
} };
int XMLParser::endCB(void *userdata, int state, auto endCB = [] (void *userdata, int state,
const char *nspace, const char *name) const char *nspace, const char *name) noexcept {
{
Callbacks *cb = static_cast<Callbacks *>(userdata); Callbacks *cb = static_cast<Callbacks *>(userdata);
try { try {
return cb->m_end ? return cb->m_end ?
@ -854,68 +844,73 @@ int XMLParser::endCB(void *userdata, int state,
SE_LOG_ERROR(NULL, "endCB %s %s failed", nspace, name); SE_LOG_ERROR(NULL, "endCB %s %s failed", nspace, name);
return -1; return -1;
} }
};
ne_xml_push_handler(m_parser,
startCB, dataCB, endCB,
&cb);
return *this;
} }
XMLParser::StartCB_t XMLParser::accept(const std::string &nspaceExpected,
int XMLParser::accept(const std::string &nspaceExpected, const std::string &nameExpected)
const std::string &nameExpected,
const char *nspace,
const char *name)
{ {
return [nspaceExpected, nameExpected] (int state, const char *nspace, const char *name, const char **attributes) {
if (nspace && nspaceExpected == nspace && if (nspace && nspaceExpected == nspace &&
name && nameExpected == name) { name && nameExpected == name) {
return 1; return 1;
} else { } else {
return 0; return 0;
} }
};
} }
int XMLParser::append(std::string &buffer, XMLParser::DataCB_t XMLParser::append(std::string &buffer)
const char *data,
size_t len)
{ {
buffer.append(data, len); return [&buffer] (int state, const char *newdata, size_t len) {
return 0; buffer.append(newdata, len);
}
int XMLParser::reset(std::string &buffer)
{
buffer.clear();
return 0; return 0;
};
} }
void XMLParser::initAbortingReportParser(const ResponseEndCB_t &responseEnd) void XMLParser::initAbortingReportParser(const ResponseEndCB_t &responseEnd)
{ {
pushHandler(boost::bind(Neon::XMLParser::accept, "DAV:", "multistatus", _2, _3)); pushHandler(accept("DAV:", "multistatus"));
pushHandler(boost::bind(Neon::XMLParser::accept, "DAV:", "response", _2, _3), pushHandler(accept("DAV:", "response"),
Neon::XMLParser::DataCB_t(), {},
boost::bind(&Neon::XMLParser::doResponseEnd, [this, responseEnd] (int state, const char *nspace, const char *name) {
this, responseEnd)); int abort = 0;
pushHandler(boost::bind(Neon::XMLParser::accept, "DAV:", "href", _2, _3), if (responseEnd) {
boost::bind(Neon::XMLParser::append, boost::ref(m_href), _2, _3)); abort = responseEnd(m_href, m_etag, m_status);
pushHandler(boost::bind(Neon::XMLParser::accept, "DAV:", "propstat", _2, _3));
pushHandler(boost::bind(Neon::XMLParser::accept, "DAV:", "status", _2, _3),
boost::bind(Neon::XMLParser::append, boost::ref(m_status), _2, _3));
pushHandler(boost::bind(Neon::XMLParser::accept, "DAV:", "prop", _2, _3));
pushHandler(boost::bind(Neon::XMLParser::accept, "DAV:", "getetag", _2, _3),
boost::bind(Neon::XMLParser::append, boost::ref(m_etag), _2, _3));
} }
// clean up for next response
static int VoidResponseEndCBWrapper(const XMLParser::VoidResponseEndCB_t &responseEnd, m_href.clear();
const std::string &href, m_etag.clear();
const std::string &etag, m_status.clear();
const std::string &status) return abort;
{ });
responseEnd(href, etag, status); pushHandler(accept("DAV:", "href"),
return 0; append(m_href));
pushHandler(accept("DAV:", "propstat"));
pushHandler(accept("DAV:", "status"),
append(m_status));
pushHandler(accept("DAV:", "prop"));
pushHandler(accept("DAV:", "getetag"),
append(m_etag));
} }
void XMLParser::initReportParser(const VoidResponseEndCB_t &responseEnd) void XMLParser::initReportParser(const VoidResponseEndCB_t &responseEnd)
{ {
if (responseEnd) { if (responseEnd) {
initAbortingReportParser(boost::bind(VoidResponseEndCBWrapper, responseEnd, _1, _2, _3)); auto end = [responseEnd] (const std::string &href,
const std::string &etag,
const std::string &status) {
responseEnd(href, etag, status);
return 0;
};
initAbortingReportParser(end);
} else { } else {
initAbortingReportParser(ResponseEndCB_t()); initAbortingReportParser();
} }
} }
@ -974,7 +969,10 @@ void Session::checkAuthorization()
// Count the number of times we asked for new tokens. This helps // Count the number of times we asked for new tokens. This helps
// the provider determine whether the token that it returns are valid. // the provider determine whether the token that it returns are valid.
try { try {
m_oauth2Bearer = m_authProvider->getOAuth2Bearer(boost::bind(&Settings::updatePassword, m_settings, _1)); auto update_password = [this] (const std::string& password) {
m_settings->updatePassword(password);
};
m_oauth2Bearer = m_authProvider->getOAuth2Bearer(update_password);
SE_LOG_DEBUG(NULL, "got new OAuth2 token '%s' for next request", m_oauth2Bearer.c_str()); SE_LOG_DEBUG(NULL, "got new OAuth2 token '%s' for next request", m_oauth2Bearer.c_str());
} catch (...) { } catch (...) {
std::string explanation; std::string explanation;
@ -988,7 +986,7 @@ void Session::checkAuthorization()
} }
} }
bool Session::run(Request &request, const std::set<int> *expectedCodes, const boost::function<bool ()> &aborted) bool Session::run(Request &request, const std::set<int> *expectedCodes, const std::function<bool ()> &aborted)
{ {
int error; int error;
@ -999,8 +997,13 @@ bool Session::run(Request &request, const std::set<int> *expectedCodes, const bo
ne_request *req = request.getRequest(); ne_request *req = request.getRequest();
if (result) { if (result) {
result->clear(); result->clear();
auto addResultData = [] (void *userdata, const char *buf, size_t len) {
Request *me = static_cast<Request *>(userdata);
me->m_result->append(buf, len);
return 0;
};
ne_add_response_body_reader(req, ne_accept_2xx, ne_add_response_body_reader(req, ne_accept_2xx,
Request::addResultData, &request); addResultData, &request);
error = ne_request_dispatch(req); error = ne_request_dispatch(req);
} else { } else {
error = ne_xml_dispatch_request(req, request.getParser()->get()); error = ne_xml_dispatch_request(req, request.getParser()->get());
@ -1017,13 +1020,6 @@ bool Session::run(Request &request, const std::set<int> *expectedCodes, const bo
expectedCodes); expectedCodes);
} }
int Request::addResultData(void *userdata, const char *buf, size_t len)
{
Request *me = static_cast<Request *>(userdata);
me->m_result->append(buf, len);
return 0;
}
} }
SE_END_CXX SE_END_CXX

View File

@ -16,13 +16,12 @@
#include <ne_props.h> #include <ne_props.h>
#include <ne_request.h> #include <ne_request.h>
#include <memory>
#include <functional>
#include <string> #include <string>
#include <list> #include <list>
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
#include <syncevo/util.h> #include <syncevo/util.h>
#include <syncevo/declarations.h> #include <syncevo/declarations.h>
SE_BEGIN_CXX SE_BEGIN_CXX
@ -88,7 +87,7 @@ class Settings {
* Grant access to AuthProvider. In addition to plain username/password * Grant access to AuthProvider. In addition to plain username/password
* in getCredentials, this one here might also be used for OAuth2. * in getCredentials, this one here might also be used for OAuth2.
*/ */
virtual boost::shared_ptr<AuthProvider> getAuthProvider() = 0; virtual std::shared_ptr<AuthProvider> getAuthProvider() = 0;
/** /**
* Updates password to new one returned during OAuth2 authorization. * Updates password to new one returned during OAuth2 authorization.
@ -307,11 +306,11 @@ class Session {
/** /**
* @param settings must provide information about settings on demand * @param settings must provide information about settings on demand
*/ */
Session(const boost::shared_ptr<Settings> &settings); Session(const std::shared_ptr<Settings> &settings);
static boost::shared_ptr<Session> m_cachedSession; static std::shared_ptr<Session> m_cachedSession;
ForceAuthorization m_forceAuthorizationOnce; ForceAuthorization m_forceAuthorizationOnce;
boost::shared_ptr<AuthProvider> m_authProvider; std::shared_ptr<AuthProvider> m_authProvider;
/** /**
* Count how often a request was sent with credentials. * Count how often a request was sent with credentials.
@ -347,7 +346,7 @@ class Session {
* to reuse proxy information (libproxy has a considerably delay during * to reuse proxy information (libproxy has a considerably delay during
* initialization) and HTTP connection/authentication. * initialization) and HTTP connection/authentication.
*/ */
static boost::shared_ptr<Session> create(const boost::shared_ptr<Settings> &settings); static std::shared_ptr<Session> create(const std::shared_ptr<Settings> &settings);
~Session(); ~Session();
#ifdef HAVE_LIBNEON_OPTIONS #ifdef HAVE_LIBNEON_OPTIONS
@ -358,13 +357,13 @@ class Session {
/** /**
* called with URI and complete result set; exceptions are logged, but ignored * called with URI and complete result set; exceptions are logged, but ignored
*/ */
typedef boost::function<void (const URI &, const ne_prop_result_set *)> PropfindURICallback_t; typedef std::function<void (const URI &, const ne_prop_result_set *)> PropfindURICallback_t;
/** /**
* called with URI and specific property, value string may be NULL (error case); * called with URI and specific property, value string may be NULL (error case);
* exceptions are logged and abort iterating over properties (but not URIs) * exceptions are logged and abort iterating over properties (but not URIs)
*/ */
typedef boost::function<void (const URI &, const ne_propname *, const char *, const ne_status *)> PropfindPropCallback_t; typedef std::function<void (const URI &, const ne_propname *, const char *, const ne_status *)> PropfindPropCallback_t;
/** ne_simple_propfind(): invoke callback for each URI */ /** ne_simple_propfind(): invoke callback for each URI */
void propfindURI(const std::string &path, int depth, void propfindURI(const std::string &path, int depth,
@ -413,7 +412,7 @@ class Session {
* @return result of Session::checkError() * @return result of Session::checkError()
*/ */
bool run(Request &request, const std::set<int> *expectedCodes, bool run(Request &request, const std::set<int> *expectedCodes,
const boost::function<bool ()> &aborted = boost::function<bool ()>()); const std::function<bool ()> &aborted = {});
/** /**
* to be called after each operation which might have produced debugging output by neon; * to be called after each operation which might have produced debugging output by neon;
@ -428,10 +427,10 @@ class Session {
* (when username/password are provided by AuthProvider) or all * (when username/password are provided by AuthProvider) or all
* requests to use OAuth2 authentication. * requests to use OAuth2 authentication.
*/ */
void forceAuthorization(ForceAuthorization forceAuthorization, const boost::shared_ptr<AuthProvider> &authProvider); void forceAuthorization(ForceAuthorization forceAuthorization, const std::shared_ptr<AuthProvider> &authProvider);
private: private:
boost::shared_ptr<Settings> m_settings; std::shared_ptr<Settings> m_settings;
bool m_debugging; bool m_debugging;
ne_session *m_session; ne_session *m_session;
URI m_uri; URI m_uri;
@ -489,7 +488,7 @@ class XMLParser
* arguments are parent state, namespace, name, attributes (NULL terminated) * arguments are parent state, namespace, name, attributes (NULL terminated)
* @return < 0 abort, 0 decline, > 0 accept * @return < 0 abort, 0 decline, > 0 accept
*/ */
typedef boost::function<int (int, const char *, const char *, const char **)> StartCB_t; typedef std::function<int (int, const char *, const char *, const char **)> StartCB_t;
/** /**
* See ne_xml_cdata_cb: * See ne_xml_cdata_cb:
@ -497,7 +496,7 @@ class XMLParser
* May be NULL. * May be NULL.
* @return != 0 to abort * @return != 0 to abort
*/ */
typedef boost::function<int (int, const char *, size_t)> DataCB_t; typedef std::function<int (int, const char *, size_t)> DataCB_t;
/** /**
* See ne_xml_endelm_cb: * See ne_xml_endelm_cb:
@ -505,7 +504,7 @@ class XMLParser
* May be NULL. * May be NULL.
* @return != 0 to abort * @return != 0 to abort
*/ */
typedef boost::function<int (int, const char *, const char *)> EndCB_t; typedef std::function<int (int, const char *, const char *)> EndCB_t;
/** /**
* add new handler, see ne_xml_push_handler() * add new handler, see ne_xml_push_handler()
@ -517,22 +516,13 @@ class XMLParser
/** /**
* StartCB_t: accepts a new element if namespace and name match * StartCB_t: accepts a new element if namespace and name match
*/ */
static int accept(const std::string &nspaceExpected, static StartCB_t accept(const std::string &nspaceExpected,
const std::string &nameExpected, const std::string &nameExpected);
const char *nspace,
const char *name);
/** /**
* DataCB_t: append to std::string * DataCB_t: append to std::string
*/ */
static int append(std::string &buffer, static DataCB_t append(std::string &buffer);
const char *data,
size_t len);
/**
* EndCB_t: clear std::string
*/
static int reset(std::string &buffer);
/** /**
* Called each time a response is completely parsed. * Called each time a response is completely parsed.
@ -542,8 +532,8 @@ class XMLParser
* @param status it's status line, empty if not requested or unavailable * @param status it's status line, empty if not requested or unavailable
* @return non-zero for aborting the parsing * @return non-zero for aborting the parsing
*/ */
typedef boost::function<int (const std::string &, const std::string &, const std::string &)> ResponseEndCB_t; typedef std::function<int (const std::string &, const std::string &, const std::string &)> ResponseEndCB_t;
typedef boost::function<void (const std::string &, const std::string &, const std::string &)> VoidResponseEndCB_t; typedef std::function<void (const std::string &, const std::string &, const std::string &)> VoidResponseEndCB_t;
/** /**
* Setup parser for handling REPORT result. * Setup parser for handling REPORT result.
@ -561,8 +551,8 @@ class XMLParser
* when expecting only one response, the callback * when expecting only one response, the callback
* is not needed * is not needed
*/ */
void initReportParser(const VoidResponseEndCB_t &responseEnd = VoidResponseEndCB_t()); void initReportParser(const VoidResponseEndCB_t &responseEnd = {});
void initAbortingReportParser(const ResponseEndCB_t &responseEnd); void initAbortingReportParser(const ResponseEndCB_t &responseEnd = {});
private: private:
ne_xml_parser *m_parser; ne_xml_parser *m_parser;
@ -583,18 +573,6 @@ class XMLParser
/** buffers for initReportParser() */ /** buffers for initReportParser() */
std::string m_href, m_etag, m_status; std::string m_href, m_etag, m_status;
int doResponseEnd(const ResponseEndCB_t &responseEnd) {
int abort = 0;
if (responseEnd) {
abort = responseEnd(m_href, m_etag, m_status);
}
// clean up for next response
m_href.clear();
m_etag.clear();
m_status.clear();
return abort;
}
static int startCB(void *userdata, int parent, static int startCB(void *userdata, int parent,
const char *nspace, const char *name, const char *nspace, const char *name,
const char **atts); const char **atts);
@ -652,9 +630,6 @@ class Request
XMLParser *getParser() const { return m_parser; } XMLParser *getParser() const { return m_parser; }
std::string getPath() const { return m_path; } std::string getPath() const { return m_path; }
/** ne_block_reader implementation */
static int addResultData(void *userdata, const char *buf, size_t len);
private: private:
// buffers for string (copied by ne_request_create(), // buffers for string (copied by ne_request_create(),
// but due to a bug in neon, our method string is still used // but due to a bug in neon, our method string is still used
@ -669,6 +644,8 @@ class Request
ne_request *m_req; ne_request *m_req;
std::string *m_result; std::string *m_result;
XMLParser *m_parser; XMLParser *m_parser;
friend Session;
}; };
/** thrown for 301 HTTP status */ /** thrown for 301 HTTP status */

View File

@ -4,7 +4,6 @@
#include "WebDAVSource.h" #include "WebDAVSource.h"
#include <boost/bind.hpp>
#include <boost/algorithm/string/replace.hpp> #include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/classification.hpp>
@ -42,7 +41,7 @@ public:
typedef std::vector<std::string> URLs; typedef std::vector<std::string> URLs;
private: private:
boost::shared_ptr<SyncConfig> m_context; std::shared_ptr<SyncConfig> m_context;
SyncSourceConfig *m_sourceConfig; SyncSourceConfig *m_sourceConfig;
URLs m_urls; URLs m_urls;
std::string m_urlsDescription; std::string m_urlsDescription;
@ -56,7 +55,7 @@ private:
bool m_credentialsOkay; bool m_credentialsOkay;
public: public:
ContextSettings(const boost::shared_ptr<SyncConfig> &context, ContextSettings(const std::shared_ptr<SyncConfig> &context,
SyncSourceConfig *sourceConfig) : SyncSourceConfig *sourceConfig) :
m_context(context), m_context(context),
m_sourceConfig(sourceConfig), m_sourceConfig(sourceConfig),
@ -106,7 +105,7 @@ public:
// never know that credentials should work (bad for Google, // never know that credentials should work (bad for Google,
// with its temporary authentication errors) // with its temporary authentication errors)
if (m_context) { if (m_context) {
boost::shared_ptr<FilterConfigNode> node = m_context->getNode(WebDAVCredentialsOkay()); std::shared_ptr<FilterConfigNode> node = m_context->getNode(WebDAVCredentialsOkay());
m_credentialsOkay = WebDAVCredentialsOkay().getPropertyValue(*node); m_credentialsOkay = WebDAVCredentialsOkay().getPropertyValue(*node);
} }
} }
@ -155,7 +154,7 @@ public:
std::string &username, std::string &username,
std::string &password); std::string &password);
virtual boost::shared_ptr<AuthProvider> getAuthProvider(); virtual std::shared_ptr<AuthProvider> getAuthProvider();
void updatePassword(const string &password); void updatePassword(const string &password);
@ -168,7 +167,7 @@ public:
virtual bool getCredentialsOkay() { return m_credentialsOkay; } virtual bool getCredentialsOkay() { return m_credentialsOkay; }
virtual void setCredentialsOkay(bool okay) { virtual void setCredentialsOkay(bool okay) {
if (m_credentialsOkay != okay && m_context) { if (m_credentialsOkay != okay && m_context) {
boost::shared_ptr<FilterConfigNode> node = m_context->getNode(WebDAVCredentialsOkay()); std::shared_ptr<FilterConfigNode> node = m_context->getNode(WebDAVCredentialsOkay());
if (!node->isReadOnly()) { if (!node->isReadOnly()) {
WebDAVCredentialsOkay().setProperty(*node, okay); WebDAVCredentialsOkay().setProperty(*node, okay);
node->flush(); node->flush();
@ -186,7 +185,7 @@ public:
private: private:
void initializeFlags(const std::string &url); void initializeFlags(const std::string &url);
boost::shared_ptr<AuthProvider> m_authProvider; std::shared_ptr<AuthProvider> m_authProvider;
void lookupAuthProvider(); void lookupAuthProvider();
}; };
@ -201,7 +200,7 @@ void ContextSettings::getCredentials(const std::string &realm,
password = creds.m_password; password = creds.m_password;
} }
boost::shared_ptr<AuthProvider> ContextSettings::getAuthProvider() std::shared_ptr<AuthProvider> ContextSettings::getAuthProvider()
{ {
lookupAuthProvider(); lookupAuthProvider();
return m_authProvider; return m_authProvider;
@ -310,7 +309,7 @@ WebDAVSource::Props_t::iterator WebDAVSource::Props_t::find(const WebDAVSource::
} }
WebDAVSource::WebDAVSource(const SyncSourceParams &params, WebDAVSource::WebDAVSource(const SyncSourceParams &params,
const boost::shared_ptr<Neon::Settings> &settings) : const std::shared_ptr<Neon::Settings> &settings) :
TrackingSyncSource(params), TrackingSyncSource(params),
m_settings(settings) m_settings(settings)
{ {
@ -320,10 +319,18 @@ WebDAVSource::WebDAVSource(const SyncSourceParams &params,
} }
/* insert contactServer() into BackupData_t and RestoreData_t (implemented by SyncSourceRevisions) */ /* insert contactServer() into BackupData_t and RestoreData_t (implemented by SyncSourceRevisions) */
m_operations.m_backupData = boost::bind(&WebDAVSource::backupData, m_operations.m_backupData = [this, backup = m_operations.m_backupData] (const SyncSource::Operations::ConstBackupInfo &oldBackup,
this, m_operations.m_backupData, _1, _2, _3); const SyncSource::Operations::BackupInfo &newBackup,
m_operations.m_restoreData = boost::bind(&WebDAVSource::restoreData, BackupReport &backupReport) {
this, m_operations.m_restoreData, _1, _2, _3); contactServer();
backup(oldBackup, newBackup, backupReport);
};
m_operations.m_restoreData = [this, restore = m_operations.m_restoreData] (const SyncSource::Operations::ConstBackupInfo &oldBackup,
bool dryrun,
SyncSourceReport &report) {
contactServer();
restore(oldBackup, dryrun, report);
};
// ignore the "Request ends, status 207 class 2xx, error line:" printed by neon // ignore the "Request ends, status 207 class 2xx, error line:" printed by neon
LogRedirect::addIgnoreError(", error line:"); LogRedirect::addIgnoreError(", error line:");
@ -571,22 +578,6 @@ void WebDAVSource::open()
// Nothing to do here, expensive initialization is in contactServer(). // Nothing to do here, expensive initialization is in contactServer().
} }
static bool setFirstURL(Neon::URI &result,
bool &resultIsReadOnly,
const std::string &name,
const Neon::URI &uri,
bool isReadOnly)
{
if (result.empty() ||
// Overwrite read-only with read/write collection.
(resultIsReadOnly && !isReadOnly)) {
result = uri;
resultIsReadOnly = isReadOnly;
}
// Stop if read/write found.
return resultIsReadOnly;
}
void WebDAVSource::contactServer() void WebDAVSource::contactServer()
{ {
if (!m_calendar.empty() && if (!m_calendar.empty() &&
@ -623,10 +614,19 @@ void WebDAVSource::contactServer()
m_calendar = Neon::URI(); m_calendar = Neon::URI();
SE_LOG_INFO(getDisplayName(), "determine final URL based on %s", SE_LOG_INFO(getDisplayName(), "determine final URL based on %s",
m_contextSettings ? m_contextSettings->getURLDescription().c_str() : ""); m_contextSettings ? m_contextSettings->getURLDescription().c_str() : "");
findCollections(boost::bind(setFirstURL, auto setFirstURL = [this, &isReadOnly] (const std::string &name,
boost::ref(m_calendar), const Neon::URI &uri,
boost::ref(isReadOnly), bool isReadOnlyURI) {
_1, _2, _3)); if (m_calendar.empty() ||
// Overwrite read-only with read/write collection.
(isReadOnly && !isReadOnlyURI)) {
m_calendar = uri;
isReadOnly = isReadOnlyURI;
}
// Stop if read/write found.
return isReadOnly;
};
findCollections(setFirstURL);
if (m_calendar.empty()) { if (m_calendar.empty()) {
throwError(SE_HERE, "no database found"); throwError(SE_HERE, "no database found");
} }
@ -802,7 +802,7 @@ std::string WebDAVSource::lookupDNSSRV(const std::string &domain)
return url; return url;
} }
bool WebDAVSource::findCollections(const boost::function<bool (const std::string &, bool WebDAVSource::findCollections(const std::function<bool (const std::string &,
const Neon::URI &, const Neon::URI &,
bool isReadOnly)> &storeResult) bool isReadOnly)> &storeResult)
{ {
@ -814,7 +814,7 @@ bool WebDAVSource::findCollections(const boost::function<bool (const std::string
(timeoutSeconds <= 0 || (timeoutSeconds <= 0 ||
retrySeconds <= 0) ? "resending disabled" : "resending allowed"); retrySeconds <= 0) ? "resending disabled" : "resending allowed");
boost::shared_ptr<AuthProvider> authProvider = m_contextSettings->getAuthProvider(); std::shared_ptr<AuthProvider> authProvider = m_contextSettings->getAuthProvider();
std::string username = authProvider->getUsername(); std::string username = authProvider->getUsername();
// If no URL was configured, then try DNS SRV lookup. // If no URL was configured, then try DNS SRV lookup.
@ -947,9 +947,7 @@ bool WebDAVSource::findCollections(const boost::function<bool (const std::string
Candidate candidate = tried.getNextCandidate(); Candidate candidate = tried.getNextCandidate();
Props_t davProps; Props_t davProps;
Neon::Session::PropfindPropCallback_t callback = auto callback = openPropCallback(davProps);
boost::bind(&WebDAVSource::openPropCallback,
this, boost::ref(davProps), _1, _2, _3, _4);
// With Yahoo! the initial connection often failed with 50x // With Yahoo! the initial connection often failed with 50x
// errors. Retrying individual requests is error prone because at // errors. Retrying individual requests is error prone because at
@ -1054,14 +1052,11 @@ bool WebDAVSource::findCollections(const boost::function<bool (const std::string
try { try {
SE_LOG_DEBUG(NULL, "debugging: read all WebDAV properties of %s", candidate.m_uri.toURL().c_str()); SE_LOG_DEBUG(NULL, "debugging: read all WebDAV properties of %s", candidate.m_uri.toURL().c_str());
// Use OAuth2, if available. // Use OAuth2, if available.
boost::shared_ptr<AuthProvider> authProvider = m_settings->getAuthProvider(); std::shared_ptr<AuthProvider> authProvider = m_settings->getAuthProvider();
if (authProvider->methodIsSupported(AuthProvider::AUTH_METHOD_OAUTH2)) { if (authProvider->methodIsSupported(AuthProvider::AUTH_METHOD_OAUTH2)) {
m_session->forceAuthorization(Neon::Session::AUTH_HTTPS, authProvider); m_session->forceAuthorization(Neon::Session::AUTH_HTTPS, authProvider);
} }
Neon::Session::PropfindPropCallback_t callback = m_session->propfindProp(candidate.m_uri.m_path, 0, NULL, openPropCallback(davProps), Timespec());
boost::bind(&WebDAVSource::openPropCallback,
this, boost::ref(davProps), _1, _2, _3, _4);
m_session->propfindProp(candidate.m_uri.m_path, 0, NULL, callback, Timespec());
} catch (const Neon::FatalException &ex) { } catch (const Neon::FatalException &ex) {
throw; throw;
} catch (...) { } catch (...) {
@ -1551,12 +1546,12 @@ std::list<std::string> WebDAVSource::extractHREFs(const std::string &propval)
return res; return res;
} }
void WebDAVSource::openPropCallback(Props_t &davProps, Neon::Session::PropfindPropCallback_t WebDAVSource::openPropCallback(Props_t &davProps)
const Neon::URI &uri, {
return [this, &davProps] (const Neon::URI &uri,
const ne_propname *prop, const ne_propname *prop,
const char *value, const char *value,
const ne_status *status) const ne_status *status) {
{
// TODO: recognize CALDAV:calendar-timezone and use it for local time conversion of events // TODO: recognize CALDAV:calendar-timezone and use it for local time conversion of events
std::string name; std::string name;
if (prop->nspace) { if (prop->nspace) {
@ -1569,6 +1564,7 @@ void WebDAVSource::openPropCallback(Props_t &davProps,
boost::trim_if(davProps[uri.m_path][name], boost::trim_if(davProps[uri.m_path][name],
boost::is_space()); boost::is_space());
} }
};
} }
static const ne_propname getetag[] = { static const ne_propname getetag[] = {
@ -1577,22 +1573,6 @@ static const ne_propname getetag[] = {
{ NULL, NULL } { NULL, NULL }
}; };
static int FoundItem(bool &isEmpty,
const std::string &href,
const std::string &etag,
const std::string &status)
{
if (isEmpty) {
Neon::Status parsed;
// Err on the side of caution: if unsure about status, include item.
if (parsed.parse(status.c_str()) ||
parsed.klass == 2) {
isEmpty = false;
}
}
return isEmpty ? 0 : 100;
}
bool WebDAVSource::isEmpty() bool WebDAVSource::isEmpty()
{ {
contactServer(); contactServer();
@ -1605,9 +1585,7 @@ bool WebDAVSource::isEmpty()
RevisionMap_t revisions; RevisionMap_t revisions;
Timespec deadline = createDeadline(); Timespec deadline = createDeadline();
m_session->propfindURI(m_calendar.m_path, 1, getetag, m_session->propfindURI(m_calendar.m_path, 1, getetag,
boost::bind(&WebDAVSource::listAllItemsCallback, listAllItemsCallback(revisions, failed),
this, _1, _2, boost::ref(revisions),
boost::ref(failed)),
deadline); deadline);
if (failed) { if (failed) {
SE_THROW("incomplete listing of all items"); SE_THROW("incomplete listing of all items");
@ -1641,9 +1619,20 @@ bool WebDAVSource::isEmpty()
getSession()->startOperation("REPORT 'check for items'", deadline); getSession()->startOperation("REPORT 'check for items'", deadline);
while (true) { while (true) {
Neon::XMLParser parser; Neon::XMLParser parser;
parser.initAbortingReportParser(boost::bind(FoundItem, auto foundItem = [&isEmpty] (const std::string &href,
boost::ref(isEmpty), const std::string &etag,
_1, _2, _3)); const std::string &status) {
if (isEmpty) {
Neon::Status parsed;
// Err on the side of caution: if unsure about status, include item.
if (parsed.parse(status.c_str()) ||
parsed.klass == 2) {
isEmpty = false;
}
}
return isEmpty ? 0 : 100;
};
parser.initAbortingReportParser(foundItem);
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser); Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
report.addHeader("Depth", "1"); report.addHeader("Depth", "1");
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\""); report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
@ -1679,11 +1668,16 @@ void WebDAVSource::close()
m_session.reset(); m_session.reset();
} }
static bool storeCollection(SyncSource::Databases &result, WebDAVSource::Databases WebDAVSource::getDatabases()
const std::string &name,
const Neon::URI &uri,
bool isReadOnly)
{ {
Databases result;
// do a scan if some kind of credentials were set
if (m_contextSettings->getAuthProvider()->wasConfigured()) {
auto storeCollection = [&result] (const std::string &name,
const Neon::URI &uri,
bool isReadOnly) {
std::string url = uri.toURL(); std::string url = uri.toURL();
// avoid duplicates // avoid duplicates
@ -1693,20 +1687,10 @@ static bool storeCollection(SyncSource::Databases &result,
return true; return true;
} }
} }
result.push_back(SyncSource::Database(name, url, false, isReadOnly)); result.push_back(SyncSource::Database(name, url, false, isReadOnly));
return true; return true;
} };
findCollections(storeCollection);
WebDAVSource::Databases WebDAVSource::getDatabases()
{
Databases result;
// do a scan if some kind of credentials were set
if (m_contextSettings->getAuthProvider()->wasConfigured()) {
findCollections(boost::bind(storeCollection,
boost::ref(result),
_1, _2, _3));
// Move all read-only collections to the end of the array. // Move all read-only collections to the end of the array.
// They are probably not the default calendar (for example, // They are probably not the default calendar (for example,
@ -1842,11 +1826,8 @@ void WebDAVSource::checkPostSupport()
}; };
Timespec deadline = createDeadline(); Timespec deadline = createDeadline();
Props_t davProps; Props_t davProps;
Neon::Session::PropfindPropCallback_t callback =
boost::bind(&WebDAVSource::openPropCallback,
this, boost::ref(davProps), _1, _2, _3, _4);
SE_LOG_DEBUG(NULL, "check POST support of %s", m_calendar.m_path.c_str()); SE_LOG_DEBUG(NULL, "check POST support of %s", m_calendar.m_path.c_str());
m_session->propfindProp(m_calendar.m_path, 0, getaddmember, callback, deadline); m_session->propfindProp(m_calendar.m_path, 0, getaddmember, openPropCallback(davProps), deadline);
// Fatal communication problems will be reported via exceptions. // Fatal communication problems will be reported via exceptions.
// Once we get here, invalid or incomplete results can be // Once we get here, invalid or incomplete results can be
// treated as "don't have revision string". // treated as "don't have revision string".
@ -1875,11 +1856,8 @@ std::string WebDAVSource::databaseRevision()
Timespec deadline = createDeadline(); Timespec deadline = createDeadline();
Props_t davProps; Props_t davProps;
Neon::Session::PropfindPropCallback_t callback =
boost::bind(&WebDAVSource::openPropCallback,
this, boost::ref(davProps), _1, _2, _3, _4);
SE_LOG_DEBUG(NULL, "read ctag of %s", m_calendar.m_path.c_str()); SE_LOG_DEBUG(NULL, "read ctag of %s", m_calendar.m_path.c_str());
m_session->propfindProp(m_calendar.m_path, 0, getctag, callback, deadline); m_session->propfindProp(m_calendar.m_path, 0, getctag, openPropCallback(davProps), deadline);
// Fatal communication problems will be reported via exceptions. // Fatal communication problems will be reported via exceptions.
// Once we get here, invalid or incomplete results can be // Once we get here, invalid or incomplete results can be
// treated as "don't have revision string". // treated as "don't have revision string".
@ -1897,9 +1875,7 @@ void WebDAVSource::listAllItems(RevisionMap_t &revisions)
bool failed = false; bool failed = false;
Timespec deadline = createDeadline(); Timespec deadline = createDeadline();
m_session->propfindURI(m_calendar.m_path, 1, getetag, m_session->propfindURI(m_calendar.m_path, 1, getetag,
boost::bind(&WebDAVSource::listAllItemsCallback, listAllItemsCallback(revisions, failed),
this, _1, _2, boost::ref(revisions),
boost::ref(failed)),
deadline); deadline);
if (failed) { if (failed) {
SE_THROW("incomplete listing of all items"); SE_THROW("incomplete listing of all items");
@ -1938,11 +1914,9 @@ void WebDAVSource::listAllItems(RevisionMap_t &revisions)
while (true) { while (true) {
string data; string data;
Neon::XMLParser parser; Neon::XMLParser parser;
parser.initReportParser(boost::bind(&WebDAVSource::checkItem, this, parser.initReportParser(checkItem(revisions, &data));
boost::ref(revisions), parser.pushHandler(Neon::XMLParser::accept("urn:ietf:params:xml:ns:caldav", "calendar-data"),
_1, _2, &data)); Neon::XMLParser::append(data));
parser.pushHandler(boost::bind(Neon::XMLParser::accept, "urn:ietf:params:xml:ns:caldav", "calendar-data", _2, _3),
boost::bind(Neon::XMLParser::append, boost::ref(data), _2, _3));
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser); Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
report.addHeader("Depth", "1"); report.addHeader("Depth", "1");
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\""); report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
@ -2001,9 +1975,7 @@ std::string WebDAVSource::findByUID(const std::string &uid,
getSession()->startOperation("REPORT 'UID lookup'", deadline); getSession()->startOperation("REPORT 'UID lookup'", deadline);
while (true) { while (true) {
Neon::XMLParser parser; Neon::XMLParser parser;
parser.initReportParser(boost::bind(&WebDAVSource::checkItem, this, parser.initReportParser(checkItem(revisions, nullptr));
boost::ref(revisions),
_1, _2, (std::string *)0));
Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser); Neon::Request report(*getSession(), "REPORT", getCalendar().m_path, query, parser);
report.addHeader("Depth", "1"); report.addHeader("Depth", "1");
report.addHeader("Content-Type", "application/xml; charset=\"utf-8\""); report.addHeader("Content-Type", "application/xml; charset=\"utf-8\"");
@ -2030,11 +2002,11 @@ std::string WebDAVSource::findByUID(const std::string &uid,
return ""; return "";
} }
void WebDAVSource::listAllItemsCallback(const Neon::URI &uri, Neon::Session::PropfindURICallback_t WebDAVSource::listAllItemsCallback(RevisionMap_t &revisions,
const ne_prop_result_set *results,
RevisionMap_t &revisions,
bool &failed) bool &failed)
{ {
return [this, &revisions, &failed] (const Neon::URI &uri,
const ne_prop_result_set *results) {
static const ne_propname prop = { static const ne_propname prop = {
"DAV:", "getetag" "DAV:", "getetag"
}; };
@ -2067,13 +2039,15 @@ void WebDAVSource::listAllItemsCallback(const Neon::URI &uri,
uri.toURL().c_str(), uri.toURL().c_str(),
Neon::Status2String(ne_propset_status(results, &prop)).c_str()); Neon::Status2String(ne_propset_status(results, &prop)).c_str());
} }
};
} }
int WebDAVSource::checkItem(RevisionMap_t &revisions, Neon::XMLParser::VoidResponseEndCB_t WebDAVSource::checkItem(RevisionMap_t &revisions,
const std::string &href,
const std::string &etag,
std::string *data) std::string *data)
{ {
return [this, &revisions, data] (const std::string &href,
const std::string &etag,
const std::string &status) {
// Ignore responses with no data: this is not perfect (should better // Ignore responses with no data: this is not perfect (should better
// try to figure out why there is no data), but better than // try to figure out why there is no data), but better than
// failing. // failing.
@ -2081,7 +2055,7 @@ int WebDAVSource::checkItem(RevisionMap_t &revisions,
// One situation is the response for the collection itself, // One situation is the response for the collection itself,
// which comes with a 404 status and no data with Google Calendar. // which comes with a 404 status and no data with Google Calendar.
if (data && data->empty()) { if (data && data->empty()) {
return 0; return;
} }
// No need to parse, user content cannot start at start of line in // No need to parse, user content cannot start at start of line in
@ -2097,7 +2071,7 @@ int WebDAVSource::checkItem(RevisionMap_t &revisions,
if (data) { if (data) {
data->clear(); data->clear();
} }
return 0; };
} }
@ -2297,9 +2271,7 @@ TrackingSyncSource::InsertItemResult WebDAVSource::insertItem(const string &uid,
RevisionMap_t revisions; RevisionMap_t revisions;
bool failed = false; bool failed = false;
m_session->propfindURI(luid2path(new_uid), 0, getetag, m_session->propfindURI(luid2path(new_uid), 0, getetag,
boost::bind(&WebDAVSource::listAllItemsCallback, listAllItemsCallback(revisions, failed),
this, _1, _2, boost::ref(revisions),
boost::ref(failed)),
deadline); deadline);
// Turns out we get a result for our original path even in // Turns out we get a result for our original path even in
// the case of a merge, although the original path is not // the case of a merge, although the original path is not
@ -2370,9 +2342,7 @@ TrackingSyncSource::InsertItemResult WebDAVSource::insertItem(const string &uid,
bool failed = false; bool failed = false;
RevisionMap_t revisions; RevisionMap_t revisions;
m_session->propfindURI(luid2path(new_uid), 0, getetag, m_session->propfindURI(luid2path(new_uid), 0, getetag,
boost::bind(&WebDAVSource::listAllItemsCallback, listAllItemsCallback(revisions, failed),
this, _1, _2, boost::ref(revisions),
boost::ref(failed)),
deadline); deadline);
rev = revisions[new_uid]; rev = revisions[new_uid];
if (failed || rev.empty()) { if (failed || rev.empty()) {

View File

@ -38,7 +38,7 @@ class WebDAVSource : public TrackingSyncSource, private boost::noncopyable
* @param settings instance which provides necessary settings callbacks for Neon * @param settings instance which provides necessary settings callbacks for Neon
*/ */
WebDAVSource(const SyncSourceParams &params, WebDAVSource(const SyncSourceParams &params,
const boost::shared_ptr<Neon::Settings> &settings); const std::shared_ptr<Neon::Settings> &settings);
/** /**
* Utility function: replace HTML entities until none are left * Utility function: replace HTML entities until none are left
@ -69,7 +69,7 @@ class WebDAVSource : public TrackingSyncSource, private boost::noncopyable
* *
* @return true if scanning completed, false if callback requested stop * @return true if scanning completed, false if callback requested stop
*/ */
bool findCollections(const boost::function<bool (const std::string &, bool findCollections(const std::function<bool (const std::string &,
const Neon::URI &, const Neon::URI &,
bool isReadOnly)> &callback); bool isReadOnly)> &callback);
@ -138,7 +138,7 @@ class WebDAVSource : public TrackingSyncSource, private boost::noncopyable
Timespec createDeadline() const; Timespec createDeadline() const;
// access to neon session and calendar, valid between open() and close() // access to neon session and calendar, valid between open() and close()
boost::shared_ptr<Neon::Session> getSession() { return m_session; } std::shared_ptr<Neon::Session> getSession() { return m_session; }
Neon::URI &getCalendar() { return m_calendar; } Neon::URI &getCalendar() { return m_calendar; }
// access to settings owned by this instance // access to settings owned by this instance
@ -230,10 +230,10 @@ class WebDAVSource : public TrackingSyncSource, private boost::noncopyable
private: private:
/** settings to be used, never NULL, may be the same as m_contextSettings */ /** settings to be used, never NULL, may be the same as m_contextSettings */
boost::shared_ptr<Neon::Settings> m_settings; std::shared_ptr<Neon::Settings> m_settings;
/** settings constructed by us instead of caller, may be NULL */ /** settings constructed by us instead of caller, may be NULL */
boost::shared_ptr<ContextSettings> m_contextSettings; std::shared_ptr<ContextSettings> m_contextSettings;
boost::shared_ptr<Neon::Session> m_session; std::shared_ptr<Neon::Session> m_session;
/** normalized path: including backslash, URI encoded */ /** normalized path: including backslash, URI encoded */
Neon::URI m_calendar; Neon::URI m_calendar;
@ -266,38 +266,12 @@ class WebDAVSource : public TrackingSyncSource, private boost::noncopyable
/** extract all <DAV:href>value</DAV:href> values from a set, empty if none */ /** extract all <DAV:href>value</DAV:href> values from a set, empty if none */
std::list<std::string> extractHREFs(const std::string &propval); std::list<std::string> extractHREFs(const std::string &propval);
void openPropCallback(Props_t &davProps, Neon::Session::PropfindPropCallback_t openPropCallback(Props_t &davProps);
const Neon::URI &uri, Neon::Session::PropfindURICallback_t listAllItemsCallback(RevisionMap_t &revisions,
const ne_propname *prop,
const char *value,
const ne_status *status);
void listAllItemsCallback(const Neon::URI &uri,
const ne_prop_result_set *results,
RevisionMap_t &revisions,
bool &failed); bool &failed);
Neon::XMLParser::VoidResponseEndCB_t checkItem(RevisionMap_t &revisions,
int checkItem(RevisionMap_t &revisions,
const std::string &href,
const std::string &etag,
std::string *data); std::string *data);
void backupData(const boost::function<Operations::BackupData_t> &op,
const Operations::ConstBackupInfo &oldBackup,
const Operations::BackupInfo &newBackup,
BackupReport &report) {
contactServer();
op(oldBackup, newBackup, report);
}
void restoreData(const boost::function<Operations::RestoreData_t> &op,
const Operations::ConstBackupInfo &oldBackup,
bool dryrun,
SyncSourceReport &report) {
contactServer();
op(oldBackup, dryrun, report);
}
/** /**
* return true if the resource with the given properties is one * return true if the resource with the given properties is one
* of those collections which is guaranteed to not contain * of those collections which is guaranteed to not contain

View File

@ -16,7 +16,6 @@
#include <dlfcn.h> #include <dlfcn.h>
#endif #endif
#include <boost/bind.hpp>
#include <boost/tokenizer.hpp> #include <boost/tokenizer.hpp>
#include <boost/assign.hpp> #include <boost/assign.hpp>
@ -60,9 +59,9 @@ static SyncSource *createSource(const SyncSourceParams &params)
sourceType.m_format == "text/x-vcalendar") { sourceType.m_format == "text/x-vcalendar") {
#ifdef ENABLE_DAV #ifdef ENABLE_DAV
if (enabled) { if (enabled) {
boost::shared_ptr<Neon::Settings> settings; std::shared_ptr<Neon::Settings> settings;
if (sourceType.m_backend == "CalDAV") { if (sourceType.m_backend == "CalDAV") {
boost::shared_ptr<SubSyncSource> sub(new CalDAVSource(params, settings)); auto sub = std::make_shared<CalDAVSource>(params, settings);
return new MapSyncSource(params, sub); return new MapSyncSource(params, sub);
} else { } else {
return new CalDAVVxxSource(sourceType.m_backend == "CalDAVTodo" ? "VTODO" : "VJOURNAL", return new CalDAVVxxSource(sourceType.m_backend == "CalDAVTodo" ? "VTODO" : "VJOURNAL",
@ -81,7 +80,7 @@ static SyncSource *createSource(const SyncSourceParams &params)
sourceType.m_format == "text/vcard") { sourceType.m_format == "text/vcard") {
#ifdef ENABLE_DAV #ifdef ENABLE_DAV
if (enabled) { if (enabled) {
boost::shared_ptr<Neon::Settings> settings; std::shared_ptr<Neon::Settings> settings;
return new CardDAVSource(params, settings); return new CardDAVSource(params, settings);
} }
#endif #endif
@ -138,7 +137,7 @@ class WebDAVTest : public CppUnit::TestFixture {
protected: protected:
void testInstantiate() { void testInstantiate() {
boost::shared_ptr<TestingSyncSource> source; std::shared_ptr<TestingSyncSource> source;
source.reset((TestingSyncSource *)SyncSource::createTestingSource("CalDAV", "CalDAV", true)); source.reset((TestingSyncSource *)SyncSource::createTestingSource("CalDAV", "CalDAV", true));
source.reset((TestingSyncSource *)SyncSource::createTestingSource("CalDAV", "CalDAV:text/calendar", true)); source.reset((TestingSyncSource *)SyncSource::createTestingSource("CalDAV", "CalDAV:text/calendar", true));
source.reset((TestingSyncSource *)SyncSource::createTestingSource("CalDAV", "CalDAV:text/x-vcalendar", true)); source.reset((TestingSyncSource *)SyncSource::createTestingSource("CalDAV", "CalDAV:text/x-vcalendar", true));
@ -262,8 +261,11 @@ public:
m_type == "caldav" || m_type == "caldav" ||
m_type == "caldavjournal" || m_type == "caldavjournal" ||
m_type == "caldavtodo"; m_type == "caldavtodo";
config.m_createSourceA = boost::bind(&WebDAVTest::createSource, this, _2, _4); auto create = [this] (ClientTest &, const std::string &clientID, int, bool isSourceA) {
config.m_createSourceB = boost::bind(&WebDAVTest::createSource, this, _2, _4); return createSource(clientID, isSourceA);
};
config.m_createSourceA =
config.m_createSourceB = create;
ConfigProps::const_iterator it = m_props.find(m_type + "/testcases"); ConfigProps::const_iterator it = m_props.find(m_type + "/testcases");
if (it != m_props.end() || if (it != m_props.end() ||
(it = m_props.find("testcases")) != m_props.end()) { (it = m_props.find("testcases")) != m_props.end()) {
@ -293,7 +295,7 @@ public:
name.c_str(), name.c_str(),
config.c_str(), config.c_str(),
tracking.c_str()); tracking.c_str());
boost::shared_ptr<SyncConfig> context(new SyncConfig(config)); auto context = std::make_shared<SyncConfig>(config);
SyncSourceNodes nodes = context->getSyncSourceNodes(name, tracking); SyncSourceNodes nodes = context->getSyncSourceNodes(name, tracking);
// Copy properties from the Client::Sync // Copy properties from the Client::Sync
@ -301,7 +303,7 @@ public:
// that a testing source used as part of Client::Sync uses the // that a testing source used as part of Client::Sync uses the
// same settings. // same settings.
std::string peerName = std::string(server ? server : "no-such-server") + "_" + clientID; std::string peerName = std::string(server ? server : "no-such-server") + "_" + clientID;
boost::shared_ptr<SyncConfig> peer(new SyncConfig(peerName)); auto peer = std::make_shared<SyncConfig>(peerName);
// Resolve credentials. // Resolve credentials.
SimpleUserInterface ui(peer->getKeyring()); SimpleUserInterface ui(peer->getKeyring());
PasswordConfigProperty::checkPasswords(ui, PasswordConfigProperty::checkPasswords(ui,
@ -317,7 +319,7 @@ public:
if (prop->isHidden()) { if (prop->isHidden()) {
continue; continue;
} }
boost::shared_ptr<FilterConfigNode> node = peerNodes.getNode(*prop); std::shared_ptr<FilterConfigNode> node = peerNodes.getNode(*prop);
InitStateString value = prop->getProperty(*node); InitStateString value = prop->getProperty(*node);
SE_LOG_DEBUG(NULL, " %s = %s (%s)", SE_LOG_DEBUG(NULL, " %s = %s (%s)",
prop->getMainName().c_str(), prop->getMainName().c_str(),
@ -336,7 +338,7 @@ public:
SE_LOG_DEBUG(NULL, " additional property backend = %s (from CLIENT_TEST_WEBDAV)", SE_LOG_DEBUG(NULL, " additional property backend = %s (from CLIENT_TEST_WEBDAV)",
m_type.c_str()); m_type.c_str());
for (const StringPair &propval: m_props) { for (const StringPair &propval: m_props) {
boost::shared_ptr<FilterConfigNode> node = context->getNode(propval.first); std::shared_ptr<FilterConfigNode> node = context->getNode(propval.first);
if (node) { if (node) {
SE_LOG_DEBUG(NULL, " additional property %s = %s (from CLIENT_TEST_WEBDAV)", SE_LOG_DEBUG(NULL, " additional property %s = %s (from CLIENT_TEST_WEBDAV)",
propval.first.c_str(), propval.second.c_str()); propval.first.c_str(), propval.second.c_str());
@ -376,10 +378,10 @@ static class WebDAVTestSingleton : RegisterSyncSourceTest {
*/ */
class WebDAVList class WebDAVList
{ {
list< boost::shared_ptr<WebDAVTest> >m_sources; list< std::shared_ptr<WebDAVTest> >m_sources;
public: public:
void push_back(const boost::shared_ptr<WebDAVTest> &source) void push_back(const std::shared_ptr<WebDAVTest> &source)
{ {
boost::scoped_ptr<TestingSyncSource> instance(source->createSource("1", true)); boost::scoped_ptr<TestingSyncSource> instance(source->createSource("1", true));
std::string database = instance->getDatabaseID(); std::string database = instance->getDatabaseID();
@ -448,19 +450,19 @@ public:
} }
if (caldav) { if (caldav) {
boost::shared_ptr<WebDAVTest> ptr(new WebDAVTest(server, "caldav", props)); auto ptr = std::make_shared<WebDAVTest>(server, "caldav", props);
m_sources.push_back(ptr); m_sources.push_back(ptr);
} }
if (caldavtodo) { if (caldavtodo) {
boost::shared_ptr<WebDAVTest> ptr(new WebDAVTest(server, "caldavtodo", props)); auto ptr = std::make_shared<WebDAVTest>(server, "caldavtodo", props);
m_sources.push_back(ptr); m_sources.push_back(ptr);
} }
if (caldavjournal) { if (caldavjournal) {
boost::shared_ptr<WebDAVTest> ptr(new WebDAVTest(server, "caldavjournal", props)); auto ptr = std::make_shared<WebDAVTest>(server, "caldavjournal", props);
m_sources.push_back(ptr); m_sources.push_back(ptr);
} }
if (carddav) { if (carddav) {
boost::shared_ptr<WebDAVTest> ptr(new WebDAVTest(server, "carddav", props)); auto ptr = std::make_shared<WebDAVTest>(server, "carddav", props);
m_sources.push_back(ptr); m_sources.push_back(ptr);
} }
} }

View File

@ -77,7 +77,7 @@ class XMLRPCSyncSourceUnitTest : public CppUnit::TestFixture {
protected: protected:
void testInstantiate() { void testInstantiate() {
boost::shared_ptr<SyncSource> source; std::shared_ptr<SyncSource> source;
source.reset(SyncSource::createTestingSource("xmlrpc", "xmlrpc:text/vcard:3.0", true)); source.reset(SyncSource::createTestingSource("xmlrpc", "xmlrpc:text/vcard:3.0", true));
source.reset(SyncSource::createTestingSource("xmlrpc", "xmlrpc:text/plain:1.0", true)); source.reset(SyncSource::createTestingSource("xmlrpc", "xmlrpc:text/plain:1.0", true));
source.reset(SyncSource::createTestingSource("xmlrpc", "XMLRPC interface:text/x-vcard:2.1", true)); source.reset(SyncSource::createTestingSource("xmlrpc", "XMLRPC interface:text/x-vcard:2.1", true));

View File

@ -33,8 +33,6 @@
#include <syncevo/util.h> #include <syncevo/util.h>
#include <syncevo/VolatileConfigNode.h> #include <syncevo/VolatileConfigNode.h>
#include <boost/bind.hpp>
#include <syncevo/declarations.h> #include <syncevo/declarations.h>
SE_BEGIN_CXX SE_BEGIN_CXX
@ -68,7 +66,7 @@ public:
* around for each of eds_event and eds_contact/30, if they ever were used * around for each of eds_event and eds_contact/30, if they ever were used
* during testing. * during testing.
*/ */
static map<string, boost::shared_ptr<TestingSyncSource> > lockEvolution; static map<string, std::shared_ptr<TestingSyncSource> > lockEvolution;
static void CleanupSources() static void CleanupSources()
{ {
lockEvolution.clear(); lockEvolution.clear();
@ -210,8 +208,8 @@ public:
// get configuration and set obligatory fields // get configuration and set obligatory fields
Logger::instance().setLevel(Logger::DEBUG); Logger::instance().setLevel(Logger::DEBUG);
std::string root = std::string("evolution/") + server + "_" + m_clientID; std::string root = std::string("evolution/") + server + "_" + m_clientID;
boost::shared_ptr<SyncConfig> config(new SyncConfig(string(server) + "_" + m_clientID)); auto config = std::make_shared<SyncConfig>(string(server) + "_" + m_clientID);
boost::shared_ptr<SyncConfig> from = boost::shared_ptr<SyncConfig> (); std::shared_ptr<SyncConfig> from = std::shared_ptr<SyncConfig> ();
if (!config->exists()) { if (!config->exists()) {
// no configuration yet, create in different contexts because // no configuration yet, create in different contexts because
@ -234,7 +232,7 @@ public:
getSourceConfig(test, testconfig); getSourceConfig(test, testconfig);
CPPUNIT_ASSERT(!testconfig.m_type.empty()); CPPUNIT_ASSERT(!testconfig.m_type.empty());
boost::shared_ptr<SyncSourceConfig> sc = config->getSyncSourceConfig(testconfig.m_sourceName); std::shared_ptr<SyncSourceConfig> sc = config->getSyncSourceConfig(testconfig.m_sourceName);
if (!sc || !sc->exists()) { if (!sc || !sc->exists()) {
// no configuration yet // no configuration yet
config->setSourceDefaults(testconfig.m_sourceName); config->setSourceDefaults(testconfig.m_sourceName);
@ -242,7 +240,7 @@ public:
CPPUNIT_ASSERT(sc); CPPUNIT_ASSERT(sc);
sc->setURI(testconfig.m_uri); sc->setURI(testconfig.m_uri);
if(from && !testconfig.m_sourceNameServerTemplate.empty()) { if(from && !testconfig.m_sourceNameServerTemplate.empty()) {
boost::shared_ptr<SyncSourceConfig> scServerTemplate = from->getSyncSourceConfig(testconfig.m_sourceNameServerTemplate); std::shared_ptr<SyncSourceConfig> scServerTemplate = from->getSyncSourceConfig(testconfig.m_sourceNameServerTemplate);
sc->setURI(scServerTemplate->getURI()); sc->setURI(scServerTemplate->getURI());
} }
} }
@ -397,10 +395,10 @@ public:
} }
} }
virtual boost::shared_ptr<TransportAgent> createTransportAgent() virtual std::shared_ptr<TransportAgent> createTransportAgent()
{ {
boost::shared_ptr<TransportAgent>wrapper = m_options.m_transport; std::shared_ptr<TransportAgent>wrapper = m_options.m_transport;
boost::shared_ptr<TransportAgent>agent =SyncContext::createTransportAgent(); std::shared_ptr<TransportAgent>agent =SyncContext::createTransportAgent();
if (!wrapper.get()) if (!wrapper.get())
return agent; return agent;
dynamic_cast<TransportWrapper*>(wrapper.get())->setAgent(agent); dynamic_cast<TransportWrapper*>(wrapper.get())->setAgent(agent);
@ -487,7 +485,7 @@ private:
name.c_str(), name.c_str(),
config.c_str(), config.c_str(),
tracking.c_str()); tracking.c_str());
boost::shared_ptr<SyncConfig> context(new SyncConfig(config)); auto context = std::make_shared<SyncConfig>(config);
SyncSourceNodes nodes = context->getSyncSourceNodes(name, tracking); SyncSourceNodes nodes = context->getSyncSourceNodes(name, tracking);
// The user of client-test must have configured the source // The user of client-test must have configured the source
@ -495,7 +493,7 @@ private:
// Client::Sync testing. Our testing source must use the same // Client::Sync testing. Our testing source must use the same
// properties, but different change tracking. // properties, but different change tracking.
std::string peerName = server ? (std::string(server) + "_" + m_clientID) : "@default"; std::string peerName = server ? (std::string(server) + "_" + m_clientID) : "@default";
boost::shared_ptr<SyncConfig> peer(new SyncConfig(peerName)); auto peer = std::make_shared<SyncConfig>(peerName);
SyncSourceNodes peerNodes = peer->getSyncSourceNodes(name); SyncSourceNodes peerNodes = peer->getSyncSourceNodes(name);
SE_LOG_DEBUG(NULL, "overriding testing source %s properties with the ones from config %s = %s", SE_LOG_DEBUG(NULL, "overriding testing source %s properties with the ones from config %s = %s",
name.c_str(), name.c_str(),
@ -505,7 +503,7 @@ private:
if (prop->isHidden()) { if (prop->isHidden()) {
continue; continue;
} }
boost::shared_ptr<FilterConfigNode> node = peerNodes.getNode(*prop); std::shared_ptr<FilterConfigNode> node = peerNodes.getNode(*prop);
InitStateString value = prop->getProperty(*node); InitStateString value = prop->getProperty(*node);
SE_LOG_DEBUG(NULL, " %s = %s (%s)", SE_LOG_DEBUG(NULL, " %s = %s (%s)",
prop->getMainName().c_str(), prop->getMainName().c_str(),
@ -518,7 +516,7 @@ private:
// Same as in init() above: set values if still empty, but don't // Same as in init() above: set values if still empty, but don't
// overwrite anything. // overwrite anything.
boost::shared_ptr<FilterConfigNode> props = nodes.getProperties(); std::shared_ptr<FilterConfigNode> props = nodes.getProperties();
std::string value; std::string value;
if (!props->getProperty("database", value)) { if (!props->getProperty("database", value)) {
props->setProperty("database", database); props->setProperty("database", database);

View File

@ -43,17 +43,16 @@ static void updatePresence(Timespec *t, bool present)
Timespec(); Timespec();
} }
boost::shared_ptr<AutoSyncManager> AutoSyncManager::createAutoSyncManager(Server &server) std::shared_ptr<AutoSyncManager> AutoSyncManager::createAutoSyncManager(Server &server)
{ {
boost::shared_ptr<AutoSyncManager> result(new AutoSyncManager(server)); auto result = make_weak_shared::make<AutoSyncManager>(server);
result->m_me = result;
result->init(); result->init();
// update cached information about a config each time it changes // update cached information about a config each time it changes
server.m_configChangedSignal.connect(Server::ConfigChangedSignal_t::slot_type(&AutoSyncManager::initConfig, result.get(), _1).track(result)); server.m_configChangedSignal.connect(Server::ConfigChangedSignal_t::slot_type(&AutoSyncManager::initConfig, result.get(), _1).track_foreign(result));
// monitor running sessions // monitor running sessions
server.m_newSyncSessionSignal.connect(Server::NewSyncSessionSignal_t::slot_type(&AutoSyncManager::sessionStarted, result.get(), _1).track(result)); server.m_newSyncSessionSignal.connect(Server::NewSyncSessionSignal_t::slot_type(&AutoSyncManager::sessionStarted, result.get(), _1).track_foreign(result));
// Keep track of the time when a transport became online. As with // Keep track of the time when a transport became online. As with
// time of last sync, we are pessimistic here and assume that the // time of last sync, we are pessimistic here and assume that the
@ -65,13 +64,13 @@ boost::shared_ptr<AutoSyncManager> AutoSyncManager::createAutoSyncManager(Server
} }
p.m_btPresenceSignal.connect(PresenceStatus::PresenceSignal_t::slot_type(updatePresence, p.m_btPresenceSignal.connect(PresenceStatus::PresenceSignal_t::slot_type(updatePresence,
&result->m_btStartTime, &result->m_btStartTime,
_1).track(result)); _1).track_foreign(result));
if (p.getHttpPresence()) { if (p.getHttpPresence()) {
result->m_httpStartTime = now; result->m_httpStartTime = now;
} }
p.m_httpPresenceSignal.connect(PresenceStatus::PresenceSignal_t::slot_type(updatePresence, p.m_httpPresenceSignal.connect(PresenceStatus::PresenceSignal_t::slot_type(updatePresence,
&result->m_httpStartTime, &result->m_httpStartTime,
_1).track(result)); _1).track_foreign(result));
return result; return result;
} }
@ -122,7 +121,7 @@ void AutoSyncManager::initConfig(const std::string &configName)
// Create anew or update, directly in map. Never remove // Create anew or update, directly in map. Never remove
// old entries, because we want to keep the m_lastSyncTime // old entries, because we want to keep the m_lastSyncTime
// in cases where configs get removed and recreated. // in cases where configs get removed and recreated.
boost::shared_ptr<AutoSyncTask> &task = m_peerMap[configName]; std::shared_ptr<AutoSyncTask> &task = m_peerMap[configName];
if (!task) { if (!task) {
task.reset(new AutoSyncTask(configName)); task.reset(new AutoSyncTask(configName));
// We should check past sessions here. Instead we assume // We should check past sessions here. Instead we assume
@ -250,7 +249,7 @@ void AutoSyncManager::schedule(const std::string &reason)
Timespec now = Timespec::monotonic(); Timespec now = Timespec::monotonic();
for (const auto &entry: m_peerMap) { for (const auto &entry: m_peerMap) {
const std::string &configName = entry.first; const std::string &configName = entry.first;
const boost::shared_ptr<AutoSyncTask> &task = entry.second; const std::shared_ptr<AutoSyncTask> &task = entry.second;
if (task->m_interval <= 0 || // not enabled if (task->m_interval <= 0 || // not enabled
task->m_permanentFailure) { // don't try again task->m_permanentFailure) { // don't try again
@ -269,9 +268,7 @@ void AutoSyncManager::schedule(const std::string &reason)
configName.c_str(), configName.c_str(),
seconds); seconds);
task->m_intervalTimeout.runOnce(seconds, task->m_intervalTimeout.runOnce(seconds,
boost::bind(&AutoSyncManager::schedule, [this, configName] () { schedule(configName + " interval timer"); });
this,
configName + " interval timer"));
continue; continue;
} }
@ -319,7 +316,7 @@ void AutoSyncManager::schedule(const std::string &reason)
// check again when it becomes present // check again when it becomes present
signal->connect(PresenceStatus::PresenceSignal_t::slot_type(&AutoSyncManager::schedule, signal->connect(PresenceStatus::PresenceSignal_t::slot_type(&AutoSyncManager::schedule,
this, this,
"presence change").track(m_me)); "presence change").track_foreign(shared_from_this()));
SE_LOG_DEBUG(NULL, "auto sync: %s: transport for %s not present", SE_LOG_DEBUG(NULL, "auto sync: %s: transport for %s not present",
configName.c_str(), configName.c_str(),
urlinfo.second.c_str()); urlinfo.second.c_str());
@ -331,9 +328,7 @@ void AutoSyncManager::schedule(const std::string &reason)
urlinfo.second.c_str(), urlinfo.second.c_str(),
seconds); seconds);
timeout->runOnce(seconds, timeout->runOnce(seconds,
boost::bind(&AutoSyncManager::schedule, [this, configName] () { schedule(configName + " transport timer"); });
this,
configName + " transport timer"));
} }
} }
@ -347,25 +342,21 @@ void AutoSyncManager::schedule(const std::string &reason)
m_server.delaySessionDestruction(m_session); m_server.delaySessionDestruction(m_session);
task->m_syncSuccessStart = false; task->m_syncSuccessStart = false;
m_session = Session::createSession(m_server, m_session = make_weak_shared::make<Session>(m_server,
task->m_remoteDeviceId, task->m_remoteDeviceId,
configName, configName,
m_server.getNextSession()); m_server.getNextSession());
// Temporarily set sync URL to the one which we picked above // Temporarily set sync URL to the one which we picked above
// once the session is active (setConfig() not allowed earlier). // once the session is active (setConfig() not allowed earlier).
// Run sync as soon as it is active.
m_session->m_sessionActiveSignal.connect([session=m_session.get(), readyURL] () {
ReadOperations::Config_t config; ReadOperations::Config_t config;
config[""]["syncURL"] = readyURL; config[""]["syncURL"] = readyURL;
m_session->m_sessionActiveSignal.connect(boost::bind(&Session::setConfig,
m_session.get(),
true, true,
config));
// Run sync as soon as it is active. session->setConfig(true, true, config);
m_session->m_sessionActiveSignal.connect(boost::bind(&Session::sync, session->sync("", {});
m_session.get(), });
"",
SessionCommon::SourceModes_t()));
// Now run it. // Now run it.
m_session->activate(); m_session->activate();
@ -386,10 +377,10 @@ void AutoSyncManager::connectIdle()
m_idleConnection = m_idleConnection =
m_server.m_idleSignal.connect(Server::IdleSignal_t::slot_type(&AutoSyncManager::schedule, m_server.m_idleSignal.connect(Server::IdleSignal_t::slot_type(&AutoSyncManager::schedule,
this, this,
"server is idle").track(m_me)); "server is idle").track_foreign(shared_from_this()));
} }
void AutoSyncManager::sessionStarted(const boost::shared_ptr<Session> &session) void AutoSyncManager::sessionStarted(const std::shared_ptr<Session> &session)
{ {
// Do we have a task for this config? // Do we have a task for this config?
std::string configName = session->getConfigName(); std::string configName = session->getConfigName();
@ -400,18 +391,20 @@ void AutoSyncManager::sessionStarted(const boost::shared_ptr<Session> &session)
return; return;
} }
boost::shared_ptr<AutoSyncManager> me = m_me.lock(); std::shared_ptr<AutoSyncManager> me;
if (!me) { try {
me = shared_from_this();
} catch (...) {
SE_LOG_DEBUG(NULL, "auto sync: already destructing, ignore new sync %s", SE_LOG_DEBUG(NULL, "auto sync: already destructing, ignore new sync %s",
configName.c_str()); configName.c_str());
return; return;
} }
const boost::shared_ptr<AutoSyncTask> &task = it->second; const std::shared_ptr<AutoSyncTask> &task = it->second;
task->m_lastSyncTime = Timespec::monotonic(); task->m_lastSyncTime = Timespec::monotonic();
// track permanent failure // track permanent failure
session->m_doneSignal.connect(Session::DoneSignal_t::slot_type(&AutoSyncManager::anySyncDone, this, task.get(), _1).track(task).track(me)); session->m_doneSignal.connect(Session::DoneSignal_t::slot_type(&AutoSyncManager::anySyncDone, this, task.get(), _1).track_foreign(task).track_foreign(me));
if (m_session == session) { if (m_session == session) {
// Only for our own auto sync session: notify user once session starts successful. // Only for our own auto sync session: notify user once session starts successful.
@ -419,18 +412,18 @@ void AutoSyncManager::sessionStarted(const boost::shared_ptr<Session> &session)
// In the (unlikely) case that the AutoSyncTask gets deleted, the // In the (unlikely) case that the AutoSyncTask gets deleted, the
// slot won't get involved, thus skipping user notifications. // slot won't get involved, thus skipping user notifications.
// Also protects against manager destructing before session. // Also protects against manager destructing before session.
session->m_syncSuccessStartSignal.connect(Session::SyncSuccessStartSignal_t::slot_type(&AutoSyncManager::autoSyncSuccessStart, this, task.get()).track(task).track(me)); session->m_syncSuccessStartSignal.connect(Session::SyncSuccessStartSignal_t::slot_type(&AutoSyncManager::autoSyncSuccessStart, this, task.get()).track_foreign(task).track_foreign(me));
// Notify user once session ends, with or without failure. // Notify user once session ends, with or without failure.
// Same instance tracking as for sync success start. // Same instance tracking as for sync success start.
session->m_doneSignal.connect(Session::DoneSignal_t::slot_type(&AutoSyncManager::autoSyncDone, this, task.get(), _1).track(task).track(me)); session->m_doneSignal.connect(Session::DoneSignal_t::slot_type(&AutoSyncManager::autoSyncDone, this, task.get(), _1).track_foreign(task).track_foreign(me));
} }
} }
bool AutoSyncManager::preventTerm() bool AutoSyncManager::preventTerm()
{ {
for (const auto &entry: m_peerMap) { for (const auto &entry: m_peerMap) {
const boost::shared_ptr<AutoSyncTask> &task = entry.second; const std::shared_ptr<AutoSyncTask> &task = entry.second;
if (task->m_interval > 0 && if (task->m_interval > 0 &&
!task->m_permanentFailure && !task->m_permanentFailure &&
!task->m_urls.empty()) { !task->m_urls.empty()) {

View File

@ -21,8 +21,6 @@
#define AUTO_SYNC_MANAGER_H #define AUTO_SYNC_MANAGER_H
#include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/predicate.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/signals2.hpp> #include <boost/signals2.hpp>
#include <syncevo/SyncML.h> #include <syncevo/SyncML.h>
@ -55,16 +53,15 @@ class Session;
* Syncs triggered by local or remote changes will be added * Syncs triggered by local or remote changes will be added
* later. * later.
*/ */
class AutoSyncManager class AutoSyncManager : public enable_weak_from_this<AutoSyncManager>, private boost::noncopyable
{ {
Server &m_server; Server &m_server;
boost::weak_ptr<AutoSyncManager> m_me;
/** true if we currently hold a ref for AutoTerm */ /** true if we currently hold a ref for AutoTerm */
bool m_autoTermLocked; bool m_autoTermLocked;
/** currently running auto sync session */ /** currently running auto sync session */
boost::shared_ptr<Session> m_session; std::shared_ptr<Session> m_session;
/** connects m_server.m_idleSignal with schedule() */ /** connects m_server.m_idleSignal with schedule() */
boost::signals2::connection m_idleConnection; boost::signals2::connection m_idleConnection;
@ -173,11 +170,11 @@ class AutoSyncManager
* enabled (to track when and if they ran) and deleted configs * enabled (to track when and if they ran) and deleted configs
* (because they might get recreated). * (because they might get recreated).
*/ */
typedef std::map<std::string, boost::shared_ptr<AutoSyncTask> > PeerMap; typedef std::map<std::string, std::shared_ptr<AutoSyncTask> > PeerMap;
PeerMap m_peerMap; PeerMap m_peerMap;
/** used to send notifications */ /** used to send notifications */
boost::shared_ptr<NotificationManagerBase> m_notificationManager; std::shared_ptr<NotificationManagerBase> m_notificationManager;
/** /**
* It reads all peers which are enabled to do auto sync and store them in * It reads all peers which are enabled to do auto sync and store them in
@ -197,7 +194,7 @@ class AutoSyncManager
* Watch further progress (if auto sync session), * Watch further progress (if auto sync session),
* record start time (in all cases). * record start time (in all cases).
*/ */
void sessionStarted(const boost::shared_ptr<Session> &session); void sessionStarted(const std::shared_ptr<Session> &session);
/** Show "sync started" notification. */ /** Show "sync started" notification. */
void autoSyncSuccessStart(AutoSyncTask *task); void autoSyncSuccessStart(AutoSyncTask *task);
@ -211,7 +208,7 @@ class AutoSyncManager
AutoSyncManager(Server &server); AutoSyncManager(Server &server);
public: public:
static boost::shared_ptr<AutoSyncManager> createAutoSyncManager(Server &server); static std::shared_ptr<AutoSyncManager> createAutoSyncManager(Server &server);
/** /**
* prevent dbus server automatic termination when it has * prevent dbus server automatic termination when it has

View File

@ -48,8 +48,8 @@ BluezManager::BluezManager(Server &server) :
if (getConnection()) { if (getConnection()) {
m_done = false; m_done = false;
DBusClientCall<DBusObject_t> getAdapter(*this, "DefaultAdapter"); DBusClientCall<DBusObject_t> getAdapter(*this, "DefaultAdapter");
getAdapter.start(boost::bind(&BluezManager::defaultAdapterCb, this, _1, _2 )); getAdapter.start([this] (const DBusObject_t &adapter, const string &error) { defaultAdapterCb(adapter, error); });
m_adapterChanged.activate(boost::bind(&BluezManager::defaultAdapterChanged, this, _1)); m_adapterChanged.activate([this] (const DBusObject_t &adapter) { defaultAdapterChanged(adapter); });
} else { } else {
m_done = true; m_done = true;
} }
@ -85,9 +85,9 @@ BluezManager::BluezAdapter::BluezAdapter(BluezManager &manager, const string &pa
m_deviceRemoved(*this, "DeviceRemoved"), m_deviceAdded(*this, "DeviceCreated") m_deviceRemoved(*this, "DeviceRemoved"), m_deviceAdded(*this, "DeviceCreated")
{ {
DBusClientCall<std::vector<DBusObject_t> > listDevices(*this, "ListDevices"); DBusClientCall<std::vector<DBusObject_t> > listDevices(*this, "ListDevices");
listDevices.start(boost::bind(&BluezAdapter::listDevicesCb, this, _1, _2)); listDevices.start([this] (const std::vector<DBusObject_t> &devices, const string &error) { listDevicesCb(devices, error); });
m_deviceRemoved.activate(boost::bind(&BluezAdapter::deviceRemoved, this, _1)); m_deviceRemoved.activate([this] (const DBusObject_t &object) { deviceRemoved(object); });
m_deviceAdded.activate(boost::bind(&BluezAdapter::deviceCreated, this, _1)); m_deviceAdded.activate([this] (const DBusObject_t &object) { deviceCreated(object); });
} }
void BluezManager::BluezAdapter::listDevicesCb(const std::vector<DBusObject_t> &devices, const string &error) void BluezManager::BluezAdapter::listDevicesCb(const std::vector<DBusObject_t> &devices, const string &error)
@ -99,7 +99,7 @@ void BluezManager::BluezAdapter::listDevicesCb(const std::vector<DBusObject_t> &
} }
m_devNo = devices.size(); m_devNo = devices.size();
for (const auto &device: devices) { for (const auto &device: devices) {
boost::shared_ptr<BluezDevice> bluezDevice(new BluezDevice(*this, device)); auto bluezDevice = std::make_shared<BluezDevice>(*this, device);
m_devices.push_back(bluezDevice); m_devices.push_back(bluezDevice);
} }
checkDone(); checkDone();
@ -108,7 +108,7 @@ void BluezManager::BluezAdapter::listDevicesCb(const std::vector<DBusObject_t> &
void BluezManager::BluezAdapter::deviceRemoved(const DBusObject_t &object) void BluezManager::BluezAdapter::deviceRemoved(const DBusObject_t &object)
{ {
string address; string address;
std::vector<boost::shared_ptr<BluezDevice> >::iterator devIt; std::vector<std::shared_ptr<BluezDevice> >::iterator devIt;
for(devIt = m_devices.begin(); devIt != m_devices.end(); ++devIt) { for(devIt = m_devices.begin(); devIt != m_devices.end(); ++devIt) {
if(boost::equals((*devIt)->getPath(), object)) { if(boost::equals((*devIt)->getPath(), object)) {
address = (*devIt)->m_mac; address = (*devIt)->m_mac;
@ -126,7 +126,7 @@ void BluezManager::BluezAdapter::deviceRemoved(const DBusObject_t &object)
void BluezManager::BluezAdapter::deviceCreated(const DBusObject_t &object) void BluezManager::BluezAdapter::deviceCreated(const DBusObject_t &object)
{ {
m_devNo++; m_devNo++;
boost::shared_ptr<BluezDevice> bluezDevice(new BluezDevice(*this, object)); auto bluezDevice = std::make_shared<BluezDevice>(*this, object);
m_devices.push_back(bluezDevice); m_devices.push_back(bluezDevice);
} }
@ -136,9 +136,10 @@ BluezManager::BluezDevice::BluezDevice (BluezAdapter &adapter, const string &pat
m_adapter(adapter), m_reply(false), m_propertyChanged(*this, "PropertyChanged") m_adapter(adapter), m_reply(false), m_propertyChanged(*this, "PropertyChanged")
{ {
DBusClientCall<PropDict> getProperties(*this, "GetProperties"); DBusClientCall<PropDict> getProperties(*this, "GetProperties");
getProperties.start(boost::bind(&BluezDevice::getPropertiesCb, this, _1, _2)); getProperties.start([this] (const PropDict &props, const string &error) { getPropertiesCb(props, error); });
m_propertyChanged.activate(boost::bind(&BluezDevice::propertyChanged, this, _1, _2)); m_propertyChanged.activate([this] (const string &name,
const boost::variant<vector<string>, string> &prop) { propertyChanged(name, prop); });
} }
/** /**
@ -174,8 +175,8 @@ void BluezManager::BluezDevice::checkSyncService(const std::vector<std::string>
DBusClientCall<ServiceDict> discoverServices(*this, DBusClientCall<ServiceDict> discoverServices(*this,
"DiscoverServices"); "DiscoverServices");
static const std::string PNP_INFO_UUID("0x1200"); static const std::string PNP_INFO_UUID("0x1200");
discoverServices.start(boost::bind(&BluezDevice::discoverServicesCb, discoverServices.start([this] (const ServiceDict &serviceDict,
this, _1, _2), const string &error) { discoverServicesCb(serviceDict, error); },
PNP_INFO_UUID); PNP_INFO_UUID);
} }
} }
@ -239,9 +240,9 @@ bool BluezManager::getPnpInfoNamesFromValues(const std::string &vendorValue, std
if (!m_watchedFile) { if (!m_watchedFile) {
m_lookupTable.bt_key_file = g_key_file_new(); m_lookupTable.bt_key_file = g_key_file_new();
string filePath(SyncEvolutionDataDir() + "/bluetooth_products.ini"); string filePath(SyncEvolutionDataDir() + "/bluetooth_products.ini");
m_watchedFile = boost::shared_ptr<SyncEvo::GLibNotify>( m_watchedFile = std::shared_ptr<SyncEvo::GLibNotify>(
new GLibNotify(filePath.c_str(), new GLibNotify(filePath.c_str(),
boost::bind(&BluezManager::loadBluetoothDeviceLookupTable, this))); [this] (GFile *, GFile *, GFileMonitorEvent) { loadBluetoothDeviceLookupTable(); }));
} }
loadBluetoothDeviceLookupTable(); loadBluetoothDeviceLookupTable();
// Make sure the file was actually loaded // Make sure the file was actually loaded
@ -311,7 +312,7 @@ void BluezManager::BluezDevice::discoverServicesCb(const ServiceDict &serviceDic
SyncConfig::DeviceDescription devDesc; SyncConfig::DeviceDescription devDesc;
if (server.getDevice(m_mac, devDesc)) { if (server.getDevice(m_mac, devDesc)) {
devDesc.m_pnpInformation = devDesc.m_pnpInformation =
boost::shared_ptr<SyncConfig::PnpInformation>( std::shared_ptr<SyncConfig::PnpInformation>(
new SyncConfig::PnpInformation(vendorName, productName)); new SyncConfig::PnpInformation(vendorName, productName));
server.updateDevice(m_mac, devDesc); server.updateDevice(m_mac, devDesc);
} }

View File

@ -79,7 +79,7 @@ private:
} }
} }
std::vector<boost::shared_ptr<BluezDevice> >& getDevices() { return m_devices; } std::vector<std::shared_ptr<BluezDevice> >& getDevices() { return m_devices; }
private: private:
/** callback of 'ListDevices' signal. Used to get all available devices of the adapter */ /** callback of 'ListDevices' signal. Used to get all available devices of the adapter */
@ -98,7 +98,7 @@ private:
int m_devReplies; int m_devReplies;
/** all available devices */ /** all available devices */
std::vector<boost::shared_ptr<BluezDevice> > m_devices; std::vector<std::shared_ptr<BluezDevice> > m_devices;
/** represents 'DeviceRemoved' signal of org.bluez.Adapter*/ /** represents 'DeviceRemoved' signal of org.bluez.Adapter*/
GDBusCXX::SignalWatch<GDBusCXX::DBusObject_t> m_deviceRemoved; GDBusCXX::SignalWatch<GDBusCXX::DBusObject_t> m_deviceRemoved;
@ -167,7 +167,7 @@ private:
Server &m_server; Server &m_server;
GDBusCXX::DBusConnectionPtr m_bluezConn; GDBusCXX::DBusConnectionPtr m_bluezConn;
boost::shared_ptr<BluezAdapter> m_adapter; std::shared_ptr<BluezAdapter> m_adapter;
// Holds the bluetooth lookup table and whether it was successfully loaded. // Holds the bluetooth lookup table and whether it was successfully loaded.
class lookupTable : private boost::noncopyable { class lookupTable : private boost::noncopyable {
@ -179,7 +179,7 @@ private:
bool isLoaded; bool isLoaded;
} m_lookupTable; } m_lookupTable;
boost::shared_ptr<GLibNotify> m_watchedFile; std::shared_ptr<GLibNotify> m_watchedFile;
void loadBluetoothDeviceLookupTable(); void loadBluetoothDeviceLookupTable();
bool getPnpInfoNamesFromValues(const std::string &vendorValue, std::string &vendorName, bool getPnpInfoNamesFromValues(const std::string &vendorValue, std::string &vendorName,
const std::string &productValue, std::string &productName); const std::string &productValue, std::string &productName);

View File

@ -45,7 +45,7 @@ void Client::detach(Resource *resource)
if (it->unique()) { if (it->unique()) {
// client was the last owner, and thus the session must be idle (otherwise // client was the last owner, and thus the session must be idle (otherwise
// it would also be referenced as active session) // it would also be referenced as active session)
boost::shared_ptr<Session> session = boost::dynamic_pointer_cast<Session>(*it); std::shared_ptr<Session> session = std::dynamic_pointer_cast<Session>(*it);
if (session) { if (session) {
// give clients a chance to query the session // give clients a chance to query the session
m_server.delaySessionDestruction(session); m_server.delaySessionDestruction(session);

View File

@ -40,7 +40,7 @@ class Client
{ {
Server &m_server; Server &m_server;
typedef std::list< boost::shared_ptr<Resource> > Resources_t; typedef std::list< std::shared_ptr<Resource> > Resources_t;
Resources_t m_resources; Resources_t m_resources;
/** counts how often a client has called Attach() without Detach() */ /** counts how often a client has called Attach() without Detach() */
@ -74,7 +74,7 @@ public:
* multiple times, which means that detach() also has to be called * multiple times, which means that detach() also has to be called
* the same number of times to finally detach the resource. * the same number of times to finally detach the resource.
*/ */
void attach(boost::shared_ptr<Resource> resource) void attach(std::shared_ptr<Resource> resource)
{ {
m_resources.push_back(resource); m_resources.push_back(resource);
} }
@ -87,7 +87,7 @@ public:
*/ */
void detach(Resource *resource); void detach(Resource *resource);
void detach(boost::shared_ptr<Resource> resource) void detach(std::shared_ptr<Resource> resource)
{ {
detach(resource.get()); detach(resource.get());
} }
@ -106,7 +106,7 @@ public:
} }
} }
} }
void detachAll(boost::shared_ptr<Resource> resource) void detachAll(std::shared_ptr<Resource> resource)
{ {
detachAll(resource.get()); detachAll(resource.get());
} }
@ -115,7 +115,7 @@ public:
* return corresponding smart pointer for a certain resource, * return corresponding smart pointer for a certain resource,
* empty pointer if not found * empty pointer if not found
*/ */
boost::shared_ptr<Resource> findResource(Resource *resource) std::shared_ptr<Resource> findResource(Resource *resource)
{ {
for (Resources_t::iterator it = m_resources.begin(); for (Resources_t::iterator it = m_resources.begin();
it != m_resources.end(); it != m_resources.end();
@ -125,7 +125,7 @@ public:
return *it; return *it;
} }
} }
return boost::shared_ptr<Resource>(); return std::shared_ptr<Resource>();
} }
}; };

View File

@ -26,6 +26,8 @@
#include "exceptions.h" #include "exceptions.h"
#include "session-helper.h" #include "session-helper.h"
#include <memory>
SE_BEGIN_CXX SE_BEGIN_CXX
/** /**
@ -58,9 +60,9 @@ public:
bool run() bool run()
{ {
//temporarily set environment variables and restore them after running //temporarily set environment variables and restore them after running
list<boost::shared_ptr<ScopedEnvChange> > changes; list<std::shared_ptr<ScopedEnvChange> > changes;
for (const StringPair &var: m_envVars) { for (const StringPair &var: m_envVars) {
changes.push_back(boost::shared_ptr<ScopedEnvChange>(new ScopedEnvChange(var.first, var.second))); changes.push_back(std::make_unique<ScopedEnvChange>(var.first, var.second));
} }
bool success = Cmdline::run(); bool success = Cmdline::run();

View File

@ -54,7 +54,7 @@ void Connection::failed(const std::string &reason)
// //
// But don't delete ourselves while some code of the Connection still // But don't delete ourselves while some code of the Connection still
// runs. Instead let server do that as part of its event loop. // runs. Instead let server do that as part of its event loop.
boost::shared_ptr<Connection> c = m_me.lock(); auto c = weak_from_this().lock();
if (c) { if (c) {
m_server.delayDeletion(c); m_server.delayDeletion(c);
m_server.detach(this); m_server.detach(this);
@ -114,13 +114,13 @@ void Connection::process(const Caller_t &caller,
message_type.c_str(), message_type.c_str(),
SessionCommon::ConnectionStateToString(m_state).c_str()); SessionCommon::ConnectionStateToString(m_state).c_str());
boost::shared_ptr<Client> client(m_server.findClient(caller)); std::shared_ptr<Client> client(m_server.findClient(caller));
if (!client) { if (!client) {
SE_THROW("unknown client"); SE_THROW("unknown client");
} }
boost::shared_ptr<Connection> myself = std::shared_ptr<Connection> myself =
boost::static_pointer_cast<Connection, Resource>(client->findResource(this)); std::static_pointer_cast<Connection, Resource>(client->findResource(this));
if (!myself) { if (!myself) {
SE_THROW("client does not own connection"); SE_THROW("client does not own connection");
} }
@ -295,7 +295,7 @@ void Connection::process(const Caller_t &caller,
// run session as client or server // run session as client or server
m_state = SessionCommon::PROCESSING; m_state = SessionCommon::PROCESSING;
m_session = Session::createSession(m_server, m_session = make_weak_shared::make<Session>(m_server,
peerDeviceID, peerDeviceID,
config, config,
m_sessionID); m_sessionID);
@ -323,7 +323,7 @@ void Connection::process(const Caller_t &caller,
// it might go away before killing completes and/or // it might go away before killing completes and/or
// fails - need to use shared pointer tracking). // fails - need to use shared pointer tracking).
// //
// boost::shared_ptr<Connection> c = m_me.lock(); // std::shared_ptr<Connection> c = m_me.lock();
// if (!c) { // if (!c) {
// SE_THROW("internal error: Connection::process() cannot lock its own instance"); // SE_THROW("internal error: Connection::process() cannot lock its own instance");
// } // }
@ -423,7 +423,7 @@ void Connection::close(const Caller_t &caller,
error.c_str(), error.c_str(),
SessionCommon::ConnectionStateToString(m_state).c_str()); SessionCommon::ConnectionStateToString(m_state).c_str());
boost::shared_ptr<Client> client(m_server.findClient(caller)); std::shared_ptr<Client> client(m_server.findClient(caller));
if (!client) { if (!client) {
SE_THROW("unknown client"); SE_THROW("unknown client");
} }
@ -431,7 +431,7 @@ void Connection::close(const Caller_t &caller,
// Remove reference to us from client, will destruct *this* // Remove reference to us from client, will destruct *this*
// instance. To let us finish our work safely, keep a reference // instance. To let us finish our work safely, keep a reference
// that the server will unref when everything is idle again. // that the server will unref when everything is idle again.
boost::shared_ptr<Connection> c = m_me.lock(); auto c = weak_from_this().lock();
if (!c) { if (!c) {
SE_THROW("connection already destructing"); SE_THROW("connection already destructing");
} }
@ -495,7 +495,7 @@ Connection::Connection(Server &server,
DBusObjectHelper(conn, DBusObjectHelper(conn,
std::string("/org/syncevolution/Connection/") + sessionID, std::string("/org/syncevolution/Connection/") + sessionID,
"org.syncevolution.Connection", "org.syncevolution.Connection",
boost::bind(&Server::autoTermCallback, &server)), [serverPtr=&server] () { serverPtr->autoTermCallback(); }),
m_server(server), m_server(server),
m_peer(peer), m_peer(peer),
m_mustAuthenticate(must_authenticate), m_mustAuthenticate(must_authenticate),
@ -517,17 +517,6 @@ Connection::Connection(Server &server,
m_sessionID.c_str()); m_sessionID.c_str());
} }
boost::shared_ptr<Connection> Connection::createConnection(Server &server,
const DBusConnectionPtr &conn,
const std::string &sessionID,
const StringMap &peer,
bool must_authenticate)
{
boost::shared_ptr<Connection> c(new Connection(server, conn, sessionID, peer, must_authenticate));
c->m_me = c;
return c;
}
Connection::~Connection() Connection::~Connection()
{ {
SE_LOG_DEBUG(NULL, "Connection %s: done with '%s'%s%s%s (old state %s)", SE_LOG_DEBUG(NULL, "Connection %s: done with '%s'%s%s%s (old state %s)",
@ -593,7 +582,7 @@ void Connection::ready()
//uint32_t contentType = m_SANContent->m_contentType[sync]; //uint32_t contentType = m_SANContent->m_contentType[sync];
bool found = false; bool found = false;
for (const std::string &source: sources) { for (const std::string &source: sources) {
boost::shared_ptr<const PersistentSyncSourceConfig> sourceConfig(context.getSyncSourceConfig(source)); std::shared_ptr<const PersistentSyncSourceConfig> sourceConfig(context.getSyncSourceConfig(source));
// prefix match because the local // prefix match because the local
// configuration might contain // configuration might contain
// additional parameters (like date // additional parameters (like date
@ -630,20 +619,16 @@ void Connection::ready()
void Connection::activateTimeout() void Connection::activateTimeout()
{ {
if (m_timeoutSeconds >= 0) { if (m_timeoutSeconds >= 0) {
m_timeout.runOnce(m_timeoutSeconds, auto timeoutCb = [this] () {
boost::bind(&Connection::timeoutCb, SE_LOG_DEBUG(NULL, "Connection %s: timed out after %ds (state %s)",
this)); m_sessionID.c_str(), m_timeoutSeconds,
SessionCommon::ConnectionStateToString(m_state).c_str());
failed(StringPrintf("timed out after %ds", m_timeoutSeconds));
};
m_timeout.runOnce(m_timeoutSeconds, timeoutCb);
} else { } else {
m_timeout.deactivate(); m_timeout.deactivate();
} }
} }
void Connection::timeoutCb()
{
SE_LOG_DEBUG(NULL, "Connection %s: timed out after %ds (state %s)",
m_sessionID.c_str(), m_timeoutSeconds,
SessionCommon::ConnectionStateToString(m_state).c_str());
failed(StringPrintf("timed out after %ds", m_timeoutSeconds));
}
SE_END_CXX SE_END_CXX

View File

@ -47,11 +47,10 @@ class Session;
* this means the Session has to abort, unless reconnecting is * this means the Session has to abort, unless reconnecting is
* supported. * supported.
*/ */
class Connection : public GDBusCXX::DBusObjectHelper, public Resource class Connection : public GDBusCXX::DBusObjectHelper, public Resource, public enable_weak_from_this<Connection>
{ {
private: private:
Server &m_server; Server &m_server;
boost::weak_ptr<Connection> m_me;
StringMap m_peer; StringMap m_peer;
bool m_mustAuthenticate; bool m_mustAuthenticate;
SessionCommon::ConnectionState m_state; SessionCommon::ConnectionState m_state;
@ -63,7 +62,7 @@ class Connection : public GDBusCXX::DBusObjectHelper, public Resource
SessionCommon::SourceModes_t m_sourceModes; SessionCommon::SourceModes_t m_sourceModes;
const std::string m_sessionID; const std::string m_sessionID;
boost::shared_ptr<Session> m_session; std::shared_ptr<Session> m_session;
/** /**
* Defines the timeout in seconds. -1 and thus "no timeout" by default. * Defines the timeout in seconds. -1 and thus "no timeout" by default.
@ -75,7 +74,6 @@ class Connection : public GDBusCXX::DBusObjectHelper, public Resource
int m_timeoutSeconds; int m_timeoutSeconds;
Timeout m_timeout; Timeout m_timeout;
void activateTimeout(); void activateTimeout();
void timeoutCb();
/** /**
* buffer for received data, waiting here for engine to ask * buffer for received data, waiting here for engine to ask
@ -94,7 +92,7 @@ class Connection : public GDBusCXX::DBusObjectHelper, public Resource
* The content of a parsed SAN package to be processed via * The content of a parsed SAN package to be processed via
* connection.ready * connection.ready
*/ */
boost::shared_ptr <SANContent> m_SANContent; std::shared_ptr <SANContent> m_SANContent;
std::string m_peerBtAddr; std::string m_peerBtAddr;
/** /**
@ -137,13 +135,8 @@ class Connection : public GDBusCXX::DBusObjectHelper, public Resource
public: public:
const std::string m_description; const std::string m_description;
// Construct via make_weak_shared.
static boost::shared_ptr<Connection> createConnection(Server &server, friend make_weak_shared;
const GDBusCXX::DBusConnectionPtr &conn,
const std::string &session_num,
const StringMap &peer,
bool must_authenticate);
~Connection(); ~Connection();
/** session requested by us is ready to run a sync */ /** session requested by us is ready to run a sync */

View File

@ -38,14 +38,8 @@ ConnmanClient::ConnmanClient(Server &server):
if (getConnection()) { if (getConnection()) {
typedef std::map <std::string, boost::variant<std::string> > PropDict; typedef std::map <std::string, boost::variant<std::string> > PropDict;
GDBusCXX::DBusClientCall<PropDict> getProp(*this,"GetProperties"); GDBusCXX::DBusClientCall<PropDict> getProp(*this,"GetProperties");
getProp.start(boost::bind(&ConnmanClient::getPropCb, this, _1, _2));
m_propertyChanged.activate(boost::bind(&ConnmanClient::propertyChanged, this, _1, _2));
}else{
SE_LOG_DEBUG(NULL, "DBus connection setup for connman failed");
}
}
void ConnmanClient::getPropCb (const std::map <std::string, auto getPropCb = [this] (const std::map <std::string,
boost::variant<std::string> >& props, const string &error) { boost::variant<std::string> >& props, const string &error) {
if (!error.empty()) { if (!error.empty()) {
m_available = false; m_available = false;
@ -74,16 +68,21 @@ void ConnmanClient::getPropCb (const std::map <std::string,
//now delivering the signals //now delivering the signals
m_server.getPresenceStatus().updatePresenceStatus (httpPresence, PresenceStatus::HTTP_TRANSPORT); m_server.getPresenceStatus().updatePresenceStatus (httpPresence, PresenceStatus::HTTP_TRANSPORT);
} };
getProp.start(getPropCb);
void ConnmanClient::propertyChanged(const std::string &name, auto propertyChanged = [this] (const std::string &name,
const boost::variant<std::vector<std::string>, std::string> &prop) const boost::variant<std::vector<std::string>, std::string> &prop) {
{
if (name == "State") { if (name == "State") {
std::string state = boost::get<std::string>(prop); std::string state = boost::get<std::string>(prop);
m_server.getPresenceStatus().updatePresenceStatus(state == "online", m_server.getPresenceStatus().updatePresenceStatus(state == "online",
PresenceStatus::HTTP_TRANSPORT); PresenceStatus::HTTP_TRANSPORT);
} }
};
m_propertyChanged.activate(propertyChanged);
}else{
SE_LOG_DEBUG(NULL, "DBus connection setup for connman failed");
}
} }
SE_END_CXX SE_END_CXX

View File

@ -39,11 +39,6 @@ class ConnmanClient : public GDBusCXX::DBusRemoteObject
public: public:
ConnmanClient (Server &server); ConnmanClient (Server &server);
void propertyChanged(const std::string &name,
const boost::variant<std::vector<std::string>, std::string> &prop);
void getPropCb(const std::map <std::string, boost::variant<std::string> >& props, const std::string &error);
/** TRUE if watching ConnMan status */ /** TRUE if watching ConnMan status */
bool isAvailable() { return m_available; } bool isAvailable() { return m_available; }

View File

@ -25,7 +25,7 @@
SE_BEGIN_CXX SE_BEGIN_CXX
uint32_t dbusErrorCallback(const boost::shared_ptr<GDBusCXX::ResultBase> &result) uint32_t dbusErrorCallback(const std::shared_ptr<GDBusCXX::ResultBase> &result)
{ {
try { try {
// If there is no pending exception, the process will abort // If there is no pending exception, the process will abort
@ -52,9 +52,9 @@ uint32_t dbusErrorCallback(const boost::shared_ptr<GDBusCXX::ResultBase> &result
return 500; return 500;
} }
ErrorCb_t createDBusErrorCb(const boost::shared_ptr<GDBusCXX::ResultBase> &result) ErrorCb_t createDBusErrorCb(const std::shared_ptr<GDBusCXX::ResultBase> &result)
{ {
return boost::bind(dbusErrorCallback, result); return [result] () { dbusErrorCallback(result); };
} }
SE_END_CXX SE_END_CXX

View File

@ -20,16 +20,14 @@
#ifndef INCL_DBUS_CALLBACKS #ifndef INCL_DBUS_CALLBACKS
#define INCL_DBUS_CALLBACKS #define INCL_DBUS_CALLBACKS
#include <boost/shared_ptr.hpp> #include <memory>
#include <boost/function.hpp> #include <functional>
#include <boost/bind.hpp>
#include <syncevo/declarations.h>
#include <stdint.h> #include <stdint.h>
#include <gdbus-cxx-bridge.h> #include <gdbus-cxx-bridge.h>
#include <syncevo/declarations.h>
SE_BEGIN_CXX SE_BEGIN_CXX
/** /**
@ -62,7 +60,7 @@ SE_BEGIN_CXX
* It is the responsibility of the caller to ensure that any objects * It is the responsibility of the caller to ensure that any objects
* bound to the callback are still around when the callback gets * bound to the callback are still around when the callback gets
* invoked. One simple way of doing that is via BoostHelper.h and * invoked. One simple way of doing that is via BoostHelper.h and
* binding to a boost::weak_ptr that tracks the instance to which * binding to a std::weak_ptr that tracks the instance to which
* the callback belongs. * the callback belongs.
* *
* The recommended naming is to use the "Async" suffix in the function * The recommended naming is to use the "Async" suffix in the function
@ -76,16 +74,16 @@ SE_BEGIN_CXX
* relaying them to the D-Bus client. Example: * relaying them to the D-Bus client. Example:
* *
* void runOperationAsync(RunOperation op, * void runOperationAsync(RunOperation op,
* const boost::shared_ptr< GDBusCXX::Result<> > &dbusResult, * const std::shared_ptr< GDBusCXX::Result<> > &dbusResult,
* const SuccessCb_t &helperReady) * const SuccessCb_t &helperReady)
* ... * ...
* useHelperAsync(SimpleResult(helperReady, * useHelperAsync(SimpleResult(helperReady,
* boost::bind(&Session::failureCb, this))); * [this] () { failureCb(); } ));
* *
* Session::failureCb() in this example then does some work on its own * Session::failureCb() in this example then does some work on its own
* and finally calls dbusErrorCallback(dbusResult). * and finally calls dbusErrorCallback(dbusResult).
*/ */
typedef boost::function<void ()> ErrorCb_t; typedef std::function<void ()> ErrorCb_t;
/** /**
* Because callbacks always come in pairs, the following * Because callbacks always come in pairs, the following
@ -95,17 +93,17 @@ typedef boost::function<void ()> ErrorCb_t;
*/ */
template <class P> class Result template <class P> class Result
{ {
boost::function<P> m_onSuccess; std::function<P> m_onSuccess;
ErrorCb_t m_onError; ErrorCb_t m_onError;
public: public:
Result(const boost::function<P> &onSuccess, Result(const std::function<P> &onSuccess,
const ErrorCb_t &onError) : const ErrorCb_t &onError) :
m_onSuccess(onSuccess), m_onSuccess(onSuccess),
m_onError(onError) m_onError(onError)
{} {}
boost::function<P> getOnSuccess() const { return m_onSuccess; } std::function<P> getOnSuccess() const { return m_onSuccess; }
ErrorCb_t getOnError() const { return m_onError; } ErrorCb_t getOnError() const { return m_onError; }
void done() const { if (m_onSuccess) m_onSuccess(); } void done() const { if (m_onSuccess) m_onSuccess(); }
@ -121,7 +119,7 @@ template <class P> class Result
* and failure callbacks. Determines type automatically based on type * and failure callbacks. Determines type automatically based on type
* of success callback. * of success callback.
*/ */
template <class P> Result<P> makeCb(const boost::function<P> &onSuccess, template <class P> Result<P> makeCb(const std::function<P> &onSuccess,
const ErrorCb_t &onFailure) const ErrorCb_t &onFailure)
{ {
return Result<P>(onSuccess, onFailure); return Result<P>(onSuccess, onFailure);
@ -134,51 +132,25 @@ template <class P> Result<P> makeCb(const boost::function<P> &onSuccess,
* @param result failed() is called here * @param result failed() is called here
* @return status code (see SyncML.h) * @return status code (see SyncML.h)
*/ */
uint32_t dbusErrorCallback(const boost::shared_ptr<GDBusCXX::ResultBase> &result); uint32_t dbusErrorCallback(const std::shared_ptr<GDBusCXX::ResultBase> &result);
/** /**
* Creates an error callback which can be used to return a pending * Creates an error callback which can be used to return a pending
* exception as a D-Bus error. Template call which is parameterized * exception as a D-Bus error. Template call which is parameterized
* with the GDBusCXX::Result* class that takes the error. * with the GDBusCXX::Result* class that takes the error.
*/ */
ErrorCb_t createDBusErrorCb(const boost::shared_ptr<GDBusCXX::ResultBase> &result); ErrorCb_t createDBusErrorCb(const std::shared_ptr<GDBusCXX::ResultBase> &result);
/**
* Creates a result object which passes back results and turns
* exceptions into dbus_error instances with the given interface
* name.
* TODO: interface name
*/
template<class R1> Result<void (const R1 &)> createDBusCb(const boost::shared_ptr< GDBusCXX::Result<R1> > &result)
{
return Result<void (const R1 &)>(boost::bind(&GDBusCXX::Result<R1>::done,
result,
_1),
createDBusErrorCb(result));
}
/**
* Creates a result object which passes back zero results and turns
* exceptions into dbus_error instances with the given interface name.
* TODO: interface name
*/
static inline Result<void ()> createDBusCb(const boost::shared_ptr< GDBusCXX::Result<> > &result)
{
return Result<void ()>(boost::bind(&GDBusCXX::Result<>::done,
result),
createDBusErrorCb(result));
}
/** /**
* a generic "operation successful" callback with no parameters * a generic "operation successful" callback with no parameters
*/ */
typedef boost::function<void ()> SuccessCb_t; typedef std::function<void ()> SuccessCb_t;
/** /**
* A generic "operation completed/failed" result pair (no parameters * A generic "operation completed/failed" result pair (no parameters
* for completion). Same as Result<void ()>, but because it doesn't * for completion). Same as Result<void ()>, but because it doesn't
* have overloaded done() template methods the done method can be used * have overloaded done() template methods the done method can be used
* in boost::bind(). * in std::bind().
*/ */
class SimpleResult { class SimpleResult {
public: public:

View File

@ -49,11 +49,15 @@ DBusSync::DBusSync(const SessionCommon::SyncParams &params,
// Watch status of parent and our own process and cancel // Watch status of parent and our own process and cancel
// any pending password request if parent or we go down. // any pending password request if parent or we go down.
boost::shared_ptr<ForkExecChild> forkexec = m_helper.getForkExecChild(); auto forkexec = m_helper.getForkExecChild();
if (forkexec) { if (forkexec) {
m_parentWatch = forkexec->m_onQuit.connect(boost::bind(&DBusSync::passwordResponse, this, true, false, "")); m_parentWatch = forkexec->m_onQuit.connect([this] () { passwordResponse(true, false, ""); });
} }
m_suspendFlagsWatch = SuspendFlags::getSuspendFlags().m_stateChanged.connect(boost::bind(&DBusSync::suspendFlagsChanged, this, _1)); m_suspendFlagsWatch = SuspendFlags::getSuspendFlags().m_stateChanged.connect([this] (SuspendFlags &flags) {
if (flags.getState() != SuspendFlags::NORMAL) {
passwordResponse(true, false, "");
}
});
// Apply temporary config filters. The parameters of this function // Apply temporary config filters. The parameters of this function
// override the source filters, if set. // override the source filters, if set.
@ -97,7 +101,7 @@ DBusSync::DBusSync(const SessionCommon::SyncParams &params,
} }
// Forward the SourceSyncedSignal via D-Bus. // Forward the SourceSyncedSignal via D-Bus.
m_sourceSyncedSignal.connect(boost::bind(m_helper.emitSourceSynced, _1, _2)); m_sourceSyncedSignal.connect([this] (const std::string &name, const SyncSourceReport &source) { m_helper.emitSourceSynced(name, source); });
} }
DBusSync::~DBusSync() DBusSync::~DBusSync()
@ -106,21 +110,21 @@ DBusSync::~DBusSync()
m_suspendFlagsWatch.disconnect(); m_suspendFlagsWatch.disconnect();
} }
boost::shared_ptr<TransportAgent> DBusSync::createTransportAgent() std::shared_ptr<TransportAgent> DBusSync::createTransportAgent()
{ {
if (m_params.m_serverAlerted || m_params.m_serverMode) { if (m_params.m_serverAlerted || m_params.m_serverMode) {
// Use the D-Bus Connection to send and receive messages. // Use the D-Bus Connection to send and receive messages.
boost::shared_ptr<DBusTransportAgent> agent(new DBusTransportAgent(m_helper)); auto agent = std::make_shared<DBusTransportAgent>(m_helper);
// Hook up agent with D-Bus in the helper. The agent may go // Hook up agent with D-Bus in the helper. The agent may go
// away at any time, so use instance tracking. // away at any time, so use instance tracking.
m_helper.m_messageSignal.connect(SessionHelper::MessageSignal_t::slot_type(&DBusTransportAgent::storeMessage, m_helper.m_messageSignal.connect(SessionHelper::MessageSignal_t::slot_type(&DBusTransportAgent::storeMessage,
agent.get(), agent.get(),
_1, _1,
_2).track(agent)); _2).track_foreign(agent));
m_helper.m_connectionStateSignal.connect(SessionHelper::ConnectionStateSignal_t::slot_type(&DBusTransportAgent::storeState, m_helper.m_connectionStateSignal.connect(SessionHelper::ConnectionStateSignal_t::slot_type(&DBusTransportAgent::storeState,
agent.get(), agent.get(),
_1).track(agent)); _1).track_foreign(agent));
if (m_params.m_serverAlerted) { if (m_params.m_serverAlerted) {
// A SAN message was sent to us, need to reply. // A SAN message was sent to us, need to reply.
@ -132,11 +136,11 @@ boost::shared_ptr<TransportAgent> DBusSync::createTransportAgent()
m_params.m_initialMessageType); m_params.m_initialMessageType);
} }
return agent; return std::static_pointer_cast<TransportAgent>(agent);
} else { } else {
// no connection, use HTTP via libsoup/GMainLoop // no connection, use HTTP via libsoup/GMainLoop
GMainLoop *loop = m_helper.getLoop(); GMainLoop *loop = m_helper.getLoop();
boost::shared_ptr<TransportAgent> agent = SyncContext::createTransportAgent(loop); auto agent = SyncContext::createTransportAgent(loop);
return agent; return agent;
} }
} }
@ -205,10 +209,8 @@ string DBusSync::askPassword(const string &passwordName,
std::string error; std::string error;
askPasswordAsync(passwordName, descr, key, askPasswordAsync(passwordName, descr, key,
boost::bind(static_cast<std::string & (std::string::*)(const std::string &)>(&std::string::assign), [&password] (const std::string &passwordArg) { password = passwordArg; },
&password, _1), [&error] () { Exception::handle(error, HANDLE_EXCEPTION_NO_ERROR); });
boost::bind(static_cast<SyncMLStatus (*)(std::string &, HandleExceptionFlags)>(&Exception::handle),
boost::ref(error), HANDLE_EXCEPTION_NO_ERROR));
// We know that askPasswordAsync() is done when it cleared the // We know that askPasswordAsync() is done when it cleared the
// callback functors. // callback functors.
while (m_passwordSuccess) { while (m_passwordSuccess) {
@ -224,12 +226,12 @@ string DBusSync::askPassword(const string &passwordName,
void DBusSync::askPasswordAsync(const std::string &passwordName, void DBusSync::askPasswordAsync(const std::string &passwordName,
const std::string &descr, const std::string &descr,
const ConfigPasswordKey &key, const ConfigPasswordKey &key,
const boost::function<void (const std::string &)> &success, const std::function<void (const std::string &)> &success,
const boost::function<void ()> &failureException) const std::function<void ()> &failureException)
{ {
// cannot handle more than one password request at a time // cannot handle more than one password request at a time
m_passwordSuccess.clear(); m_passwordSuccess = {};
m_passwordFailure.clear(); m_passwordFailure = {};
m_passwordDescr = descr; m_passwordDescr = descr;
InitStateString password; InitStateString password;
@ -260,16 +262,16 @@ void DBusSync::askPasswordAsync(const std::string &passwordName,
STATUS_PASSWORD_TIMEOUT); STATUS_PASSWORD_TIMEOUT);
} }
} catch (...) { } catch (...) {
m_passwordSuccess.clear(); m_passwordSuccess = {};
m_passwordFailure.clear(); m_passwordFailure = {};
failureException(); failureException();
} }
} }
void DBusSync::passwordResponse(bool timedOut, bool aborted, const std::string &password) void DBusSync::passwordResponse(bool timedOut, bool aborted, const std::string &password)
{ {
boost::function<void (const std::string &)> success; std::function<void (const std::string &)> success;
boost::function<void ()> failureException; std::function<void ()> failureException;
std::swap(success, m_passwordSuccess); std::swap(success, m_passwordSuccess);
std::swap(failureException, m_passwordFailure); std::swap(failureException, m_passwordFailure);
@ -300,13 +302,6 @@ void DBusSync::passwordResponse(bool timedOut, bool aborted, const std::string &
} }
} }
void DBusSync::suspendFlagsChanged(SuspendFlags &flags)
{
if (flags.getState() != SuspendFlags::NORMAL) {
passwordResponse(true, false, "");
}
}
bool DBusSync::savePassword(const std::string &passwordName, bool DBusSync::savePassword(const std::string &passwordName,
const std::string &password, const std::string &password,
const ConfigPasswordKey &key) const ConfigPasswordKey &key)

View File

@ -48,14 +48,12 @@ class DBusSync : public SyncContext, private UserInterface
SessionHelper &m_helper; SessionHelper &m_helper;
SessionCommon::SyncParams m_params; SessionCommon::SyncParams m_params;
bool m_waiting; bool m_waiting;
boost::function<void (const std::string &)> m_passwordSuccess; std::function<void (const std::string &)> m_passwordSuccess;
boost::function<void ()> m_passwordFailure; std::function<void ()> m_passwordFailure;
std::string m_passwordDescr; std::string m_passwordDescr;
boost::signals2::connection m_parentWatch; boost::signals2::connection m_parentWatch;
boost::signals2::connection m_suspendFlagsWatch; boost::signals2::connection m_suspendFlagsWatch;
void suspendFlagsChanged(SuspendFlags &flags);
public: public:
DBusSync(const SessionCommon::SyncParams &params, DBusSync(const SessionCommon::SyncParams &params,
SessionHelper &helper); SessionHelper &helper);
@ -65,7 +63,7 @@ public:
void passwordResponse(bool timedOut, bool aborted, const std::string &password); void passwordResponse(bool timedOut, bool aborted, const std::string &password);
protected: protected:
virtual boost::shared_ptr<TransportAgent> createTransportAgent(); virtual std::shared_ptr<TransportAgent> createTransportAgent();
virtual void displaySyncProgress(sysync::TProgressEventEnum type, virtual void displaySyncProgress(sysync::TProgressEventEnum type,
int32_t extra1, int32_t extra2, int32_t extra3); int32_t extra1, int32_t extra2, int32_t extra3);
virtual bool displaySourceProgress(SyncSource &source, virtual bool displaySourceProgress(SyncSource &source,
@ -79,8 +77,8 @@ protected:
virtual void askPasswordAsync(const std::string &passwordName, virtual void askPasswordAsync(const std::string &passwordName,
const std::string &descr, const std::string &descr,
const ConfigPasswordKey &key, const ConfigPasswordKey &key,
const boost::function<void (const std::string &)> &success, const std::function<void (const std::string &)> &success,
const boost::function<void ()> &failureException); const std::function<void ()> &failureException);
virtual bool savePassword(const std::string &passwordName, virtual bool savePassword(const std::string &passwordName,
const std::string &password, const std::string &password,

View File

@ -23,7 +23,6 @@
#include <syncevo/TransportAgent.h> #include <syncevo/TransportAgent.h>
#include <syncevo/SmartPtr.h> #include <syncevo/SmartPtr.h>
#include <syncevo/SynthesisEngine.h> #include <syncevo/SynthesisEngine.h>
#include <boost/weak_ptr.hpp>
#include <gdbus-cxx-bridge.h> #include <gdbus-cxx-bridge.h>

View File

@ -39,7 +39,7 @@ InfoReq::InfoReq(Server &server,
m_param(parameters) m_param(parameters)
{ {
m_server.emitInfoReq(*this); m_server.emitInfoReq(*this);
m_timeout.runOnce(m_timeoutSeconds, boost::bind(boost::ref(m_timeoutSignal))); m_timeout.runOnce(m_timeoutSeconds, [this] () { m_timeoutSignal(); });
m_param.clear(); m_param.clear();
} }
@ -88,7 +88,7 @@ void InfoReq::setResponse(const Caller_t &caller, const string &state, const Inf
m_infoState = IN_WAIT; m_infoState = IN_WAIT;
m_server.emitInfoReq(*this); m_server.emitInfoReq(*this);
//reset the timer, used to check timeout //reset the timer, used to check timeout
m_timeout.runOnce(m_timeoutSeconds, boost::bind(boost::ref(m_timeoutSignal))); m_timeout.runOnce(m_timeoutSeconds, [this] () { m_timeoutSignal(); });
} else if ((m_infoState == IN_WAIT || m_infoState == IN_REQ) && state == "response") { } else if ((m_infoState == IN_WAIT || m_infoState == IN_REQ) && state == "response") {
m_response = response; m_response = response;
m_handler = caller; m_handler = caller;

View File

@ -74,20 +74,24 @@ LocaledListener::LocaledListener():
m_propertiesGet(*this, PROPERTIES_GET) m_propertiesGet(*this, PROPERTIES_GET)
{ {
if (getConnection()) { if (getConnection()) {
m_propertiesChanged.activate(boost::bind(&LocaledListener::onPropertiesChange, this, _1, _2, _3)); auto change = [this] (const std::string &interface,
const Properties &properties,
const Invalidated &invalidated) {
onPropertiesChange(interface, properties, invalidated);
};
m_propertiesChanged.activate(change);
} else { } else {
SE_LOG_DEBUG(NULL, "localed: not activating, no connection"); SE_LOG_DEBUG(NULL, "localed: not activating, no connection");
} }
}; };
boost::shared_ptr<LocaledListener> LocaledListener::create() std::shared_ptr<LocaledListener> LocaledListener::create()
{ {
static boost::weak_ptr<LocaledListener> singleton; static std::weak_ptr<LocaledListener> singleton;
boost::shared_ptr<LocaledListener> self = singleton.lock(); std::shared_ptr<LocaledListener> self = singleton.lock();
if (!self) { if (!self) {
self.reset(new LocaledListener()); self.reset(new LocaledListener());
self->m_self = self;
singleton = self; singleton = self;
} }
return self; return self;
@ -98,7 +102,12 @@ void LocaledListener::onPropertiesChange(const std::string &interface,
const Invalidated &invalidated) const Invalidated &invalidated)
{ {
if (interface == LOCALED_INTERFACE) { if (interface == LOCALED_INTERFACE) {
boost::function<void (const LocaleEnv &env)> result(boost::bind(&LocaledListener::emitLocaleEnv, m_self, _1)); auto result = [self=weak_from_this()] (const LocaleEnv &env) {
auto lock = self.lock();
if (lock) {
lock->emitLocaleEnv(env);
}
};
for (const auto &entry: properties) { for (const auto &entry: properties) {
if (entry.first == LOCALED_LOCALE_PROPERTY) { if (entry.first == LOCALED_LOCALE_PROPERTY) {
const LocaleEnv *locale = boost::get<LocaleEnv>(&entry.second); const LocaleEnv *locale = boost::get<LocaleEnv>(&entry.second);
@ -115,9 +124,12 @@ void LocaledListener::onPropertiesChange(const std::string &interface,
invalidated.end(), invalidated.end(),
LOCALED_LOCALE_PROPERTY) != invalidated.end()) { LOCALED_LOCALE_PROPERTY) != invalidated.end()) {
SE_LOG_DEBUG(NULL, "localed: Locale changed, need to get new value"); SE_LOG_DEBUG(NULL, "localed: Locale changed, need to get new value");
m_propertiesGet.start(boost::bind(&LocaledListener::processLocaleProperty, m_self, m_propertiesGet.start([self=weak_from_this(), result] (const LocaleVariant &variant, const std::string &error) {
_1, _2, false, auto lock = self.lock();
result), if (lock) {
lock->processLocaleProperty(variant, error, false, result);
}
},
std::string(LOCALED_INTERFACE), std::string(LOCALED_INTERFACE),
std::string(LOCALED_LOCALE_PROPERTY)); std::string(LOCALED_LOCALE_PROPERTY));
} }
@ -158,11 +170,16 @@ void LocaledListener::emitLocaleEnv(const LocaleEnv &env)
m_localeValues(env); m_localeValues(env);
} }
void LocaledListener::check(const boost::function<void (const LocaleEnv &env)> &result) void LocaledListener::check(const std::function<void (const LocaleEnv &env)> &result)
{ {
if (getConnection()) { if (getConnection()) {
SE_LOG_DEBUG(NULL, "localed: get current Locale property"); SE_LOG_DEBUG(NULL, "localed: get current Locale property");
m_propertiesGet.start(boost::bind(&LocaledListener::processLocaleProperty, m_self, _1, _2, true, result), m_propertiesGet.start([self=weak_from_this(), result] (const LocaleVariant &variant, const std::string &error) {
auto lock = self.lock();
if (lock) {
lock->processLocaleProperty(variant, error, true, result);
}
},
std::string(LOCALED_INTERFACE), std::string(LOCALED_INTERFACE),
std::string(LOCALED_LOCALE_PROPERTY)); std::string(LOCALED_LOCALE_PROPERTY));
} else { } else {
@ -176,8 +193,8 @@ void LocaledListener::setLocale(const LocaleEnv &locale)
for (const char *name: LOCALED_ENV_VARS) { for (const char *name: LOCALED_ENV_VARS) {
const char *value = getenv(name); const char *value = getenv(name);
std::string assignment = StringPrintf("%s=", name); std::string assignment = StringPrintf("%s=", name);
LocaleEnv::const_iterator instance = std::find_if(locale.begin(), locale.end(), auto instance = std::find_if(locale.begin(), locale.end(),
boost::bind(boost::starts_with<std::string, std::string>, _1, name)); [&name] (const std::string &l) { return boost::starts_with(l, name); });
const char *newvalue = instance != locale.end() ? instance->c_str() + assignment.size() : NULL; const char *newvalue = instance != locale.end() ? instance->c_str() + assignment.size() : NULL;
if ((value && newvalue && strcmp(value, newvalue)) || if ((value && newvalue && strcmp(value, newvalue)) ||
(!value && newvalue)) { (!value && newvalue)) {

View File

@ -22,8 +22,10 @@
#include <gdbus-cxx-bridge.h> #include <gdbus-cxx-bridge.h>
#include <boost/signals2.hpp> #include <boost/signals2.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp> #include <memory>
#include <syncevo/util.h>
#include <syncevo/declarations.h> #include <syncevo/declarations.h>
SE_BEGIN_CXX SE_BEGIN_CXX
@ -31,14 +33,14 @@ SE_BEGIN_CXX
/** /**
* The D-Bus binding for http://www.freedesktop.org/wiki/Software/systemd/localed/ * The D-Bus binding for http://www.freedesktop.org/wiki/Software/systemd/localed/
*/ */
class LocaledListener : public GDBusCXX::DBusRemoteObject class LocaledListener : public GDBusCXX::DBusRemoteObject, public enable_weak_from_this<LocaledListener>
{ {
public: public:
/** /**
* Singleton - at most one instance of LocaledListener will exist. * Singleton - at most one instance of LocaledListener will exist.
* It lives as long as one of the create() callers keeps the reference. * It lives as long as one of the create() callers keeps the reference.
*/ */
static boost::shared_ptr<LocaledListener> create(); static std::shared_ptr<LocaledListener> create();
/** /**
* array of var=value, for example LANG, LC_NUMERIC, etc. * array of var=value, for example LANG, LC_NUMERIC, etc.
@ -56,7 +58,7 @@ class LocaledListener : public GDBusCXX::DBusRemoteObject
* either with the current settings from localed or, if * either with the current settings from localed or, if
* retrieving those fails, with the current environment. * retrieving those fails, with the current environment.
*/ */
void check(const boost::function<void (const LocaleEnv &env)> &result); void check(const std::function<void (const LocaleEnv &env)> &result);
/** /**
* Updates current environment to match the one in the parameter. * Updates current environment to match the one in the parameter.
@ -81,7 +83,6 @@ class LocaledListener : public GDBusCXX::DBusRemoteObject
LocaleChangedSignal m_localeChanged; LocaleChangedSignal m_localeChanged;
private: private:
boost::weak_ptr<LocaledListener> m_self;
typedef boost::variant<LocaleEnv> LocaleVariant; typedef boost::variant<LocaleEnv> LocaleVariant;
typedef std::map<std::string, LocaleVariant> Properties; typedef std::map<std::string, LocaleVariant> Properties;
typedef std::vector<std::string> Invalidated; typedef std::vector<std::string> Invalidated;
@ -92,7 +93,7 @@ class LocaledListener : public GDBusCXX::DBusRemoteObject
void onPropertiesChange(const std::string &interface, void onPropertiesChange(const std::string &interface,
const Properties &properties, const Properties &properties,
const Invalidated &invalidated); const Invalidated &invalidated);
typedef boost::function<void (const LocaleEnv &env)> ProcessLocalePropCB_t; typedef std::function<void (const LocaleEnv &env)> ProcessLocalePropCB_t;
void processLocaleProperty(const LocaleVariant &locale, void processLocaleProperty(const LocaleVariant &locale,
const std::string &error, const std::string &error,
bool mustCall, bool mustCall,

View File

@ -79,7 +79,7 @@ static Logger::Level checkLogLevel(const char *option, int logLevel)
int main(int argc, char **argv, char **envp) int main(int argc, char **argv, char **envp)
{ {
// remember environment for restart // remember environment for restart
boost::shared_ptr<Restart> restart; std::shared_ptr<Restart> restart;
restart.reset(new Restart(argv, envp)); restart.reset(new Restart(argv, envp));
// Internationalization for auto sync messages. // Internationalization for auto sync messages.
@ -212,7 +212,7 @@ int main(int argc, char **argv, char **envp)
// process name for developers in this process, and not in // process name for developers in this process, and not in
// syncevo-dbus-helper. // syncevo-dbus-helper.
Logger::setProcessName("syncevo-dbus-server"); Logger::setProcessName("syncevo-dbus-server");
boost::shared_ptr<SuspendFlags::Guard> guard = SuspendFlags::getSuspendFlags().activate(); std::shared_ptr<SuspendFlags::Guard> guard = SuspendFlags::getSuspendFlags().activate();
DBusErrorCXX err; DBusErrorCXX err;
DBusConnectionPtr conn = dbus_get_bus_connection("SESSION", DBusConnectionPtr conn = dbus_get_bus_connection("SESSION",
@ -225,12 +225,12 @@ int main(int argc, char **argv, char **envp)
// make this object the main owner of the connection // make this object the main owner of the connection
boost::scoped_ptr<DBusObject> obj(new DBusObject(conn, "foo", "bar", true)); boost::scoped_ptr<DBusObject> obj(new DBusObject(conn, "foo", "bar", true));
boost::shared_ptr<SyncEvo::Server> server(new SyncEvo::Server(loop, restart, conn, duration)); auto server = std::make_shared<SyncEvo::Server>(loop, restart, conn, duration);
server->setDBusLogLevel(levelDBus); server->setDBusLogLevel(levelDBus);
server->activate(); server->activate();
#ifdef ENABLE_DBUS_PIM #ifdef ENABLE_DBUS_PIM
boost::shared_ptr<GDBusCXX::DBusObjectHelper> manager(SyncEvo::CreateContactManager(server, startPIM)); std::shared_ptr<GDBusCXX::DBusObjectHelper> manager(SyncEvo::CreateContactManager(server, startPIM));
#endif #endif
if (gdbus) { if (gdbus) {

View File

@ -42,9 +42,7 @@ NetworkManagerClient::NetworkManagerClient(Server &server) :
{ {
if (getConnection()) { if (getConnection()) {
m_properties.get(); m_properties.get();
m_stateChanged.activate(boost::bind( m_stateChanged.activate([this] (uint32_t uiState) { stateChanged(uiState); });
&NetworkManagerClient::stateChanged,
this, _1));
} else { } else {
SE_LOG_DEBUG(NULL, SE_LOG_DEBUG(NULL,
"DBus connection setup for NetworkManager failed"); "DBus connection setup for NetworkManager failed");
@ -86,14 +84,8 @@ NetworkManagerClient::NetworkManagerProperties::NetworkManagerProperties(
void NetworkManagerClient::NetworkManagerProperties::get() void NetworkManagerClient::NetworkManagerProperties::get()
{ {
GDBusCXX::DBusClientCall<boost::variant<uint32_t, std::string> > get(*this, "Get"); GDBusCXX::DBusClientCall<boost::variant<uint32_t, std::string> > get(*this, "Get");
get.start(boost::bind(&NetworkManagerProperties::getCallback, this, _1, _2), auto callback = [this] (const boost::variant<uint32_t, std::string> &prop,
std::string(m_manager.getInterface()), std::string("State")); const std::string &error) {
}
void NetworkManagerClient::NetworkManagerProperties::getCallback(
const boost::variant<uint32_t, std::string> &prop,
const std::string &error)
{
if (!error.empty()) { if (!error.empty()) {
SE_LOG_DEBUG(NULL, "Error in calling Get of Interface org.freedesktop.DBus.Properties : %s", error.c_str()); SE_LOG_DEBUG(NULL, "Error in calling Get of Interface org.freedesktop.DBus.Properties : %s", error.c_str());
} else { } else {
@ -101,6 +93,8 @@ void NetworkManagerClient::NetworkManagerProperties::getCallback(
m_manager.m_available = true; m_manager.m_available = true;
m_manager.stateChanged(boost::get<uint32_t>(prop)); m_manager.stateChanged(boost::get<uint32_t>(prop));
} }
};
get.start(callback, std::string(m_manager.getInterface()), std::string("State"));
} }
SE_END_CXX SE_END_CXX

View File

@ -74,8 +74,6 @@ private:
NetworkManagerProperties(NetworkManagerClient& manager); NetworkManagerProperties(NetworkManagerClient& manager);
void get(); void get();
void getCallback(const boost::variant<uint32_t, std::string> &prop,
const std::string &error);
private: private:
NetworkManagerClient &m_manager; NetworkManagerClient &m_manager;
}; };

View File

@ -30,9 +30,9 @@ SE_BEGIN_CXX
#define SYNC_UI_PATH "/usr/bin/sync-ui" #define SYNC_UI_PATH "/usr/bin/sync-ui"
boost::shared_ptr<NotificationManagerBase> NotificationManagerFactory::createManager() std::shared_ptr<NotificationManagerBase> NotificationManagerFactory::createManager()
{ {
boost::shared_ptr<NotificationManagerBase> mgr; std::shared_ptr<NotificationManagerBase> mgr;
/* Detect what kind of manager we need: if /usr/bin/sync-ui /* Detect what kind of manager we need: if /usr/bin/sync-ui
* doesn't exists, we shall use the MLite backend; otherwise, if * doesn't exists, we shall use the MLite backend; otherwise, if

View File

@ -23,7 +23,7 @@
#include "syncevo/declarations.h" #include "syncevo/declarations.h"
#include "notification-manager.h" #include "notification-manager.h"
#include <boost/shared_ptr.hpp> #include <memory>
SE_BEGIN_CXX SE_BEGIN_CXX
@ -36,7 +36,7 @@ class NotificationManagerFactory {
* Note: NotificationManagerFactory does not take ownership of * Note: NotificationManagerFactory does not take ownership of
* the returned pointer: the user must delete it when done. * the returned pointer: the user must delete it when done.
*/ */
static boost::shared_ptr<NotificationManagerBase> createManager(); static std::shared_ptr<NotificationManagerBase> createManager();
}; };
SE_END_CXX SE_END_CXX

View File

@ -76,13 +76,13 @@ void ReadOperations::getConfigs(bool getTemplates, std::vector<std::string> &con
} }
} }
boost::shared_ptr<SyncConfig> ReadOperations::getLocalConfig(const string &configName, bool mustExist) std::shared_ptr<SyncConfig> ReadOperations::getLocalConfig(const string &configName, bool mustExist)
{ {
string peer, context; string peer, context;
SyncConfig::splitConfigString(SyncConfig::normalizeConfigString(configName), SyncConfig::splitConfigString(SyncConfig::normalizeConfigString(configName),
peer, context); peer, context);
boost::shared_ptr<SyncConfig> syncConfig(new SyncConfig(configName)); auto syncConfig = std::make_shared<SyncConfig>(configName);
/** if config was not set temporarily */ /** if config was not set temporarily */
if (!setFilters(*syncConfig)) { if (!setFilters(*syncConfig)) {
@ -108,14 +108,14 @@ void ReadOperations::getNamedConfig(const std::string &configName,
Config_t &config) Config_t &config)
{ {
map<string, string> localConfigs; map<string, string> localConfigs;
boost::shared_ptr<SyncConfig> dbusConfig; std::shared_ptr<SyncConfig> dbusConfig;
SyncConfig *syncConfig; SyncConfig *syncConfig;
string syncURL; string syncURL;
/** get server template */ /** get server template */
if(getTemplate) { if(getTemplate) {
string peer, context; string peer, context;
boost::shared_ptr<SyncConfig::TemplateDescription> peerTemplate = std::shared_ptr<SyncConfig::TemplateDescription> peerTemplate =
m_server.getPeerTempl(configName); m_server.getPeerTempl(configName);
if(peerTemplate) { if(peerTemplate) {
SyncConfig::splitConfigString(SyncConfig::normalizeConfigString(peerTemplate->m_templateId), SyncConfig::splitConfigString(SyncConfig::normalizeConfigString(peerTemplate->m_templateId),
@ -157,7 +157,7 @@ void ReadOperations::getNamedConfig(const std::string &configName,
// use the shared properties from the right context as filter // use the shared properties from the right context as filter
// so that the returned template preserves existing properties // so that the returned template preserves existing properties
boost::shared_ptr<SyncConfig> shared = getLocalConfig(string("@") + context, false); std::shared_ptr<SyncConfig> shared = getLocalConfig(string("@") + context, false);
ConfigProps props; ConfigProps props;
shared->getProperties()->readProperties(props); shared->getProperties()->readProperties(props);
@ -252,7 +252,7 @@ void ReadOperations::getReports(uint32_t start, uint32_t count,
SyncReport report; SyncReport report;
// peerName is also extracted from the dir // peerName is also extracted from the dir
string peerName = client.readSessionInfo(dir,report); string peerName = client.readSessionInfo(dir,report);
boost::shared_ptr<SyncConfig> config(new SyncConfig(m_configName)); auto config = std::make_shared<SyncConfig>(m_configName);
string storedPeerName = config->getPeerName(); string storedPeerName = config->getPeerName();
//if can't find peer name, use the peer name from the log dir //if can't find peer name, use the peer name from the log dir
if(!storedPeerName.empty()) { if(!storedPeerName.empty()) {
@ -278,7 +278,7 @@ void ReadOperations::getReports(uint32_t start, uint32_t count,
void ReadOperations::checkSource(const std::string &sourceName) void ReadOperations::checkSource(const std::string &sourceName)
{ {
boost::shared_ptr<SyncConfig> config(new SyncConfig(m_configName)); auto config = std::make_shared<SyncConfig>(m_configName);
setFilters(*config); setFilters(*config);
list<std::string> sourceNames = config->getSyncSources(); list<std::string> sourceNames = config->getSyncSources();
@ -312,7 +312,7 @@ void ReadOperations::checkSource(const std::string &sourceName)
} }
void ReadOperations::getDatabases(const string &sourceName, SourceDatabases_t &databases) void ReadOperations::getDatabases(const string &sourceName, SourceDatabases_t &databases)
{ {
boost::shared_ptr<SyncConfig> config(new SyncConfig(m_configName)); auto config = std::make_shared<SyncConfig>(m_configName);
setFilters(*config); setFilters(*config);
SyncSourceParams params(sourceName, config->getSyncSourceNodes(sourceName), config); SyncSourceParams params(sourceName, config->getSyncSourceNodes(sourceName), config);

View File

@ -91,7 +91,7 @@ private:
* - configName = @default (considered always available) * - configName = @default (considered always available)
* - mustExist = false (used when reading a templates for a context which might not exist yet) * - mustExist = false (used when reading a templates for a context which might not exist yet)
*/ */
boost::shared_ptr<SyncConfig> getLocalConfig(const std::string &configName, bool mustExist = true); std::shared_ptr<SyncConfig> getLocalConfig(const std::string &configName, bool mustExist = true);
}; };
SE_END_CXX SE_END_CXX

View File

@ -20,8 +20,6 @@
#include <fstream> #include <fstream>
#include <boost/bind.hpp>
#include <syncevo/GLibSupport.h> #include <syncevo/GLibSupport.h>
#include <syncevo/timeout.h> #include <syncevo/timeout.h>
@ -43,25 +41,15 @@ using namespace GDBusCXX;
SE_BEGIN_CXX SE_BEGIN_CXX
void Server::onIdleChange(bool idle)
{
SE_LOG_DEBUG(NULL, "server is %s", idle ? "idle" : "not idle");
if (idle) {
autoTermUnref();
} else {
autoTermRef();
}
}
class ServerLogger : public Logger class ServerLogger : public Logger
{ {
Logger::Handle m_parentLogger; Logger::Handle m_parentLogger;
// Currently a strong reference. Would be a weak reference // Currently a strong reference. Would be a weak reference
// if we had proper reference counting for Server. // if we had proper reference counting for Server.
boost::shared_ptr<Server> m_server; std::shared_ptr<Server> m_server;
public: public:
ServerLogger(const boost::shared_ptr<Server> &server) : ServerLogger(const std::shared_ptr<Server> &server) :
m_parentLogger(Logger::instance()), m_parentLogger(Logger::instance()),
m_server(server) m_server(server)
{ {
@ -75,7 +63,7 @@ public:
// from holding onto the server while it tries to shut down. // from holding onto the server while it tries to shut down.
// //
// This is important because the server's live time is not // This is important because the server's live time is not
// really controlled via the boost::shared_ptr, it may // really controlled via the std::shared_ptr, it may
// destruct while there are still references. See // destruct while there are still references. See
// Server::m_logger instantiation below. // Server::m_logger instantiation below.
RecMutex::Guard guard = lock(); RecMutex::Guard guard = lock();
@ -191,16 +179,16 @@ StringMap Server::getVersions()
} }
void Server::attachClient(const Caller_t &caller, void Server::attachClient(const Caller_t &caller,
const boost::shared_ptr<Watch> &watch) const std::shared_ptr<Watch> &watch)
{ {
boost::shared_ptr<Client> client = addClient(caller, watch); std::shared_ptr<Client> client = addClient(caller, watch);
autoTermRef(); autoTermRef();
client->increaseAttachCount(); client->increaseAttachCount();
} }
void Server::detachClient(const Caller_t &caller) void Server::detachClient(const Caller_t &caller)
{ {
boost::shared_ptr<Client> client = findClient(caller); std::shared_ptr<Client> client = findClient(caller);
if (client) { if (client) {
autoTermUnref(); autoTermUnref();
client->decreaseAttachCount(); client->decreaseAttachCount();
@ -211,7 +199,7 @@ void Server::setNotifications(bool enabled,
const Caller_t &caller, const Caller_t &caller,
const string & /* notifications */) const string & /* notifications */)
{ {
boost::shared_ptr<Client> client = findClient(caller); std::shared_ptr<Client> client = findClient(caller);
if (client && client->getAttachCount()) { if (client && client->getAttachCount()) {
client->setNotificationsEnabled(enabled); client->setNotificationsEnabled(enabled);
} else { } else {
@ -232,7 +220,7 @@ bool Server::notificationsEnabled()
} }
void Server::connect(const Caller_t &caller, void Server::connect(const Caller_t &caller,
const boost::shared_ptr<Watch> &watch, const std::shared_ptr<Watch> &watch,
const StringMap &peer, const StringMap &peer,
bool must_authenticate, bool must_authenticate,
const std::string &session, const std::string &session,
@ -249,17 +237,17 @@ void Server::connect(const Caller_t &caller,
} }
std::string new_session = getNextSession(); std::string new_session = getNextSession();
boost::shared_ptr<Connection> c(Connection::createConnection(*this, auto c = make_weak_shared::make<Connection>(*this,
getConnection(), getConnection(),
new_session, new_session,
peer, peer,
must_authenticate)); must_authenticate);
SE_LOG_DEBUG(NULL, "connecting D-Bus client %s with connection %s '%s'", SE_LOG_DEBUG(NULL, "connecting D-Bus client %s with connection %s '%s'",
caller.c_str(), caller.c_str(),
c->getPath(), c->getPath(),
c->m_description.c_str()); c->m_description.c_str());
boost::shared_ptr<Client> client = addClient(caller, std::shared_ptr<Client> client = addClient(caller,
watch); watch);
client->attach(c); client->attach(c);
c->activate(); c->activate();
@ -268,7 +256,7 @@ void Server::connect(const Caller_t &caller,
} }
void Server::startSessionWithFlags(const Caller_t &caller, void Server::startSessionWithFlags(const Caller_t &caller,
const boost::shared_ptr<Watch> &watch, const std::shared_ptr<Watch> &watch,
const std::string &server, const std::string &server,
const std::vector<std::string> &flags, const std::vector<std::string> &flags,
DBusObject_t &object) DBusObject_t &object)
@ -278,10 +266,10 @@ void Server::startSessionWithFlags(const Caller_t &caller,
SE_THROW("server shutting down"); SE_THROW("server shutting down");
} }
boost::shared_ptr<Client> client = addClient(caller, std::shared_ptr<Client> client = addClient(caller,
watch); watch);
std::string new_session = getNextSession(); std::string new_session = getNextSession();
boost::shared_ptr<Session> session = Session::createSession(*this, auto session = make_weak_shared::make<Session>(*this,
"is this a client or server session?", "is this a client or server session?",
server, server,
new_session, new_session,
@ -293,9 +281,9 @@ void Server::startSessionWithFlags(const Caller_t &caller,
} }
boost::shared_ptr<Session> Server::startInternalSession(const std::string &server, std::shared_ptr<Session> Server::startInternalSession(const std::string &server,
SessionFlags flags, SessionFlags flags,
const boost::function<void (const boost::weak_ptr<Session> &session)> &callback) const std::function<void (const std::weak_ptr<Session> &session)> &callback)
{ {
if (m_shutdownRequested) { if (m_shutdownRequested) {
// don't allow new sessions, we cannot activate them // don't allow new sessions, we cannot activate them
@ -311,12 +299,12 @@ boost::shared_ptr<Session> Server::startInternalSession(const std::string &serve
} }
std::string new_session = getNextSession(); std::string new_session = getNextSession();
boost::shared_ptr<Session> session = Session::createSession(*this, auto session = make_weak_shared::make<Session>(*this,
"is this a client or server session?", "is this a client or server session?",
server, server,
new_session, new_session,
dbusFlags); dbusFlags);
session->m_sessionActiveSignal.connect(boost::bind(callback, boost::weak_ptr<Session>(session))); session->m_sessionActiveSignal.connect([weakSessionPtr=std::weak_ptr<Session>(session), callback] () { callback(weakSessionPtr); });
session->activate(); session->activate();
enqueue(session); enqueue(session);
return session; return session;
@ -336,8 +324,8 @@ void Server::getSessions(std::vector<DBusObject_t> &sessions)
if (m_activeSession) { if (m_activeSession) {
sessions.push_back(m_activeSession->getPath()); sessions.push_back(m_activeSession->getPath());
} }
for (boost::weak_ptr<Session> &session: m_workQueue) { for (std::weak_ptr<Session> &session: m_workQueue) {
boost::shared_ptr<Session> s = session.lock(); std::shared_ptr<Session> s = session.lock();
if (s) { if (s) {
sessions.push_back(s->getPath()); sessions.push_back(s->getPath());
} }
@ -345,13 +333,13 @@ void Server::getSessions(std::vector<DBusObject_t> &sessions)
} }
Server::Server(GMainLoop *loop, Server::Server(GMainLoop *loop,
boost::shared_ptr<Restart> &restart, std::shared_ptr<Restart> &restart,
const DBusConnectionPtr &conn, const DBusConnectionPtr &conn,
int duration) : int duration) :
DBusObjectHelper(conn, DBusObjectHelper(conn,
SessionCommon::SERVER_PATH, SessionCommon::SERVER_PATH,
SessionCommon::SERVER_IFACE, SessionCommon::SERVER_IFACE,
boost::bind(&Server::autoTermCallback, this)), [this] () { autoTermCallback(); }),
m_loop(loop), m_loop(loop),
m_suspendFlagsSource(0), m_suspendFlagsSource(0),
m_shutdownRequested(false), m_shutdownRequested(false),
@ -373,7 +361,7 @@ Server::Server(GMainLoop *loop,
// This would help with dangling references to it when other threads // This would help with dangling references to it when other threads
// use it for logging, see ServerLogger. However, with mutex locking // use it for logging, see ServerLogger. However, with mutex locking
// in ServerLogger that shouldn't be a problem. // in ServerLogger that shouldn't be a problem.
m_logger(new ServerLogger(boost::shared_ptr<Server>(this, NopDestructor()))) m_logger(new ServerLogger(std::shared_ptr<Server>(this, NopDestructor())))
{ {
struct timeval tv; struct timeval tv;
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
@ -405,16 +393,28 @@ Server::Server(GMainLoop *loop,
// Log entering and leaving idle state and // Log entering and leaving idle state and
// allow/prevent auto-termination. // allow/prevent auto-termination.
m_idleSignal.connect(boost::bind(&Server::onIdleChange, this, _1)); auto onIdleChange = [this] (bool idle) {
SE_LOG_DEBUG(NULL, "server is %s", idle ? "idle" : "not idle");
if (idle) {
autoTermUnref();
} else {
autoTermRef();
}
};
m_idleSignal.connect(onIdleChange);
// connect ConfigChanged signal to source for that information // connect ConfigChanged signal to source for that information
m_configChangedSignal.connect(boost::bind(boost::ref(configChanged))); m_configChangedSignal.connect([this] (const std::string &configName) { configChanged(); });
} }
gboolean Server::onSuspendFlagsChange(GIOChannel *source, void Server::activate()
GIOCondition condition,
gpointer data) throw ()
{ {
// Watch SuspendFlags fd to react to signals quickly.
int fd = SuspendFlags::getSuspendFlags().getEventFD();
GIOChannelCXX channel(g_io_channel_unix_new(fd), TRANSFER_REF);
auto onSuspendFlagsChange = [] (GIOChannel *source,
GIOCondition condition,
gpointer data) throw () {
Server *me = static_cast<Server *>(data); Server *me = static_cast<Server *>(data);
try { try {
if (!SuspendFlags::getSuspendFlags().isNormal()) { if (!SuspendFlags::getSuspendFlags().isNormal()) {
@ -426,14 +426,8 @@ gboolean Server::onSuspendFlagsChange(GIOChannel *source,
Exception::handle(); Exception::handle();
} }
// Keep watching, just in case that we catch multiple signals. // Keep watching, just in case that we catch multiple signals.
return TRUE; return (gboolean)TRUE;
} };
void Server::activate()
{
// Watch SuspendFlags fd to react to signals quickly.
int fd = SuspendFlags::getSuspendFlags().getEventFD();
GIOChannelCXX channel(g_io_channel_unix_new(fd), TRANSFER_REF);
m_suspendFlagsSource = g_io_add_watch(channel, G_IO_IN, onSuspendFlagsChange, this); m_suspendFlagsSource = g_io_add_watch(channel, G_IO_IN, onSuspendFlagsChange, this);
// Activate our D-Bus object *before* interacting with D-Bus // Activate our D-Bus object *before* interacting with D-Bus
@ -517,7 +511,7 @@ void Server::fileModified(const std::string &file)
m_lastFileMod = Timespec::monotonic(); m_lastFileMod = Timespec::monotonic();
if (!m_activeSession) { if (!m_activeSession) {
m_shutdownTimer.activate(SHUTDOWN_QUIESENCE_SECONDS, m_shutdownTimer.activate(SHUTDOWN_QUIESENCE_SECONDS,
boost::bind(&Server::shutdown, this)); [this] () { return shutdown(); });
} }
m_shutdownRequested = true; m_shutdownRequested = true;
} }
@ -549,7 +543,7 @@ void Server::run()
for (const string &file: files) { for (const string &file: files) {
try { try {
SE_LOG_DEBUG(NULL, "watching: %s", file.c_str()); SE_LOG_DEBUG(NULL, "watching: %s", file.c_str());
boost::shared_ptr<SyncEvo::GLibNotify> notify(new GLibNotify(file.c_str(), boost::bind(&Server::fileModified, this, file))); auto notify = std::make_shared<GLibNotify>(file.c_str(), [this, file] (GFile *, GFile *, GFileMonitorEvent) { fileModified(file); });
m_files.push_back(notify); m_files.push_back(notify);
} catch (...) { } catch (...) {
// ignore errors for indidividual files // ignore errors for indidividual files
@ -576,7 +570,7 @@ void Server::run()
/** /**
* look up client by its ID * look up client by its ID
*/ */
boost::shared_ptr<Client> Server::findClient(const Caller_t &ID) std::shared_ptr<Client> Server::findClient(const Caller_t &ID)
{ {
for (Clients_t::iterator it = m_clients.begin(); for (Clients_t::iterator it = m_clients.begin();
it != m_clients.end(); it != m_clients.end();
@ -585,13 +579,13 @@ boost::shared_ptr<Client> Server::findClient(const Caller_t &ID)
return it->second; return it->second;
} }
} }
return boost::shared_ptr<Client>(); return std::shared_ptr<Client>();
} }
boost::shared_ptr<Client> Server::addClient(const Caller_t &ID, std::shared_ptr<Client> Server::addClient(const Caller_t &ID,
const boost::shared_ptr<Watch> &watch) const std::shared_ptr<Watch> &watch)
{ {
boost::shared_ptr<Client> client(findClient(ID)); std::shared_ptr<Client> client(findClient(ID));
if (client) { if (client) {
return client; return client;
} }
@ -599,7 +593,9 @@ boost::shared_ptr<Client> Server::addClient(const Caller_t &ID,
// add to our list *before* checking that peer exists, so // add to our list *before* checking that peer exists, so
// that clientGone() can remove it if the check fails // that clientGone() can remove it if the check fails
m_clients.push_back(std::make_pair(watch, client)); m_clients.push_back(std::make_pair(watch, client));
watch->setCallback(boost::bind(&Server::clientGone, this, client.get())); // Here we intentionally bind the raw pointer. It's only going to be used for
// comparisons.
watch->setCallback([this, clientPtr=client.get()] () { Server::clientGone(clientPtr); });
return client; return client;
} }
@ -611,7 +607,7 @@ void Server::detach(Resource *resource)
} }
} }
void Server::enqueue(const boost::shared_ptr<Session> &session) void Server::enqueue(const std::shared_ptr<Session> &session)
{ {
bool idle = isIdle(); bool idle = isIdle();
@ -619,7 +615,7 @@ void Server::enqueue(const boost::shared_ptr<Session> &session)
while (it != m_workQueue.begin()) { while (it != m_workQueue.begin()) {
--it; --it;
// skip over dead sessions, they will get cleaned up elsewhere // skip over dead sessions, they will get cleaned up elsewhere
boost::shared_ptr<Session> session = it->lock(); std::shared_ptr<Session> session = it->lock();
if (session && session->getPriority() <= session->getPriority()) { if (session && session->getPriority() <= session->getPriority()) {
++it; ++it;
break; break;
@ -638,13 +634,13 @@ void Server::killSessionsAsync(const std::string &peerDeviceID,
{ {
WorkQueue_t::iterator it = m_workQueue.begin(); WorkQueue_t::iterator it = m_workQueue.begin();
while (it != m_workQueue.end()) { while (it != m_workQueue.end()) {
boost::shared_ptr<Session> session = it->lock(); std::shared_ptr<Session> session = it->lock();
if (session && session->getPeerDeviceID() == peerDeviceID) { if (session && session->getPeerDeviceID() == peerDeviceID) {
SE_LOG_DEBUG(NULL, "removing pending session %s because it matches deviceID %s", SE_LOG_DEBUG(NULL, "removing pending session %s because it matches deviceID %s",
session->getSessionID().c_str(), session->getSessionID().c_str(),
peerDeviceID.c_str()); peerDeviceID.c_str());
// remove session and its corresponding connection // remove session and its corresponding connection
boost::shared_ptr<Connection> c = session->getStubConnection().lock(); std::shared_ptr<Connection> c = session->getStubConnection().lock();
if (c) { if (c) {
c->shutdown(); c->shutdown();
} }
@ -655,7 +651,7 @@ void Server::killSessionsAsync(const std::string &peerDeviceID,
} }
// Check active session. We need to wait for it to shut down cleanly. // Check active session. We need to wait for it to shut down cleanly.
boost::shared_ptr<Session> active = m_activeSessionRef.lock(); std::shared_ptr<Session> active = m_activeSessionRef.lock();
if (active && if (active &&
active->getPeerDeviceID() == peerDeviceID) { active->getPeerDeviceID() == peerDeviceID) {
SE_LOG_DEBUG(NULL, "aborting active session %s because it matches deviceID %s", SE_LOG_DEBUG(NULL, "aborting active session %s because it matches deviceID %s",
@ -705,7 +701,7 @@ void Server::dequeue(Session *session)
if (shutdown >= now) { if (shutdown >= now) {
SE_LOG_DEBUG(NULL, "file modified, initiating shutdown after session finished"); SE_LOG_DEBUG(NULL, "file modified, initiating shutdown after session finished");
m_shutdownTimer.activate((shutdown - now).seconds(), m_shutdownTimer.activate((shutdown - now).seconds(),
boost::bind(&Server::shutdown, this)); [this] () { return this->shutdown(); });
} }
} }
checkQueue(); checkQueue();
@ -752,12 +748,6 @@ void Server::removeSyncSession(Session *session)
} }
} }
static void quitLoop(GMainLoop *loop)
{
SE_LOG_DEBUG(NULL, "stopping server's event loop");
g_main_loop_quit(loop);
}
void Server::checkQueue() void Server::checkQueue()
{ {
if (m_activeSession) { if (m_activeSession) {
@ -776,13 +766,17 @@ void Server::checkQueue()
// then the server shut down immediately after Detach()). // then the server shut down immediately after Detach()).
if (!m_shutdownTimer) { if (!m_shutdownTimer) {
SE_LOG_DEBUG(NULL, "shutting down in checkQueue(), idle and shutdown was requested"); SE_LOG_DEBUG(NULL, "shutting down in checkQueue(), idle and shutdown was requested");
addTimeout(boost::bind(quitLoop, m_loop), 0); addTimeout([this] () {
SE_LOG_DEBUG(NULL, "stopping server's event loop");
g_main_loop_quit(m_loop);
},
0);
} }
return; return;
} }
while (!m_workQueue.empty()) { while (!m_workQueue.empty()) {
boost::shared_ptr<Session> session = m_workQueue.front().lock(); std::shared_ptr<Session> session = m_workQueue.front().lock();
m_workQueue.pop_front(); m_workQueue.pop_front();
if (session) { if (session) {
// activate the session // activate the session
@ -796,13 +790,7 @@ void Server::checkQueue()
} }
} }
void Server::sessionExpired(const boost::shared_ptr<Session> &session) void Server::delaySessionDestruction(const std::shared_ptr<Session> &session)
{
SE_LOG_DEBUG(NULL, "session %s expired",
session->getSessionID().c_str());
}
void Server::delaySessionDestruction(const boost::shared_ptr<Session> &session)
{ {
if (!session) { if (!session) {
return; return;
@ -810,8 +798,12 @@ void Server::delaySessionDestruction(const boost::shared_ptr<Session> &session)
SE_LOG_DEBUG(NULL, "delaying destruction of session %s by one minute", SE_LOG_DEBUG(NULL, "delaying destruction of session %s by one minute",
session->getSessionID().c_str()); session->getSessionID().c_str());
addTimeout(boost::bind(&Server::sessionExpired, // The trick here is to bind the shared pointer to the timeout instance
session), // for the duration of the timeout.
addTimeout([session] () {
SE_LOG_DEBUG(NULL, "session %s expired",
session->getSessionID().c_str());
},
60 /* 1 minute */); 60 /* 1 minute */);
} }
@ -825,14 +817,14 @@ inline void insertPair(std::map<string, string> &params,
} }
boost::shared_ptr<InfoReq> Server::passwordRequest(const string &descr, std::shared_ptr<InfoReq> Server::passwordRequest(const string &descr,
const ConfigPasswordKey &key, const ConfigPasswordKey &key,
const boost::weak_ptr<Session> &s) const std::weak_ptr<Session> &s)
{ {
boost::shared_ptr<Session> session = s.lock(); std::shared_ptr<Session> session = s.lock();
if (!session) { if (!session) {
// already gone, ignore request // already gone, ignore request
return boost::shared_ptr<InfoReq>(); return std::shared_ptr<InfoReq>();
} }
std::map<string, string> params; std::map<string, string> params;
@ -844,30 +836,25 @@ boost::shared_ptr<InfoReq> Server::passwordRequest(const string &descr,
insertPair(params, "protocol", key.protocol); insertPair(params, "protocol", key.protocol);
insertPair(params, "authtype", key.authtype); insertPair(params, "authtype", key.authtype);
insertPair(params, "port", key.port ? StringPrintf("%u",key.port) : ""); insertPair(params, "port", key.port ? StringPrintf("%u",key.port) : "");
boost::shared_ptr<InfoReq> req = createInfoReq("password", params, *session); std::shared_ptr<InfoReq> req = createInfoReq("password", params, *session);
// Return password or failure to Session and thus the session helper. // Return password or failure to Session and thus the session helper.
req->m_responseSignal.connect(boost::bind(&Server::passwordResponse, req->m_responseSignal.connect([this, s] (const InfoReq::InfoMap &response) { passwordResponse(response, s); });
this,
_1,
s));
// Tell session about timeout. // Tell session about timeout.
req->m_timeoutSignal.connect(InfoReq::TimeoutSignal_t::slot_type(&Session::passwordResponse, req->m_timeoutSignal.connect(InfoReq::TimeoutSignal_t::slot_type(&Session::passwordResponse,
session.get(), session.get(),
true, true,
false, false,
"").track(s)); "").track_foreign(s));
// Request becomes obsolete when session is done. // Request becomes obsolete when session is done.
session->m_doneSignal.connect(boost::bind(&Server::removeInfoReq, session->m_doneSignal.connect([this, id=req->getId()] (SyncEvo::SyncMLStatus, const SyncEvo::SyncReport &) { removeInfoReq(id); });
this,
req->getId()));
return req; return req;
} }
void Server::passwordResponse(const InfoReq::InfoMap &response, void Server::passwordResponse(const InfoReq::InfoMap &response,
const boost::weak_ptr<Session> &s) const std::weak_ptr<Session> &s)
{ {
boost::shared_ptr<Session> session = s.lock(); std::shared_ptr<Session> session = s.lock();
if (!session) { if (!session) {
// already gone, ignore request // already gone, ignore request
return; return;
@ -884,29 +871,24 @@ void Server::passwordResponse(const InfoReq::InfoMap &response,
} }
bool Server::callTimeout(const boost::shared_ptr<Timeout> &timeout, const boost::function<void ()> &callback) void Server::addTimeout(const std::function<void ()> &callback,
int seconds)
{ {
auto timeout = std::make_shared<Timeout>();
m_timeouts.push_back(timeout);
auto callTimeout = [this, timeoutWeak=std::weak_ptr<Timeout>(timeout), callback] () {
auto timeout = timeoutWeak.lock();
if (timeout) {
callback(); callback();
// We are executing the timeout, don't invalidate the instance // We are executing the timeout, don't invalidate the instance
// until later when our caller is no longer using the instance to // until later when our caller is no longer using the instance to
// call us. // call us.
delayDeletion(timeout); delayDeletion(timeout);
m_timeouts.remove(timeout); m_timeouts.remove(timeout);
return false;
} }
return false;
void Server::addTimeout(const boost::function<void ()> &callback, };
int seconds) timeout->activate(seconds, callTimeout);
{
boost::shared_ptr<Timeout> timeout(new Timeout);
m_timeouts.push_back(timeout);
timeout->activate(seconds,
boost::bind(&Server::callTimeout,
this,
// avoid copying the shared pointer here,
// otherwise the Timeout will never be deleted
boost::ref(m_timeouts.back()),
callback));
} }
void Server::infoResponse(const Caller_t &caller, void Server::infoResponse(const Caller_t &caller,
@ -917,26 +899,23 @@ void Server::infoResponse(const Caller_t &caller,
InfoReqMap::iterator it = m_infoReqMap.find(id); InfoReqMap::iterator it = m_infoReqMap.find(id);
// if not found, ignore // if not found, ignore
if (it != m_infoReqMap.end()) { if (it != m_infoReqMap.end()) {
const boost::shared_ptr<InfoReq> infoReq = it->second.lock(); const std::shared_ptr<InfoReq> infoReq = it->second.lock();
if (infoReq) { if (infoReq) {
infoReq->setResponse(caller, state, response); infoReq->setResponse(caller, state, response);
} }
} }
} }
boost::shared_ptr<InfoReq> Server::createInfoReq(const string &type, std::shared_ptr<InfoReq> Server::createInfoReq(const string &type,
const std::map<string, string> &parameters, const std::map<std::string, std::string> &parameters,
const Session &session) const Session &session)
{ {
boost::shared_ptr<InfoReq> infoReq(new InfoReq(*this, type, parameters, session.getPath())); auto infoReq = std::make_shared<InfoReq>(*this, type, parameters, session.getPath());
m_infoReqMap.insert(std::make_pair(infoReq->getId(), infoReq)); m_infoReqMap.insert(std::make_pair(infoReq->getId(), infoReq));
// will be removed automatically // will be removed automatically
infoReq->m_responseSignal.connect(boost::bind(&Server::removeInfoReq, auto remove = [this, id=infoReq->getId()] () { removeInfoReq(id); };
this, infoReq->m_responseSignal.connect([this, id=infoReq->getId()] (const std::map<std::string, std::string> &) { removeInfoReq(id); });
infoReq->getId())); infoReq->m_timeoutSignal.connect([this, id=infoReq->getId()] () { removeInfoReq(id); });
infoReq->m_timeoutSignal.connect(boost::bind(&Server::removeInfoReq,
this,
infoReq->getId()));
return infoReq; return infoReq;
} }
@ -982,14 +961,14 @@ void Server::getDeviceList(SyncConfig::DeviceList &devices)
} }
void Server::addPeerTempl(const string &templName, void Server::addPeerTempl(const string &templName,
const boost::shared_ptr<SyncConfig::TemplateDescription> peerTempl) const std::shared_ptr<SyncConfig::TemplateDescription> &peerTempl)
{ {
std::string lower = templName; std::string lower = templName;
boost::to_lower(lower); boost::to_lower(lower);
m_matchedTempls.insert(MatchedTemplates::value_type(lower, peerTempl)); m_matchedTempls.insert(MatchedTemplates::value_type(lower, peerTempl));
} }
boost::shared_ptr<SyncConfig::TemplateDescription> Server::getPeerTempl(const string &peer) std::shared_ptr<SyncConfig::TemplateDescription> Server::getPeerTempl(const string &peer)
{ {
std::string lower = peer; std::string lower = peer;
boost::to_lower(lower); boost::to_lower(lower);
@ -997,7 +976,7 @@ boost::shared_ptr<SyncConfig::TemplateDescription> Server::getPeerTempl(const st
if(it != m_matchedTempls.end()) { if(it != m_matchedTempls.end()) {
return it->second; return it->second;
} else { } else {
return boost::shared_ptr<SyncConfig::TemplateDescription>(); return std::shared_ptr<SyncConfig::TemplateDescription>();
} }
} }
@ -1008,7 +987,7 @@ bool Server::getDevice(const string &deviceId, SyncConfig::DeviceDescription &de
if (boost::equals(syncDevIt->m_deviceId, deviceId)) { if (boost::equals(syncDevIt->m_deviceId, deviceId)) {
device = *syncDevIt; device = *syncDevIt;
if (syncDevIt->m_pnpInformation) { if (syncDevIt->m_pnpInformation) {
device.m_pnpInformation = boost::shared_ptr<SyncConfig::PnpInformation>( device.m_pnpInformation = std::shared_ptr<SyncConfig::PnpInformation>(
new SyncConfig::PnpInformation(syncDevIt->m_pnpInformation->m_vendor, new SyncConfig::PnpInformation(syncDevIt->m_pnpInformation->m_vendor,
syncDevIt->m_pnpInformation->m_product)); syncDevIt->m_pnpInformation->m_product));
} }

View File

@ -20,10 +20,6 @@
#ifndef SYNCEVO_DBUS_SERVER_H #ifndef SYNCEVO_DBUS_SERVER_H
#define SYNCEVO_DBUS_SERVER_H #define SYNCEVO_DBUS_SERVER_H
#include <set>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/signals2.hpp> #include <boost/signals2.hpp>
#include <syncevo/SyncConfig.h> #include <syncevo/SyncConfig.h>
@ -34,6 +30,9 @@
#include "dbus-callbacks.h" #include "dbus-callbacks.h"
#include "read-operations.h" #include "read-operations.h"
#include <set>
#include <memory>
#include <syncevo/declarations.h> #include <syncevo/declarations.h>
SE_BEGIN_CXX SE_BEGIN_CXX
@ -66,11 +65,11 @@ class Server : public GDBusCXX::DBusObjectHelper
guint m_suspendFlagsSource; guint m_suspendFlagsSource;
bool m_shutdownRequested; bool m_shutdownRequested;
Timespec m_lastFileMod; Timespec m_lastFileMod;
boost::shared_ptr<SyncEvo::Restart> &m_restart; std::shared_ptr<SyncEvo::Restart> &m_restart;
GDBusCXX::DBusConnectionPtr m_conn; GDBusCXX::DBusConnectionPtr m_conn;
uint32_t m_lastSession; uint32_t m_lastSession;
typedef std::list< std::pair< boost::shared_ptr<GDBusCXX::Watch>, boost::shared_ptr<Client> > > Clients_t; typedef std::list< std::pair< std::shared_ptr<GDBusCXX::Watch>, std::shared_ptr<Client> > > Clients_t;
Clients_t m_clients; Clients_t m_clients;
/** /**
@ -79,7 +78,7 @@ class Server : public GDBusCXX::DBusObjectHelper
* server terminates, thus unrefing anything encapsulated inside * server terminates, thus unrefing anything encapsulated inside
* it. * it.
*/ */
std::list< boost::function<void ()> > m_delayDeletion; std::list< std::function<void ()> > m_delayDeletion;
/** /**
* Watch all files mapped into our address space. When * Watch all files mapped into our address space. When
@ -93,7 +92,7 @@ class Server : public GDBusCXX::DBusObjectHelper
* down or restarts. The latter is necessary if the daemon has * down or restarts. The latter is necessary if the daemon has
* automatic syncing enabled in a config. * automatic syncing enabled in a config.
*/ */
list< boost::shared_ptr<GLibNotify> > m_files; list< std::shared_ptr<GLibNotify> > m_files;
void fileModified(const std::string &file); void fileModified(const std::string &file);
bool shutdown(); bool shutdown();
@ -121,7 +120,7 @@ class Server : public GDBusCXX::DBusObjectHelper
/** /**
* The weak pointer that corresponds to m_activeSession. * The weak pointer that corresponds to m_activeSession.
*/ */
boost::weak_ptr<Session> m_activeSessionRef; std::weak_ptr<Session> m_activeSessionRef;
/** /**
* The running sync session. Having a separate reference to it * The running sync session. Having a separate reference to it
@ -132,9 +131,9 @@ class Server : public GDBusCXX::DBusObjectHelper
* addSyncSession() and remove itself with removeSyncSession() when * addSyncSession() and remove itself with removeSyncSession() when
* done. * done.
*/ */
boost::shared_ptr<Session> m_syncSession; std::shared_ptr<Session> m_syncSession;
typedef std::list< boost::weak_ptr<Session> > WorkQueue_t; typedef std::list< std::weak_ptr<Session> > WorkQueue_t;
/** /**
* A queue of pending, idle Sessions. Sorted by priority, most * A queue of pending, idle Sessions. Sorted by priority, most
* important one first. Currently this is used to give client * important one first. Currently this is used to give client
@ -150,7 +149,7 @@ class Server : public GDBusCXX::DBusObjectHelper
/** /**
* a hash of pending InfoRequest * a hash of pending InfoRequest
*/ */
typedef std::map<string, boost::weak_ptr<InfoReq> > InfoReqMap; typedef std::map<string, std::weak_ptr<InfoReq> > InfoReqMap;
// hash map of pending info requests // hash map of pending info requests
InfoReqMap m_infoReqMap; InfoReqMap m_infoReqMap;
@ -160,11 +159,11 @@ class Server : public GDBusCXX::DBusObjectHelper
// a hash to represent matched templates for devices, the key is // a hash to represent matched templates for devices, the key is
// the peer name // the peer name
typedef std::map<string, boost::shared_ptr<SyncConfig::TemplateDescription> > MatchedTemplates; typedef std::map<string, std::shared_ptr<SyncConfig::TemplateDescription> > MatchedTemplates;
MatchedTemplates m_matchedTempls; MatchedTemplates m_matchedTempls;
boost::shared_ptr<BluezManager> m_bluezManager; std::shared_ptr<BluezManager> m_bluezManager;
/** devices which have sync services */ /** devices which have sync services */
SyncConfig::DeviceList m_syncDevices; SyncConfig::DeviceList m_syncDevices;
@ -186,7 +185,7 @@ class Server : public GDBusCXX::DBusObjectHelper
/** Server.Attach() */ /** Server.Attach() */
void attachClient(const GDBusCXX::Caller_t &caller, void attachClient(const GDBusCXX::Caller_t &caller,
const boost::shared_ptr<GDBusCXX::Watch> &watch); const std::shared_ptr<GDBusCXX::Watch> &watch);
/** Server.Detach() */ /** Server.Detach() */
void detachClient(const GDBusCXX::Caller_t &caller); void detachClient(const GDBusCXX::Caller_t &caller);
@ -228,7 +227,7 @@ class Server : public GDBusCXX::DBusObjectHelper
/** Server.Connect() */ /** Server.Connect() */
void connect(const GDBusCXX::Caller_t &caller, void connect(const GDBusCXX::Caller_t &caller,
const boost::shared_ptr<GDBusCXX::Watch> &watch, const std::shared_ptr<GDBusCXX::Watch> &watch,
const StringMap &peer, const StringMap &peer,
bool must_authenticate, bool must_authenticate,
const std::string &session, const std::string &session,
@ -236,7 +235,7 @@ class Server : public GDBusCXX::DBusObjectHelper
/** Server.StartSession() */ /** Server.StartSession() */
void startSession(const GDBusCXX::Caller_t &caller, void startSession(const GDBusCXX::Caller_t &caller,
const boost::shared_ptr<GDBusCXX::Watch> &watch, const std::shared_ptr<GDBusCXX::Watch> &watch,
const std::string &server, const std::string &server,
GDBusCXX::DBusObject_t &object) { GDBusCXX::DBusObject_t &object) {
startSessionWithFlags(caller, watch, server, std::vector<std::string>(), object); startSessionWithFlags(caller, watch, server, std::vector<std::string>(), object);
@ -244,7 +243,7 @@ class Server : public GDBusCXX::DBusObjectHelper
/** Server.StartSessionWithFlags() */ /** Server.StartSessionWithFlags() */
void startSessionWithFlags(const GDBusCXX::Caller_t &caller, void startSessionWithFlags(const GDBusCXX::Caller_t &caller,
const boost::shared_ptr<GDBusCXX::Watch> &watch, const std::shared_ptr<GDBusCXX::Watch> &watch,
const std::string &server, const std::string &server,
const std::vector<std::string> &flags, const std::vector<std::string> &flags,
GDBusCXX::DBusObject_t &object); GDBusCXX::DBusObject_t &object);
@ -263,9 +262,9 @@ class Server : public GDBusCXX::DBusObjectHelper
* that reference, the session gets deleted and the callback * that reference, the session gets deleted and the callback
* will not be called. * will not be called.
*/ */
boost::shared_ptr<Session> startInternalSession(const std::string &server, std::shared_ptr<Session> startInternalSession(const std::string &server,
SessionFlags flags, SessionFlags flags,
const boost::function<void (const boost::weak_ptr<Session> &session)> &callback); const std::function<void (const std::weak_ptr<Session> &session)> &callback);
/** Server.GetConfig() */ /** Server.GetConfig() */
void getConfig(const std::string &config_name, void getConfig(const std::string &config_name,
@ -384,7 +383,7 @@ class Server : public GDBusCXX::DBusObjectHelper
boost::scoped_ptr<NetworkManagerClient> m_networkManager; boost::scoped_ptr<NetworkManagerClient> m_networkManager;
/** Manager to automatic sync */ /** Manager to automatic sync */
boost::shared_ptr<AutoSyncManager> m_autoSync; std::shared_ptr<AutoSyncManager> m_autoSync;
//automatic termination //automatic termination
AutoTerm m_autoTerm; AutoTerm m_autoTerm;
@ -394,7 +393,7 @@ class Server : public GDBusCXX::DBusObjectHelper
// Created in constructor and captures parent logger there, // Created in constructor and captures parent logger there,
// then pushed as default logger in activate(). // then pushed as default logger in activate().
boost::shared_ptr<ServerLogger> m_logger; std::shared_ptr<ServerLogger> m_logger;
PushLogger<ServerLogger> m_pushLogger; PushLogger<ServerLogger> m_pushLogger;
/** /**
@ -402,28 +401,11 @@ class Server : public GDBusCXX::DBusObjectHelper
* Each timeout which requests to be not called * Each timeout which requests to be not called
* again will be removed from this list. * again will be removed from this list.
*/ */
list< boost::shared_ptr<Timeout> > m_timeouts; list< std::shared_ptr<Timeout> > m_timeouts;
/**
* called each time a timeout triggers,
* removes those which are done
*/
bool callTimeout(const boost::shared_ptr<Timeout> &timeout, const boost::function<void ()> &callback);
/** called 1 minute after last client detached from a session */
static void sessionExpired(const boost::shared_ptr<Session> &session);
/** hooked into m_idleSignal, controls auto-termination */
void onIdleChange(bool idle);
/** hooked up to SuspendFlags fd via g_io_add_watch */
static gboolean onSuspendFlagsChange(GIOChannel *source,
GIOCondition condition,
gpointer data) throw ();
public: public:
Server(GMainLoop *loop, Server(GMainLoop *loop,
boost::shared_ptr<Restart> &restart, std::shared_ptr<Restart> &restart,
const GDBusCXX::DBusConnectionPtr &conn, const GDBusCXX::DBusConnectionPtr &conn,
int duration); int duration);
void activate(); void activate();
@ -436,7 +418,7 @@ public:
void run(); void run();
/** currently running operation */ /** currently running operation */
boost::shared_ptr<Session> getSyncSession() const { return m_syncSession; } std::shared_ptr<Session> getSyncSession() const { return m_syncSession; }
/** true iff no work is pending */ /** true iff no work is pending */
bool isIdle() const { return !m_activeSession && m_workQueue.empty(); } bool isIdle() const { return !m_activeSession && m_workQueue.empty(); }
@ -456,19 +438,19 @@ public:
/** /**
* Called when a session starts its real work (= calls addSyncSession()). * Called when a session starts its real work (= calls addSyncSession()).
*/ */
typedef boost::signals2::signal<void (const boost::shared_ptr<Session> &)> NewSyncSessionSignal_t; typedef boost::signals2::signal<void (const std::shared_ptr<Session> &)> NewSyncSessionSignal_t;
NewSyncSessionSignal_t m_newSyncSessionSignal; NewSyncSessionSignal_t m_newSyncSessionSignal;
/** /**
* look up client by its ID * look up client by its ID
*/ */
boost::shared_ptr<Client> findClient(const GDBusCXX::Caller_t &ID); std::shared_ptr<Client> findClient(const GDBusCXX::Caller_t &ID);
/** /**
* find client by its ID or create one anew * find client by its ID or create one anew
*/ */
boost::shared_ptr<Client> addClient(const GDBusCXX::Caller_t &ID, std::shared_ptr<Client> addClient(const GDBusCXX::Caller_t &ID,
const boost::shared_ptr<GDBusCXX::Watch> &watch); const std::shared_ptr<GDBusCXX::Watch> &watch);
/** detach this resource from all clients which own it */ /** detach this resource from all clients which own it */
void detach(Resource *resource); void detach(Resource *resource);
@ -479,7 +461,7 @@ public:
* by the creator of the session, *after* the session is * by the creator of the session, *after* the session is
* ready to run. * ready to run.
*/ */
void enqueue(const boost::shared_ptr<Session> &session); void enqueue(const std::shared_ptr<Session> &session);
/** /**
* Remove all sessions with this device ID from the * Remove all sessions with this device ID from the
@ -535,21 +517,21 @@ public:
* session. Once the timeout fires, it is called and then removed, * session. Once the timeout fires, it is called and then removed,
* which removes the reference. * which removes the reference.
*/ */
void delaySessionDestruction(const boost::shared_ptr<Session> &session); void delaySessionDestruction(const std::shared_ptr<Session> &session);
/** /**
* Works for any kind of object: keep shared pointer until the * Works for any kind of object: keep shared pointer until the
* event loop is idle, then unref it inside. Useful for instances * event loop is idle, then unref it inside. Useful for instances
* which need to delete themselves. * which need to delete themselves.
*/ */
template <class T> void delayDeletion(const boost::shared_ptr<T> &t) { template <class T> void delayDeletion(const std::shared_ptr<T> &t) {
// The functor will never be called, important here is only // The functor will never be called, important here is only
// that it contains a copy of the shared pointer. // that it contains a copy of the shared pointer.
m_delayDeletion.push_back(boost::bind(delayDeletionDummy<T>, t)); m_delayDeletion.push_back([t] () {});
g_idle_add(&Server::delayDeletionCb, this); g_idle_add(&Server::delayDeletionCb, this);
} }
template <class T> static void delayDeletionDummy(const boost::shared_ptr<T> &t) throw () {} template <class T> static void delayDeletionDummy(const std::shared_ptr<T> &t) throw () {}
static gboolean delayDeletionCb(gpointer userData) throw () { static gboolean delayDeletionCb(gpointer userData) throw () {
Server *me = static_cast<Server *>(userData); Server *me = static_cast<Server *>(userData);
@ -571,13 +553,13 @@ public:
* caller must do that or the request will automatically be * caller must do that or the request will automatically be
* deleted. * deleted.
*/ */
boost::shared_ptr<InfoReq> passwordRequest(const std::string &descr, std::shared_ptr<InfoReq> passwordRequest(const std::string &descr,
const ConfigPasswordKey &key, const ConfigPasswordKey &key,
const boost::weak_ptr<Session> &session); const std::weak_ptr<Session> &session);
/** got response for earlier request, need to extract password and tell session */ /** got response for earlier request, need to extract password and tell session */
void passwordResponse(const StringMap &response, void passwordResponse(const StringMap &response,
const boost::weak_ptr<Session> &session); const std::weak_ptr<Session> &session);
/** /**
* Invokes the given callback once in the given amount of seconds. * Invokes the given callback once in the given amount of seconds.
@ -585,7 +567,7 @@ public:
* before that time, then the callback will be deleted without * before that time, then the callback will be deleted without
* being called. * being called.
*/ */
void addTimeout(const boost::function<void ()> &callback, void addTimeout(const std::function<void ()> &callback,
int seconds); int seconds);
/** /**
@ -594,7 +576,7 @@ public:
* calling removeInfoReq() when the request becomes obsolete * calling removeInfoReq() when the request becomes obsolete
* sooner than that. * sooner than that.
*/ */
boost::shared_ptr<InfoReq> createInfoReq(const string &type, std::shared_ptr<InfoReq> createInfoReq(const string &type,
const std::map<string, string> &parameters, const std::map<string, string> &parameters,
const Session &session); const Session &session);
void autoTermRef(int counts = 1) { m_autoTerm.ref(counts); } void autoTermRef(int counts = 1) { m_autoTerm.ref(counts); }
@ -610,9 +592,9 @@ public:
PresenceStatus& getPresenceStatus(); PresenceStatus& getPresenceStatus();
void clearPeerTempls() { m_matchedTempls.clear(); } void clearPeerTempls() { m_matchedTempls.clear(); }
void addPeerTempl(const string &templName, const boost::shared_ptr<SyncConfig::TemplateDescription> peerTempl); void addPeerTempl(const string &templName, const std::shared_ptr<SyncConfig::TemplateDescription> &peerTempl);
boost::shared_ptr<SyncConfig::TemplateDescription> getPeerTempl(const string &peer); std::shared_ptr<SyncConfig::TemplateDescription> getPeerTempl(const string &peer);
/** /**
* methods to operate device list. See DeviceList definition. * methods to operate device list. See DeviceList definition.
@ -671,7 +653,7 @@ public:
// extensions to the D-Bus server, created dynamically by main() // extensions to the D-Bus server, created dynamically by main()
#ifdef ENABLE_DBUS_PIM #ifdef ENABLE_DBUS_PIM
boost::shared_ptr<GDBusCXX::DBusObjectHelper> CreateContactManager(const boost::shared_ptr<Server> &server, bool start); std::shared_ptr<GDBusCXX::DBusObjectHelper> CreateContactManager(const std::shared_ptr<Server> &server, bool start);
#endif #endif
SE_END_CXX SE_END_CXX

View File

@ -28,11 +28,6 @@
SE_BEGIN_CXX SE_BEGIN_CXX
static void dumpString(const std::string &output)
{
fputs(output.c_str(), stdout);
}
/** /**
* Same logging approach as in Server class: pretend that we * Same logging approach as in Server class: pretend that we
* have reference counting for the SessionHelper class and * have reference counting for the SessionHelper class and
@ -41,11 +36,11 @@ static void dumpString(const std::string &output)
class SessionHelperLogger : public Logger class SessionHelperLogger : public Logger
{ {
Handle m_parentLogger; Handle m_parentLogger;
boost::shared_ptr<SessionHelper> m_helper; std::shared_ptr<SessionHelper> m_helper;
Level m_dbusLogLevel; Level m_dbusLogLevel;
public: public:
SessionHelperLogger(const boost::shared_ptr<SessionHelper> &helper): SessionHelperLogger(const std::shared_ptr<SessionHelper> &helper):
m_parentLogger(Logger::instance()), m_parentLogger(Logger::instance()),
m_helper(helper), m_helper(helper),
m_dbusLogLevel(DEBUG) m_dbusLogLevel(DEBUG)
@ -87,7 +82,9 @@ public:
options.m_processName, options.m_processName,
options.m_prefix, options.m_prefix,
format, argsCopy, format, argsCopy,
boost::bind(dumpString, _1)); [] (const std::string &output, size_t expectedTotal) {
fputs(output.c_str(), stdout);
});
} }
va_end(argsCopy); va_end(argsCopy);
} else if (m_parentLogger) { } else if (m_parentLogger) {
@ -126,7 +123,7 @@ public:
SessionHelper::SessionHelper(GMainLoop *loop, SessionHelper::SessionHelper(GMainLoop *loop,
const GDBusCXX::DBusConnectionPtr &conn, const GDBusCXX::DBusConnectionPtr &conn,
const boost::shared_ptr<ForkExecChild> &forkexec) : const std::shared_ptr<ForkExecChild> &forkexec) :
GDBusCXX::DBusObjectHelper(conn, GDBusCXX::DBusObjectHelper(conn,
std::string(SessionCommon::HELPER_PATH) + "/" + forkexec->getInstance(), std::string(SessionCommon::HELPER_PATH) + "/" + forkexec->getInstance(),
SessionCommon::HELPER_IFACE, SessionCommon::HELPER_IFACE,
@ -135,7 +132,7 @@ SessionHelper::SessionHelper(GMainLoop *loop,
m_loop(loop), m_loop(loop),
m_conn(conn), m_conn(conn),
m_forkexec(forkexec), m_forkexec(forkexec),
m_logger(new SessionHelperLogger(boost::shared_ptr<SessionHelper>(this, NopDestructor()))), m_logger(new SessionHelperLogger(std::shared_ptr<SessionHelper>(this, NopDestructor()))),
emitLogOutput(*this, "LogOutput"), emitLogOutput(*this, "LogOutput"),
emitSyncProgress(*this, "SyncProgress"), emitSyncProgress(*this, "SyncProgress"),
emitSourceProgress(*this, "SourceProgress"), emitSourceProgress(*this, "SourceProgress"),
@ -210,15 +207,17 @@ bool SessionHelper::connected()
return m_forkexec && m_forkexec->getState() == ForkExecChild::CONNECTED; return m_forkexec && m_forkexec->getState() == ForkExecChild::CONNECTED;
} }
// TODO: the common wrapper code (i.e. sync/restore/execute) could be moved into a template function...
void SessionHelper::sync(const SessionCommon::SyncParams &params, void SessionHelper::sync(const SessionCommon::SyncParams &params,
const boost::shared_ptr< GDBusCXX::Result<bool, SyncReport> > &result) const std::shared_ptr< GDBusCXX::Result<bool, SyncReport> > &result)
{ {
m_operation = boost::bind(&SessionHelper::doSync, this, params, result); m_operation = [this, params, result] () { return doSync(params, result); };
g_main_loop_quit(m_loop); g_main_loop_quit(m_loop);
} }
bool SessionHelper::doSync(const SessionCommon::SyncParams &params, bool SessionHelper::doSync(const SessionCommon::SyncParams &params,
const boost::shared_ptr< GDBusCXX::Result<bool, SyncReport> > &result) const std::shared_ptr< GDBusCXX::Result<bool, SyncReport> > &result)
{ {
try { try {
m_sync.reset(new DBusSync(params, *this)); m_sync.reset(new DBusSync(params, *this));
@ -245,15 +244,15 @@ bool SessionHelper::doSync(const SessionCommon::SyncParams &params,
void SessionHelper::restore(const std::string &configName, void SessionHelper::restore(const std::string &configName,
const string &dir, bool before, const std::vector<std::string> &sources, const string &dir, bool before, const std::vector<std::string> &sources,
const boost::shared_ptr< GDBusCXX::Result<bool> > &result) const std::shared_ptr< GDBusCXX::Result<bool> > &result)
{ {
m_operation = boost::bind(&SessionHelper::doRestore, this, configName, dir, before, sources, result); m_operation = [this, configName, dir, before, sources, result] () { return doRestore(configName, dir, before, sources, result); };
g_main_loop_quit(m_loop); g_main_loop_quit(m_loop);
} }
bool SessionHelper::doRestore(const std::string &configName, bool SessionHelper::doRestore(const std::string &configName,
const string &dir, bool before, const std::vector<std::string> &sources, const string &dir, bool before, const std::vector<std::string> &sources,
const boost::shared_ptr< GDBusCXX::Result<bool> > &result) const std::shared_ptr< GDBusCXX::Result<bool> > &result)
{ {
try { try {
SessionCommon::SyncParams params; SessionCommon::SyncParams params;
@ -285,14 +284,14 @@ bool SessionHelper::doRestore(const std::string &configName,
void SessionHelper::execute(const vector<string> &args, const map<string, string> &vars, void SessionHelper::execute(const vector<string> &args, const map<string, string> &vars,
const boost::shared_ptr< GDBusCXX::Result<bool> > &result) const std::shared_ptr< GDBusCXX::Result<bool> > &result)
{ {
m_operation = boost::bind(&SessionHelper::doExecute, this, args, vars, result); m_operation = [this, args, vars, result] () { return doExecute(args, vars, result); };
g_main_loop_quit(m_loop); g_main_loop_quit(m_loop);
} }
bool SessionHelper::doExecute(const vector<string> &args, const map<string, string> &vars, bool SessionHelper::doExecute(const vector<string> &args, const map<string, string> &vars,
const boost::shared_ptr< GDBusCXX::Result<bool> > &result) const std::shared_ptr< GDBusCXX::Result<bool> > &result)
{ {
try { try {
CmdlineWrapper cmdline(*this, args, vars); CmdlineWrapper cmdline(*this, args, vars);

View File

@ -24,10 +24,10 @@
#include "dbus-sync.h" #include "dbus-sync.h"
#include <gdbus-cxx-bridge.h> #include <gdbus-cxx-bridge.h>
#include <boost/function.hpp>
#include <glib.h> #include <glib.h>
#include <boost/shared_ptr.hpp> #include <memory>
#include <functional>
#include <syncevo/declarations.h> #include <syncevo/declarations.h>
SE_BEGIN_CXX SE_BEGIN_CXX
@ -48,9 +48,9 @@ class SessionHelper : public GDBusCXX::DBusObjectHelper,
{ {
GMainLoop *m_loop; GMainLoop *m_loop;
GDBusCXX::DBusConnectionPtr m_conn; GDBusCXX::DBusConnectionPtr m_conn;
boost::shared_ptr<ForkExecChild> m_forkexec; std::shared_ptr<ForkExecChild> m_forkexec;
boost::function<bool ()> m_operation; std::function<bool ()> m_operation;
boost::shared_ptr<SessionHelperLogger> m_logger; std::shared_ptr<SessionHelperLogger> m_logger;
PushLogger<Logger> m_pushLogger; PushLogger<Logger> m_pushLogger;
/** valid during doSync() */ /** valid during doSync() */
@ -58,26 +58,26 @@ class SessionHelper : public GDBusCXX::DBusObjectHelper,
/** called by main event loop: initiate a sync operation */ /** called by main event loop: initiate a sync operation */
void sync(const SessionCommon::SyncParams &params, void sync(const SessionCommon::SyncParams &params,
const boost::shared_ptr< GDBusCXX::Result<bool, SyncReport> > &result); const std::shared_ptr< GDBusCXX::Result<bool, SyncReport> > &result);
/** /**
* called by run(): do the sync operation * called by run(): do the sync operation
* @return true if the helper is meant to terminate * @return true if the helper is meant to terminate
*/ */
bool doSync(const SessionCommon::SyncParams &params, bool doSync(const SessionCommon::SyncParams &params,
const boost::shared_ptr< GDBusCXX::Result<bool, SyncReport> > &result); const std::shared_ptr< GDBusCXX::Result<bool, SyncReport> > &result);
void restore(const std::string &configName, void restore(const std::string &configName,
const string &dir, bool before, const std::vector<std::string> &sources, const string &dir, bool before, const std::vector<std::string> &sources,
const boost::shared_ptr< GDBusCXX::Result<bool> > &result); const std::shared_ptr< GDBusCXX::Result<bool> > &result);
bool doRestore(const std::string &configName, bool doRestore(const std::string &configName,
const string &dir, bool before, const std::vector<std::string> &sources, const string &dir, bool before, const std::vector<std::string> &sources,
const boost::shared_ptr< GDBusCXX::Result<bool> > &result); const std::shared_ptr< GDBusCXX::Result<bool> > &result);
void execute(const vector<string> &args, const map<string, string> &vars, void execute(const vector<string> &args, const map<string, string> &vars,
const boost::shared_ptr< GDBusCXX::Result<bool> > &result); const std::shared_ptr< GDBusCXX::Result<bool> > &result);
bool doExecute(const vector<string> &args, const map<string, string> &vars, bool doExecute(const vector<string> &args, const map<string, string> &vars,
const boost::shared_ptr< GDBusCXX::Result<bool> > &result); const std::shared_ptr< GDBusCXX::Result<bool> > &result);
/** SessionHelper.PasswordResponse */ /** SessionHelper.PasswordResponse */
void passwordResponse(bool timedOut, bool aborted, const std::string &password); void passwordResponse(bool timedOut, bool aborted, const std::string &password);
@ -88,7 +88,7 @@ class SessionHelper : public GDBusCXX::DBusObjectHelper,
public: public:
SessionHelper(GMainLoop *loop, SessionHelper(GMainLoop *loop,
const GDBusCXX::DBusConnectionPtr &conn, const GDBusCXX::DBusConnectionPtr &conn,
const boost::shared_ptr<ForkExecChild> &forkexec); const std::shared_ptr<ForkExecChild> &forkexec);
~SessionHelper(); ~SessionHelper();
void setDBusLogLevel(Logger::Level level); void setDBusLogLevel(Logger::Level level);
@ -101,7 +101,7 @@ class SessionHelper : public GDBusCXX::DBusObjectHelper,
/** Still have connection to parent. Shortcut which asks the ForkExecChild class. */ /** Still have connection to parent. Shortcut which asks the ForkExecChild class. */
bool connected(); bool connected();
boost::shared_ptr<ForkExecChild> getForkExecChild() { return m_forkexec; } std::shared_ptr<ForkExecChild> getForkExecChild() { return m_forkexec; }
/** Server.LogOutput for the session D-Bus object */ /** Server.LogOutput for the session D-Bus object */
GDBusCXX::EmitSignalOptional<std::string, GDBusCXX::EmitSignalOptional<std::string,

View File

@ -120,20 +120,17 @@ public:
void Session::attach(const Caller_t &caller) void Session::attach(const Caller_t &caller)
{ {
boost::shared_ptr<Client> client(m_server.findClient(caller)); std::shared_ptr<Client> client(m_server.findClient(caller));
if (!client) { if (!client) {
throw runtime_error("unknown client"); throw runtime_error("unknown client");
} }
boost::shared_ptr<Session> me = m_me.lock(); std::shared_ptr<Session> me = shared_from_this();
if (!me) {
throw runtime_error("session already deleted?!");
}
client->attach(me); client->attach(me);
} }
void Session::detach(const Caller_t &caller) void Session::detach(const Caller_t &caller)
{ {
boost::shared_ptr<Client> client(m_server.findClient(caller)); std::shared_ptr<Client> client(m_server.findClient(caller));
if (!client) { if (!client) {
throw runtime_error("unknown client"); throw runtime_error("unknown client");
} }
@ -206,7 +203,7 @@ void Session::setNamedConfig(const std::string &configName,
bool update, bool temporary, bool update, bool temporary,
const ReadOperations::Config_t &config) const ReadOperations::Config_t &config)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
if (m_runOperation != SessionCommon::OP_NULL) { if (m_runOperation != SessionCommon::OP_NULL) {
string msg = StringPrintf("%s started, cannot change configuration at this time", runOpToString(m_runOperation).c_str()); string msg = StringPrintf("%s started, cannot change configuration at this time", runOpToString(m_runOperation).c_str());
SE_THROW_EXCEPTION(InvalidCall, msg); SE_THROW_EXCEPTION(InvalidCall, msg);
@ -237,7 +234,7 @@ void Session::setNamedConfig(const std::string &configName,
m_server.getPresenceStatus().updateConfigPeers (configName, config); m_server.getPresenceStatus().updateConfigPeers (configName, config);
/** check whether we need remove the entire configuration */ /** check whether we need remove the entire configuration */
if(!update && !temporary && config.empty()) { if(!update && !temporary && config.empty()) {
boost::shared_ptr<SyncConfig> syncConfig(new SyncConfig(configName)); auto syncConfig = std::make_shared<SyncConfig>(configName);
if(syncConfig.get()) { if(syncConfig.get()) {
syncConfig->remove(); syncConfig->remove();
m_setConfig = true; m_setConfig = true;
@ -275,7 +272,7 @@ void Session::setNamedConfig(const std::string &configName,
m_tempConfig = true; m_tempConfig = true;
} else { } else {
/* need to save configurations */ /* need to save configurations */
boost::shared_ptr<SyncConfig> from(new SyncConfig(configName)); auto from = std::make_shared<SyncConfig>(configName);
/* if it is not clear mode and config does not exist, an error throws */ /* if it is not clear mode and config does not exist, an error throws */
if(update && !from->exists()) { if(update && !from->exists()) {
SE_THROW_EXCEPTION(NoSuchConfig, "The configuration '" + configName + "' doesn't exist" ); SE_THROW_EXCEPTION(NoSuchConfig, "The configuration '" + configName + "' doesn't exist" );
@ -313,7 +310,7 @@ void Session::setNamedConfig(const std::string &configName,
// We need no interactive user interface, but we do need to handle // We need no interactive user interface, but we do need to handle
// storing passwords in a keyring here. // storing passwords in a keyring here.
boost::shared_ptr<SyncContext> syncConfig(new SyncContext(configName)); auto syncConfig = std::make_shared<SyncContext>(configName);
syncConfig->prepareConfigForWrite(); syncConfig->prepareConfigForWrite();
syncConfig->copy(*from, NULL); syncConfig->copy(*from, NULL);
@ -349,7 +346,7 @@ void Session::setNamedConfig(const std::string &configName,
void Session::initServer(SharedBuffer data, const std::string &messageType) void Session::initServer(SharedBuffer data, const std::string &messageType)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
m_serverMode = true; m_serverMode = true;
m_initialMessage = data; m_initialMessage = data;
m_initialMessageType = messageType; m_initialMessageType = messageType;
@ -358,7 +355,7 @@ void Session::initServer(SharedBuffer data, const std::string &messageType)
void Session::syncExtended(const std::string &mode, const SessionCommon::SourceModes_t &sourceModes, void Session::syncExtended(const std::string &mode, const SessionCommon::SourceModes_t &sourceModes,
const StringMap &env) const StringMap &env)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
if (m_runOperation == SessionCommon::OP_SYNC) { if (m_runOperation == SessionCommon::OP_SYNC) {
string msg = StringPrintf("%s started, cannot start again", runOpToString(m_runOperation).c_str()); string msg = StringPrintf("%s started, cannot start again", runOpToString(m_runOperation).c_str());
SE_THROW_EXCEPTION(InvalidCall, msg); SE_THROW_EXCEPTION(InvalidCall, msg);
@ -377,13 +374,13 @@ void Session::syncExtended(const std::string &mode, const SessionCommon::SourceM
// caller. Starting the helper (if needed) and making it // caller. Starting the helper (if needed) and making it
// execute the sync is part of "running sync". // execute the sync is part of "running sync".
runOperationAsync(SessionCommon::OP_SYNC, runOperationAsync(SessionCommon::OP_SYNC,
boost::bind(&Session::sync2, this, mode, sourceModes), [this, mode, sourceModes] () { sync2(mode, sourceModes); },
env); env);
} }
void Session::sync2(const std::string &mode, const SessionCommon::SourceModes_t &sourceModes) void Session::sync2(const std::string &mode, const SessionCommon::SourceModes_t &sourceModes)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
if (!m_forkExecParent || !m_helper) { if (!m_forkExecParent || !m_helper) {
SE_THROW("syncing cannot continue, helper died"); SE_THROW("syncing cannot continue, helper died");
} }
@ -403,7 +400,7 @@ void Session::sync2(const std::string &mode, const SessionCommon::SourceModes_t
params.m_sourceFilter = m_sourceFilter; params.m_sourceFilter = m_sourceFilter;
params.m_sourceFilters = m_sourceFilters; params.m_sourceFilters = m_sourceFilters;
boost::shared_ptr<Connection> c = m_connection.lock(); std::shared_ptr<Connection> c = m_connection.lock();
if (c && !c->mustAuthenticate()) { if (c && !c->mustAuthenticate()) {
// unsetting username/password disables checking them // unsetting username/password disables checking them
params.m_syncFilter["password"] = InitStateString("", true); params.m_syncFilter["password"] = InitStateString("", true);
@ -421,19 +418,52 @@ void Session::sync2(const std::string &mode, const SessionCommon::SourceModes_t
// //
// Session might quit before connection, so use instance // Session might quit before connection, so use instance
// tracking. // tracking.
m_helper->m_sendMessage.activate(boost::bind(&Session::sendViaConnection, auto sendViaConnection = [this] (const DBusArray<uint8_t> buffer,
this, const std::string &type,
_1, _2, _3)); const std::string &url) {
m_helper->m_shutdownConnection.activate(boost::bind(&Session::shutdownConnection, PushLogger<Logger> guard(weak_from_this());
this)); try {
boost::shared_ptr<Connection> connection = m_connection.lock(); std::shared_ptr<Connection> connection = m_connection.lock();
if (!connection) {
SE_THROW_EXCEPTION(TransportException,
"D-Bus peer has disconnected");
}
connection->send(buffer, type, url);
} catch (...) {
std::string explanation;
Exception::handle(explanation);
connectionState(explanation);
}
};
m_helper->m_sendMessage.activate(sendViaConnection);
auto shutdownConnection = [this] () {
PushLogger<Logger> guard(weak_from_this());
try {
std::shared_ptr<Connection> connection = m_connection.lock();
if (!connection) {
SE_THROW_EXCEPTION(TransportException,
"D-Bus peer has disconnected");
}
connection->sendFinalMsg();
} catch (...) {
std::string explanation;
Exception::handle(explanation);
connectionState(explanation);
}
};
m_helper->m_shutdownConnection.activate(shutdownConnection);
std::shared_ptr<Connection> connection = m_connection.lock();
if (connection) { if (connection) {
connection->m_messageSignal.connect(Connection::MessageSignal_t::slot_type(&Session::storeMessage, connection->m_messageSignal.connect(Connection::MessageSignal_t::slot_type(&Session::storeMessage,
this, this,
_1, _2).track(m_me)); _1, _2).track_foreign(weak_from_this()));
connection->m_statusSignal.connect(Connection::StatusSignal_t::slot_type(&Session::connectionState, connection->m_statusSignal.connect(Connection::StatusSignal_t::slot_type(&Session::connectionState,
this, this,
_1)); _1).track_foreign(weak_from_this()));
} }
// Helper implements Sync() asynchronously. If it completes // Helper implements Sync() asynchronously. If it completes
@ -441,13 +471,15 @@ void Session::sync2(const std::string &mode, const SessionCommon::SourceModes_t
// the error is recorded before ending the session. Premature // the error is recorded before ending the session. Premature
// exits by the helper are handled by D-Bus, which then will abort // exits by the helper are handled by D-Bus, which then will abort
// the pending method call. // the pending method call.
m_helper->m_sync.start(boost::bind(&Session::dbusResultCb, m_me, "sync()", _1, _2, _3), m_helper->m_sync.start([me = weak_from_this()] (bool success, const SyncReport &report, const std::string &error) {
dbusResultCb(me, "sync()", success, report, error);
},
params); params);
} }
void Session::abort() void Session::abort()
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
if (m_runOperation != SessionCommon::OP_SYNC && m_runOperation != SessionCommon::OP_CMDLINE) { if (m_runOperation != SessionCommon::OP_SYNC && m_runOperation != SessionCommon::OP_CMDLINE) {
SE_THROW_EXCEPTION(InvalidCall, "sync not started, cannot abort at this time"); SE_THROW_EXCEPTION(InvalidCall, "sync not started, cannot abort at this time");
} }
@ -468,29 +500,18 @@ void Session::abort()
void Session::setFreezeAsync(bool freeze, const Result<void (bool)> &result) void Session::setFreezeAsync(bool freeze, const Result<void (bool)> &result)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
SE_LOG_DEBUG(NULL, "session %s: SetFreeze(%s), %s", SE_LOG_DEBUG(NULL, "session %s: SetFreeze(%s), %s",
getPath(), getPath(),
freeze ? "freeze" : "thaw", freeze ? "freeze" : "thaw",
m_forkExecParent ? "send to helper" : "no effect, because no helper"); m_forkExecParent ? "send to helper" : "no effect, because no helper");
if (m_forkExecParent) { if (m_forkExecParent) {
m_helper->m_setFreeze.start(boost::bind(&Session::setFreezeDone, auto done = [this, me = weak_from_this(), freeze, result] (bool changed, const std::string &error) noexcept {
m_me, auto lock = me.lock();
_1, _2, if (!lock) {
freeze, return;
result),
freeze);
} else {
// Had no effect.
result.done(false);
} }
} PushLogger<Logger> guard(weak_from_this());
void Session::setFreezeDone(bool changed, const std::string &error,
bool freeze,
const Result<void (bool)> &result)
{
PushLogger<Logger> guard(m_me);
try { try {
SE_LOG_DEBUG(NULL, "session %s: SetFreeze(%s) returned from helper %s, error %s", SE_LOG_DEBUG(NULL, "session %s: SetFreeze(%s) returned from helper %s, error %s",
getPath(), getPath(),
@ -507,11 +528,17 @@ void Session::setFreezeDone(bool changed, const std::string &error,
} catch (...) { } catch (...) {
result.failed(); result.failed();
} }
};
m_helper->m_setFreeze.start(done, freeze);
} else {
// Had no effect.
result.done(false);
}
} }
void Session::suspend() void Session::suspend()
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
if (m_runOperation != SessionCommon::OP_SYNC && m_runOperation != SessionCommon::OP_CMDLINE) { if (m_runOperation != SessionCommon::OP_SYNC && m_runOperation != SessionCommon::OP_CMDLINE) {
SE_THROW_EXCEPTION(InvalidCall, "sync not started, cannot suspend at this time"); SE_THROW_EXCEPTION(InvalidCall, "sync not started, cannot suspend at this time");
} }
@ -528,7 +555,7 @@ void Session::suspend()
void Session::abortAsync(const SimpleResult &result) void Session::abortAsync(const SimpleResult &result)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
if (!m_forkExecParent) { if (!m_forkExecParent) {
result.done(); result.done();
} else { } else {
@ -537,7 +564,7 @@ void Session::abortAsync(const SimpleResult &result)
// This must succeed; there is no timeout or failure mode. // This must succeed; there is no timeout or failure mode.
// TODO: kill helper after a certain amount of time?! // TODO: kill helper after a certain amount of time?!
m_forkExecParent->stop(SIGTERM); m_forkExecParent->stop(SIGTERM);
m_forkExecParent->m_onQuit.connect(boost::bind(&SimpleResult::done, result)); m_forkExecParent->m_onQuit.connect([result] (int) { result.done(); });
} }
} }
@ -545,7 +572,7 @@ void Session::getStatus(std::string &status,
uint32_t &error, uint32_t &error,
SourceStatuses_t &sources) SourceStatuses_t &sources)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
status = syncStatusToString(m_syncStatus); status = syncStatusToString(m_syncStatus);
if (m_stepIsWaiting) { if (m_stepIsWaiting) {
status += ";waiting"; status += ";waiting";
@ -558,7 +585,7 @@ void Session::getStatus(std::string &status,
void Session::getAPIProgress(int32_t &progress, void Session::getAPIProgress(int32_t &progress,
APISourceProgresses_t &sources) APISourceProgresses_t &sources)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
progress = m_progData.getProgress(); progress = m_progData.getProgress();
sources = m_sourceProgress; sources = m_sourceProgress;
} }
@ -566,7 +593,7 @@ void Session::getAPIProgress(int32_t &progress,
void Session::getProgress(int32_t &progress, void Session::getProgress(int32_t &progress,
SourceProgresses_t &sources) SourceProgresses_t &sources)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
progress = m_progData.getProgress(); progress = m_progData.getProgress();
sources = m_sourceProgress; sources = m_sourceProgress;
} }
@ -584,7 +611,7 @@ bool Session::getSyncSourceReport(const std::string &sourceName, SyncSourceRepor
void Session::fireStatus(bool flush) void Session::fireStatus(bool flush)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
std::string status; std::string status;
uint32_t error; uint32_t error;
SourceStatuses_t sources; SourceStatuses_t sources;
@ -601,7 +628,7 @@ void Session::fireStatus(bool flush)
void Session::fireProgress(bool flush) void Session::fireProgress(bool flush)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
int32_t progress; int32_t progress;
SourceProgresses_t sources; SourceProgresses_t sources;
@ -615,22 +642,6 @@ void Session::fireProgress(bool flush)
m_progressSignal(progress, sources); m_progressSignal(progress, sources);
} }
boost::shared_ptr<Session> Session::createSession(Server &server,
const std::string &peerDeviceID,
const std::string &config_name,
const std::string &session,
const std::vector<std::string> &flags)
{
boost::shared_ptr<Session> me(new Session(server, peerDeviceID, config_name, session, flags));
me->m_me = me;
return me;
}
static void SetProgress(Session::SourceProgresses_t &to, const Session::SourceProgresses_t &from)
{
to = from;
}
Session::Session(Server &server, Session::Session(Server &server,
const std::string &peerDeviceID, const std::string &peerDeviceID,
const std::string &config_name, const std::string &config_name,
@ -639,7 +650,7 @@ Session::Session(Server &server,
DBusObjectHelper(server.getConnection(), DBusObjectHelper(server.getConnection(),
std::string("/org/syncevolution/Session/") + session, std::string("/org/syncevolution/Session/") + session,
"org.syncevolution.Session", "org.syncevolution.Session",
boost::bind(&Server::autoTermCallback, &server)), [serverPtr = &server] () { serverPtr->autoTermCallback(); }),
ReadOperations(config_name, server), ReadOperations(config_name, server),
m_flags(flags), m_flags(flags),
m_sessionID(session), m_sessionID(session),
@ -689,23 +700,30 @@ Session::Session(Server &server,
add(this, &Session::execute, "Execute"); add(this, &Session::execute, "Execute");
add(emitStatus); add(emitStatus);
add(emitProgress); add(emitProgress);
m_statusSignal.connect(boost::bind(boost::ref(emitStatus), _1, _2, _3)); auto status = [this] (const std::string &status,
m_progressSignal.connect(boost::bind(&Timespec::resetMonotonic, &m_lastProgressTimestamp)); uint32_t error,
m_progressSignal.connect(boost::bind(SetProgress, boost::ref(m_lastProgress), _2)); const SourceStatuses_t &sources) {
m_progressSignal.connect(boost::bind(boost::ref(emitProgress), _1, _2)); emitStatus(status, error, sources);
};
m_statusSignal.connect(status);
auto progress = [this] (int32_t progress,
const SourceProgresses_t &sources) {
m_lastProgressTimestamp.resetMonotonic();
m_lastProgress = sources;
emitProgress(progress, sources);
};
m_progressSignal.connect(progress);
SE_LOG_DEBUG(NULL, "session %s created", getPath()); SE_LOG_DEBUG(NULL, "session %s created", getPath());
} }
void Session::passwordRequest(const std::string &descr, const ConfigPasswordKey &key) void Session::dbusResultCb(const std::weak_ptr<Session> &me, const std::string &operation, bool success, const SyncReport &report, const std::string &error) noexcept
{ {
PushLogger<Logger> guard(m_me); auto lock = me.lock();
m_passwordRequest = m_server.passwordRequest(descr, key, m_me); if (!lock) {
return;
} }
PushLogger<Logger> guard(me);
void Session::dbusResultCb(const std::string &operation, bool success, const SyncReport &report, const std::string &error) throw()
{
PushLogger<Logger> guard(m_me);
try { try {
SE_LOG_DEBUG(NULL, "%s helper call completed, %s", SE_LOG_DEBUG(NULL, "%s helper call completed, %s",
operation.c_str(), operation.c_str(),
@ -713,7 +731,7 @@ void Session::dbusResultCb(const std::string &operation, bool success, const Syn
success ? "<<successfully>>" : success ? "<<successfully>>" :
"<<unsuccessfully>>"); "<<unsuccessfully>>");
if (error.empty()) { if (error.empty()) {
doneCb(success, report); lock->doneCb(false, success, report);
} else { } else {
// Translate back into local exception, will be handled by // Translate back into local exception, will be handled by
// catch clause and (eventually) failureCb(). // catch clause and (eventually) failureCb().
@ -723,13 +741,13 @@ void Session::dbusResultCb(const std::string &operation, bool success, const Syn
error); error);
} }
} catch (...) { } catch (...) {
failureCb(); lock->failureCb();
} }
} }
void Session::failureCb() throw() void Session::failureCb() throw()
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
try { try {
if (m_status == SESSION_DONE) { if (m_status == SESSION_DONE) {
// ignore errors that happen after session already closed, // ignore errors that happen after session already closed,
@ -760,7 +778,7 @@ void Session::failureCb() throw()
m_error = error; m_error = error;
} }
// will fire status signal, including the error // will fire status signal, including the error
doneCb(false); doneCb(false, false);
} }
} catch (...) { } catch (...) {
// fatal problem, log it and terminate // fatal problem, log it and terminate
@ -768,9 +786,15 @@ void Session::failureCb() throw()
} }
} }
void Session::doneCb(bool success, const SyncReport &report) throw() void Session::doneCb(bool destruct, bool success, const SyncReport &report) noexcept
{ {
PushLogger<Logger> guard(m_me); // When called from our destructor, then weak_from_this() fails (__cxa_call_unexpected).
// We have to ignore logging in that case.
std::weak_ptr<Session> me;
if (!destruct) {
me = weak_from_this();
}
PushLogger<Logger> guard(me);
try { try {
if (m_status == SESSION_DONE) { if (m_status == SESSION_DONE) {
return; return;
@ -784,7 +808,7 @@ void Session::doneCb(bool success, const SyncReport &report) throw()
fireStatus(true); fireStatus(true);
boost::shared_ptr<Connection> connection = m_connection.lock(); std::shared_ptr<Connection> connection = m_connection.lock();
if (connection) { if (connection) {
connection->shutdown(); connection->shutdown();
} }
@ -823,38 +847,27 @@ Session::~Session()
{ {
SE_LOG_DEBUG(NULL, "session %s deconstructing", getPath()); SE_LOG_DEBUG(NULL, "session %s deconstructing", getPath());
// If we are not done yet, then something went wrong. // If we are not done yet, then something went wrong.
doneCb(false); doneCb(true, false);
}
/** child has quit before connecting, invoke result.failed() with suitable exception pending */
static void raiseChildTermError(int status, const SimpleResult &result)
{
try {
SE_THROW(StringPrintf("helper died unexpectedly with return code %d before connecting", status));
} catch (...) {
result.failed();
}
} }
void Session::runOperationAsync(SessionCommon::RunOperation op, void Session::runOperationAsync(SessionCommon::RunOperation op,
const SuccessCb_t &helperReady, const SuccessCb_t &helperReady,
const StringMap &env) const StringMap &env)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
m_server.addSyncSession(this); m_server.addSyncSession(this);
m_runOperation = op; m_runOperation = op;
m_status = SESSION_RUNNING; m_status = SESSION_RUNNING;
m_syncStatus = SYNC_RUNNING; m_syncStatus = SYNC_RUNNING;
fireStatus(true); fireStatus(true);
useHelperAsync(SimpleResult(helperReady, useHelperAsync(SimpleResult(helperReady, [this] () { failureCb(); }),
boost::bind(&Session::failureCb, this)),
env); env);
} }
void Session::useHelperAsync(const SimpleResult &result, const StringMap &env) void Session::useHelperAsync(const SimpleResult &result, const StringMap &env)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
try { try {
if (m_helper) { if (m_helper) {
// exists already, invoke callback directly // exists already, invoke callback directly
@ -871,7 +884,7 @@ void Session::useHelperAsync(const SimpleResult &result, const StringMap &env)
std::vector<std::string> args; std::vector<std::string> args;
args.push_back("--dbus-verbosity"); args.push_back("--dbus-verbosity");
args.push_back(StringPrintf("%d", m_server.getDBusLogLevel())); args.push_back(StringPrintf("%d", m_server.getDBusLogLevel()));
m_forkExecParent = SyncEvo::ForkExecParent::create("syncevo-dbus-helper", args); m_forkExecParent = make_weak_shared::make<ForkExecParent>("syncevo-dbus-helper", args);
#ifdef USE_DLT #ifdef USE_DLT
if (getenv("SYNCEVOLUTION_USE_DLT")) { if (getenv("SYNCEVOLUTION_USE_DLT")) {
m_forkExecParent->addEnvVar("SYNCEVOLUTION_USE_DLT", StringPrintf("%d", LoggerDLT::getCurrentDLTLogLevel())); m_forkExecParent->addEnvVar("SYNCEVOLUTION_USE_DLT", StringPrintf("%d", LoggerDLT::getCurrentDLTLogLevel()));
@ -887,9 +900,114 @@ void Session::useHelperAsync(const SimpleResult &result, const StringMap &env)
// m_forkExecParent -> no need for resource // m_forkExecParent -> no need for resource
// tracking. onConnect sets up m_helper. The other two // tracking. onConnect sets up m_helper. The other two
// only log the event. // only log the event.
m_forkExecParent->m_onConnect.connect(bind(&Session::onConnect, this, _1)); auto onConnect = [this] (const GDBusCXX::DBusConnectionPtr &conn) noexcept {
m_forkExecParent->m_onQuit.connect(boost::bind(&Session::onQuit, this, _1)); PushLogger<Logger> guard(weak_from_this());
m_forkExecParent->m_onFailure.connect(boost::bind(&Session::onFailure, this, _1, _2)); try {
std::string instance = m_forkExecParent->getInstance();
SE_LOG_DEBUG(NULL, "helper %s has connected", instance.c_str());
m_helper.reset(new SessionProxy(conn, instance));
// Activate signal watch on helper signals.
m_helper->m_syncProgress.activate([this] (sysync::TProgressEventEnum type,
int32_t extra1, int32_t extra2, int32_t extra3) {
syncProgress(type, extra1, extra2, extra3);
});
m_helper->m_sourceProgress.activate([this] (sysync::TProgressEventEnum type,
const std::string &sourceName,
SyncMode sourceSyncMode,
int32_t extra1, int32_t extra2, int32_t extra3) {
sourceProgress(type, sourceName, sourceSyncMode, extra1, extra2, extra3);
});
m_helper->m_sourceSynced.activate([this] (const std::string &name, const SyncSourceReport &report) {
m_sourceSynced(name, report);
});
m_sourceSynced.connect([this] (const std::string &name, const SyncSourceReport &report) {
m_syncSourceReports[name] = report;
});
auto setWaiting = [this] (bool isWaiting) {
PushLogger<Logger> guard(weak_from_this());
// if stepInfo doesn't change, then ignore it to avoid duplicate status info
if (m_stepIsWaiting != isWaiting) {
m_stepIsWaiting = isWaiting;
fireStatus(true);
}
};
m_helper->m_waiting.activate(setWaiting);
m_helper->m_syncSuccessStart.activate([this] () {
m_syncSuccessStartSignal();
});
m_helper->m_configChanged.activate([this] () {
m_server.m_configChangedSignal("");
});
auto passwordRequest = [this] (const std::string &descr, const ConfigPasswordKey &key) {
PushLogger<Logger> guard(weak_from_this());
m_passwordRequest = m_server.passwordRequest(descr, key, weak_from_this());
};
m_helper->m_passwordRequest.activate(passwordRequest);
} catch (...) {
Exception::handle();
}
};
auto onQuit = [this] (int status) noexcept {
PushLogger<Logger> guard(weak_from_this());
try {
SE_LOG_DEBUG(NULL, "helper quit with return code %d, was %s",
status,
m_wasAborted ? "aborted" : "not aborted");
if (m_status == SESSION_DONE) {
// don't care anymore whether the helper goes down, not an error
SE_LOG_DEBUG(NULL, "session already completed, ignore helper");
} else if (m_wasAborted &&
((WIFEXITED(status) && WEXITSTATUS(status) == 0) ||
(WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM))) {
SE_LOG_DEBUG(NULL, "helper terminated via SIGTERM, as expected");
if (!m_error) {
m_error = sysync::LOCERR_USERABORT;
SE_LOG_DEBUG(NULL, "helper was asked to quit -> error %d = LOCERR_USERABORT",
m_error);
}
} else {
// Premature exit from helper?! Not necessarily, it could
// be that we get the "helper has quit" signal from
// ForkExecParent before processing the helper's D-Bus
// method reply. So instead of recording an error here,
// wait for that reply. If the helper died without sending
// it, then D-Bus will generate a "connection lost" error
// for our pending method call.
//
// Except that libdbus does not deliver that error
// reliably. As a workaround, schedule closing the
// session as an idle callback, after that potential
// future method return call was handled. The assumption
// is that it is pending - it must be, because with the
// helper gone, IO with it must be ready. Just to be sure
// a small delay is used.
}
auto done = [me = weak_from_this()] () {
auto lock = me.lock();
if (lock) {
lock->doneCb(false, {});
}
};
m_server.addTimeout(done, 1 /* seconds */);
} catch (...) {
Exception::handle();
}
};
auto onFailure = [this] (SyncMLStatus status, const std::string &explanation) noexcept {
PushLogger<Logger> guard(weak_from_this());
try {
SE_LOG_DEBUG(NULL, "helper failed, status code %d = %s, %s",
status,
Status2String(status).c_str(),
explanation.c_str());
} catch (...) {
Exception::handle();
}
};
m_forkExecParent->m_onConnect.connect(onConnect);
m_forkExecParent->m_onQuit.connect(onQuit);
m_forkExecParent->m_onFailure.connect(onFailure);
if (!getenv("SYNCEVOLUTION_DEBUG")) { if (!getenv("SYNCEVOLUTION_DEBUG")) {
// Any output from the helper is unexpected and will be // Any output from the helper is unexpected and will be
@ -897,25 +1015,37 @@ void Session::useHelperAsync(const SimpleResult &result, const StringMap &env)
// stdout redirection once it runs, so anything that // stdout redirection once it runs, so anything that
// reaches us must have been problems during early process // reaches us must have been problems during early process
// startup or final shutdown. // startup or final shutdown.
m_forkExecParent->m_onOutput.connect(bind(&Session::onOutput, this, _1, _2)); auto onOutput = [this] (const char *buffer, size_t length) {
PushLogger<Logger> guard(weak_from_this());
// treat null-bytes inside the buffer like line breaks
size_t off = 0;
do {
SE_LOG_ERROR("session-helper", "%s", buffer + off);
off += strlen(buffer + off) + 1;
} while (off < length);
};
m_forkExecParent->m_onOutput.connect(onOutput);
} }
} }
// Now also connect result with the right events. Will be // Now also connect result with the right events. Will be
// called after setting up m_helper (first come, first // called after setting up m_helper (first come, first
// serve). We copy the "result" instance with boost::bind, and // serve). We copy the "result" instance with the closure, and
// the creator of it must have made sure that we can invoke it // the creator of it must have made sure that we can invoke it
// at any time without crashing. // at any time without crashing.
// //
// If the helper quits before connecting, the startup // If the helper quits before connecting, the startup
// failed. Need to remove that connection when successful. // failed. Need to remove that connection when successful.
boost::signals2::connection c = m_forkExecParent->m_onQuit.connect(boost::bind(&raiseChildTermError, auto raiseChildTermError = [result] (int status) noexcept {
_1, try {
result)); SE_THROW(StringPrintf("helper died unexpectedly with return code %d before connecting", status));
m_forkExecParent->m_onConnect.connect(boost::bind(&Session::useHelper2, } catch (...) {
this, result.failed();
result, }
c)); };
auto c = m_forkExecParent->m_onQuit.connect(raiseChildTermError);
m_forkExecParent->m_onConnect.connect([this, result, c] (const GDBusCXX::DBusConnectionPtr &) { useHelper2(result, c); });
if (m_forkExecParent->getState() == ForkExecParent::IDLE) { if (m_forkExecParent->getState() == ForkExecParent::IDLE) {
m_forkExecParent->start(); m_forkExecParent->start();
@ -980,7 +1110,7 @@ static void Logging2Server(Server &server,
void Session::useHelper2(const SimpleResult &result, const boost::signals2::connection &c) void Session::useHelper2(const SimpleResult &result, const boost::signals2::connection &c)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
try { try {
// helper is running, don't call result.failed() when it quits // helper is running, don't call result.failed() when it quits
// sometime in the future // sometime in the future
@ -1003,13 +1133,12 @@ void Session::useHelper2(const SimpleResult &result, const boost::signals2::conn
// The downside is that unrelated output (like // The downside is that unrelated output (like
// book-keeping messages about other clients) will also be // book-keeping messages about other clients) will also be
// captured. // captured.
m_helper->m_logOutput.activate(boost::bind(Logging2Server, m_helper->m_logOutput.activate([this] (const std::string &strLevel,
boost::ref(m_server), const std::string &explanation,
getPath(), const std::string &procname) {
_1, Logging2Server(m_server, getPath(),
_2, strLevel, explanation, procname);
_3)); });
result.done(); result.done();
} else { } else {
SE_THROW("internal error, helper not ready"); SE_THROW("internal error, helper not ready");
@ -1021,101 +1150,9 @@ void Session::useHelper2(const SimpleResult &result, const boost::signals2::conn
} }
} }
void Session::onConnect(const GDBusCXX::DBusConnectionPtr &conn) throw ()
{
PushLogger<Logger> guard(m_me);
try {
std::string instance = m_forkExecParent->getInstance();
SE_LOG_DEBUG(NULL, "helper %s has connected", instance.c_str());
m_helper.reset(new SessionProxy(conn, instance));
// Activate signal watch on helper signals.
m_helper->m_syncProgress.activate(boost::bind(&Session::syncProgress, this, _1, _2, _3, _4));
m_helper->m_sourceProgress.activate(boost::bind(&Session::sourceProgress, this, _1, _2, _3, _4, _5, _6));
m_helper->m_sourceSynced.activate(boost::bind(boost::ref(m_sourceSynced), _1, _2));
m_sourceSynced.connect(boost::bind(StoreSyncSourceReport, boost::ref(m_syncSourceReports), _1, _2));
m_helper->m_waiting.activate(boost::bind(&Session::setWaiting, this, _1));
m_helper->m_syncSuccessStart.activate(boost::bind(boost::ref(Session::m_syncSuccessStartSignal)));
m_helper->m_configChanged.activate(boost::bind(boost::ref(m_server.m_configChangedSignal), ""));
m_helper->m_passwordRequest.activate(boost::bind(&Session::passwordRequest, this, _1, _2));
} catch (...) {
Exception::handle();
}
}
void Session::onQuit(int status) throw ()
{
PushLogger<Logger> guard(m_me);
try {
SE_LOG_DEBUG(NULL, "helper quit with return code %d, was %s",
status,
m_wasAborted ? "aborted" : "not aborted");
if (m_status == SESSION_DONE) {
// don't care anymore whether the helper goes down, not an error
SE_LOG_DEBUG(NULL, "session already completed, ignore helper");
} else if (m_wasAborted &&
((WIFEXITED(status) && WEXITSTATUS(status) == 0) ||
(WIFSIGNALED(status) && WTERMSIG(status) == SIGTERM))) {
SE_LOG_DEBUG(NULL, "helper terminated via SIGTERM, as expected");
if (!m_error) {
m_error = sysync::LOCERR_USERABORT;
SE_LOG_DEBUG(NULL, "helper was asked to quit -> error %d = LOCERR_USERABORT",
m_error);
}
} else {
// Premature exit from helper?! Not necessarily, it could
// be that we get the "helper has quit" signal from
// ForkExecParent before processing the helper's D-Bus
// method reply. So instead of recording an error here,
// wait for that reply. If the helper died without sending
// it, then D-Bus will generate a "connection lost" error
// for our pending method call.
//
// Except that libdbus does not deliver that error
// reliably. As a workaround, schedule closing the
// session as an idle callback, after that potential
// future method return call was handled. The assumption
// is that it is pending - it must be, because with the
// helper gone, IO with it must be ready. Just to be sure
// a small delay is used.
}
m_server.addTimeout(boost::bind(&Session::doneCb,
m_me,
false,
SyncReport()),
1 /* seconds */);
} catch (...) {
Exception::handle();
}
}
void Session::onFailure(SyncMLStatus status, const std::string &explanation) throw ()
{
PushLogger<Logger> guard(m_me);
try {
SE_LOG_DEBUG(NULL, "helper failed, status code %d = %s, %s",
status,
Status2String(status).c_str(),
explanation.c_str());
} catch (...) {
Exception::handle();
}
}
void Session::onOutput(const char *buffer, size_t length)
{
PushLogger<Logger> guard(m_me);
// treat null-bytes inside the buffer like line breaks
size_t off = 0;
do {
SE_LOG_ERROR("session-helper", "%s", buffer + off);
off += strlen(buffer + off) + 1;
} while (off < length);
}
void Session::activateSession() void Session::activateSession()
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
if (m_status != SESSION_IDLE) { if (m_status != SESSION_IDLE) {
SE_THROW("internal error, session changing from non-idle to active"); SE_THROW("internal error, session changing from non-idle to active");
} }
@ -1126,7 +1163,7 @@ void Session::activateSession()
fireStatus(true); fireStatus(true);
} }
boost::shared_ptr<Connection> c = m_connection.lock(); std::shared_ptr<Connection> c = m_connection.lock();
if (c) { if (c) {
c->ready(); c->ready();
} }
@ -1136,11 +1173,11 @@ void Session::activateSession()
void Session::passwordResponse(bool timedOut, bool aborted, const std::string &password) void Session::passwordResponse(bool timedOut, bool aborted, const std::string &password)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
if (m_helper) { if (m_helper) {
// Ignore communicaton failures with helper here, // Ignore communicaton failures with helper here,
// we'll notice that elsewhere // we'll notice that elsewhere
m_helper->m_passwordResponse.start(boost::function<void (const std::string &)>(), m_helper->m_passwordResponse.start(std::function<void (const std::string &)>(),
timedOut, aborted, password); timedOut, aborted, password);
} }
} }
@ -1149,7 +1186,7 @@ void Session::passwordResponse(bool timedOut, bool aborted, const std::string &p
void Session::syncProgress(sysync::TProgressEventEnum type, void Session::syncProgress(sysync::TProgressEventEnum type,
int32_t extra1, int32_t extra2, int32_t extra3) int32_t extra1, int32_t extra2, int32_t extra3)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
switch(type) { switch(type) {
case sysync::PEV_CUSTOM_START: case sysync::PEV_CUSTOM_START:
m_cmdlineOp = (RunOperation)extra1; m_cmdlineOp = (RunOperation)extra1;
@ -1202,7 +1239,7 @@ void Session::sourceProgress(sysync::TProgressEventEnum type,
SyncMode sourceSyncMode, SyncMode sourceSyncMode,
int32_t extra1, int32_t extra2, int32_t extra3) int32_t extra1, int32_t extra2, int32_t extra3)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
// a command line operation can be many things, helper must have told us // a command line operation can be many things, helper must have told us
SessionCommon::RunOperation op = m_runOperation == SessionCommon::OP_CMDLINE ? SessionCommon::RunOperation op = m_runOperation == SessionCommon::OP_CMDLINE ?
m_cmdlineOp : m_cmdlineOp :
@ -1334,7 +1371,7 @@ void Session::sourceProgress(sysync::TProgressEventEnum type,
bool Session::setFilters(SyncConfig &config) bool Session::setFilters(SyncConfig &config)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
/** apply temporary configs to config */ /** apply temporary configs to config */
config.setConfigFilter(true, "", m_syncFilter); config.setConfigFilter(true, "", m_syncFilter);
// set all sources in the filter to config // set all sources in the filter to config
@ -1344,19 +1381,9 @@ bool Session::setFilters(SyncConfig &config)
return m_tempConfig; return m_tempConfig;
} }
void Session::setWaiting(bool isWaiting)
{
PushLogger<Logger> guard(m_me);
// if stepInfo doesn't change, then ignore it to avoid duplicate status info
if(m_stepIsWaiting != isWaiting) {
m_stepIsWaiting = isWaiting;
fireStatus(true);
}
}
void Session::restore(const string &dir, bool before, const std::vector<std::string> &sources) void Session::restore(const string &dir, bool before, const std::vector<std::string> &sources)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
if (m_runOperation == SessionCommon::OP_RESTORE) { if (m_runOperation == SessionCommon::OP_RESTORE) {
string msg = StringPrintf("restore started, cannot restore again"); string msg = StringPrintf("restore started, cannot restore again");
SE_THROW_EXCEPTION(InvalidCall, msg); SE_THROW_EXCEPTION(InvalidCall, msg);
@ -1371,24 +1398,28 @@ void Session::restore(const string &dir, bool before, const std::vector<std::str
} }
runOperationAsync(SessionCommon::OP_RESTORE, runOperationAsync(SessionCommon::OP_RESTORE,
boost::bind(&Session::restore2, this, dir, before, sources)); [this, dir, before, sources] () {
restore2(dir, before, sources);
});
} }
void Session::restore2(const string &dir, bool before, const std::vector<std::string> &sources) void Session::restore2(const string &dir, bool before, const std::vector<std::string> &sources)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
if (!m_forkExecParent || !m_helper) { if (!m_forkExecParent || !m_helper) {
SE_THROW("syncing cannot continue, helper died"); SE_THROW("syncing cannot continue, helper died");
} }
// helper is ready, tell it what to do // helper is ready, tell it what to do
m_helper->m_restore.start(boost::bind(&Session::dbusResultCb, m_me, "restore()", _1, SyncReport(), _2), m_helper->m_restore.start([me = weak_from_this()] (bool success, const std::string &error) {
dbusResultCb(me, "restore()", success, {}, error);
},
m_configName, dir, before, sources); m_configName, dir, before, sources);
} }
void Session::execute(const vector<string> &args, const map<string, string> &vars) void Session::execute(const vector<string> &args, const map<string, string> &vars)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
if (m_runOperation == SessionCommon::OP_CMDLINE) { if (m_runOperation == SessionCommon::OP_CMDLINE) {
SE_THROW_EXCEPTION(InvalidCall, "cmdline started, cannot start again"); SE_THROW_EXCEPTION(InvalidCall, "cmdline started, cannot start again");
} else if (m_runOperation != SessionCommon::OP_NULL) { } else if (m_runOperation != SessionCommon::OP_NULL) {
@ -1400,88 +1431,50 @@ void Session::execute(const vector<string> &args, const map<string, string> &var
} }
runOperationAsync(SessionCommon::OP_CMDLINE, runOperationAsync(SessionCommon::OP_CMDLINE,
boost::bind(&Session::execute2, [this, args, vars] () {
this, execute2(args, vars);
args, vars)); });
} }
void Session::execute2(const vector<string> &args, const map<string, string> &vars) void Session::execute2(const vector<string> &args, const map<string, string> &vars)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
if (!m_forkExecParent || !m_helper) { if (!m_forkExecParent || !m_helper) {
SE_THROW("syncing cannot continue, helper died"); SE_THROW("syncing cannot continue, helper died");
} }
// helper is ready, tell it what to do // helper is ready, tell it what to do
m_helper->m_execute.start(boost::bind(&Session::dbusResultCb, m_me, "execute()", _1, SyncReport(), _2), m_helper->m_execute.start([me = weak_from_this()] (bool success, const std::string &error) {
dbusResultCb(me, "execute()", success, {}, error);
},
args, vars); args, vars);
} }
/*Implementation of Session.CheckPresence */ /*Implementation of Session.CheckPresence */
void Session::checkPresence (string &status) void Session::checkPresence (string &status)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
vector<string> transport; vector<string> transport;
m_server.checkPresence(m_configName, status, transport); m_server.checkPresence(m_configName, status, transport);
} }
void Session::sendViaConnection(const DBusArray<uint8_t> buffer,
const std::string &type,
const std::string &url)
{
PushLogger<Logger> guard(m_me);
try {
boost::shared_ptr<Connection> connection = m_connection.lock();
if (!connection) {
SE_THROW_EXCEPTION(TransportException,
"D-Bus peer has disconnected");
}
connection->send(buffer, type, url);
} catch (...) {
std::string explanation;
Exception::handle(explanation);
connectionState(explanation);
}
}
void Session::shutdownConnection()
{
PushLogger<Logger> guard(m_me);
try {
boost::shared_ptr<Connection> connection = m_connection.lock();
if (!connection) {
SE_THROW_EXCEPTION(TransportException,
"D-Bus peer has disconnected");
}
connection->sendFinalMsg();
} catch (...) {
std::string explanation;
Exception::handle(explanation);
connectionState(explanation);
}
}
void Session::storeMessage(const DBusArray<uint8_t> &message, void Session::storeMessage(const DBusArray<uint8_t> &message,
const std::string &type) const std::string &type)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
// ignore errors // ignore errors
if (m_helper) { if (m_helper) {
m_helper->m_storeMessage.start(boost::function<void (const std::string &)>(), m_helper->m_storeMessage.start(std::function<void (const std::string &)>(),
message, type); message, type);
} }
} }
void Session::connectionState(const std::string &error) void Session::connectionState(const std::string &error)
{ {
PushLogger<Logger> guard(m_me); PushLogger<Logger> guard(weak_from_this());
// ignore errors // ignore errors
if (m_helper) { if (m_helper) {
m_helper->m_connectionState.start(boost::function<void (const std::string &)>(), m_helper->m_connectionState.start(std::function<void (const std::string &)>(),
error); error);
} }
} }

View File

@ -21,7 +21,6 @@
#define SESSION_H #define SESSION_H
#include <syncevo/SynthesisEngine.h> #include <syncevo/SynthesisEngine.h>
#include <boost/weak_ptr.hpp>
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include <gdbus-cxx-bridge.h> #include <gdbus-cxx-bridge.h>
@ -48,7 +47,7 @@ class InfoReq;
/** /**
* Represents and implements the Session interface. Use * Represents and implements the Session interface. Use
* boost::shared_ptr to track it and ensure that there are references * std::shared_ptr to track it and ensure that there are references
* to it as long as the connection is needed. * to it as long as the connection is needed.
* *
* The actual implementation is split into two parts: * The actual implementation is split into two parts:
@ -64,6 +63,7 @@ class InfoReq;
class Session : public GDBusCXX::DBusObjectHelper, class Session : public GDBusCXX::DBusObjectHelper,
public Logger, public Logger,
public Resource, public Resource,
public enable_weak_from_this<Session>,
private ReadOperations, private ReadOperations,
private boost::noncopyable private boost::noncopyable
{ {
@ -101,9 +101,9 @@ class Session : public GDBusCXX::DBusObjectHelper,
std::string m_peerDeviceID; std::string m_peerDeviceID;
/** Starts the helper, on demand (see useHelperAsync()). */ /** Starts the helper, on demand (see useHelperAsync()). */
boost::shared_ptr<ForkExecParent> m_forkExecParent; std::shared_ptr<ForkExecParent> m_forkExecParent;
/** The D-Bus proxy for the helper. */ /** The D-Bus proxy for the helper. */
boost::shared_ptr<SessionProxy> m_helper; std::shared_ptr<SessionProxy> m_helper;
/** /**
* Ensures that helper is running and that its D-Bus API is * Ensures that helper is running and that its D-Bus API is
@ -135,23 +135,15 @@ class Session : public GDBusCXX::DBusObjectHelper,
*/ */
void useHelper2(const SimpleResult &result, const boost::signals2::connection &c); void useHelper2(const SimpleResult &result, const boost::signals2::connection &c);
/** set up m_helper */
void onConnect(const GDBusCXX::DBusConnectionPtr &conn) throw ();
/** unset m_helper but not m_forkExecParent (still processing signals) */
void onQuit(int result) throw ();
/** set after abort() and suspend(), to turn "child died' into the LOCERR_USERABORT status code */ /** set after abort() and suspend(), to turn "child died' into the LOCERR_USERABORT status code */
void expectChildTerm(int result) throw (); void expectChildTerm(int result) throw ();
/** log failure */
void onFailure(SyncMLStatus status, const std::string &explanation) throw ();
/** log error output from helper */
void onOutput(const char *buffer, size_t length);
bool m_serverMode; bool m_serverMode;
bool m_serverAlerted; bool m_serverAlerted;
SharedBuffer m_initialMessage; SharedBuffer m_initialMessage;
string m_initialMessageType; string m_initialMessageType;
boost::weak_ptr<Connection> m_connection; std::weak_ptr<Connection> m_connection;
std::string m_connectionError; std::string m_connectionError;
bool m_useConnection; bool m_useConnection;
@ -272,7 +264,6 @@ class Session : public GDBusCXX::DBusObjectHelper,
StringMap m_syncEnv; StringMap m_syncEnv;
typedef std::map<std::string, SyncSourceReport> SyncSourceReports; typedef std::map<std::string, SyncSourceReport> SyncSourceReports;
static void StoreSyncSourceReport(SyncSourceReports &reports, const std::string &name, const SyncSourceReport &report) { reports[name] = report; }
/** Recorded during a sync for getSyncSourceReport. */ /** Recorded during a sync for getSyncSourceReport. */
SyncSourceReports m_syncSourceReports; SyncSourceReports m_syncSourceReports;
@ -356,19 +347,8 @@ public:
*/ */
void setProgressTimeout(unsigned long ms) { m_progressTimer.setTimeout(ms); } void setProgressTimeout(unsigned long ms) { m_progressTimer.setTimeout(ms); }
/** // Construct via make_weak_shared.
* Sessions must always be held in a shared pointer friend make_weak_shared;
* because some operations depend on that. This
* constructor function here ensures that and
* also adds a weak pointer to the instance itself,
* so that it can create more shared pointers as
* needed.
*/
static boost::shared_ptr<Session> createSession(Server &server,
const std::string &peerDeviceID,
const std::string &config_name,
const std::string &session,
const std::vector<std::string> &flags = std::vector<std::string>());
/** /**
* automatically marks the session as completed before deleting it * automatically marks the session as completed before deleting it
@ -379,7 +359,7 @@ public:
* explicitly mark an idle session as completed, even if it doesn't * explicitly mark an idle session as completed, even if it doesn't
* get deleted yet (exceptions not expected by caller) * get deleted yet (exceptions not expected by caller)
*/ */
void done(bool success) throw () { doneCb(success); } void done(bool success) throw () { doneCb(false, success); }
private: private:
Session(Server &server, Session(Server &server,
@ -387,13 +367,7 @@ private:
const std::string &config_name, const std::string &config_name,
const std::string &session, const std::string &session,
const std::vector<std::string> &flags = std::vector<std::string>()); const std::vector<std::string> &flags = std::vector<std::string>());
boost::weak_ptr<Session> m_me; std::shared_ptr<InfoReq> m_passwordRequest;
boost::shared_ptr<InfoReq> m_passwordRequest;
void passwordRequest(const std::string &descr, const ConfigPasswordKey &key);
void sendViaConnection(const GDBusCXX::DBusArray<uint8_t> buffer,
const std::string &type,
const std::string &url);
void shutdownConnection();
void storeMessage(const GDBusCXX::DBusArray<uint8_t> &message, void storeMessage(const GDBusCXX::DBusArray<uint8_t> &message,
const std::string &type); const std::string &type);
void connectionState(const std::string &error); void connectionState(const std::string &error);
@ -425,8 +399,8 @@ public:
void setServerAlerted(bool serverAlerted) { m_serverAlerted = serverAlerted; } void setServerAlerted(bool serverAlerted) { m_serverAlerted = serverAlerted; }
void initServer(SharedBuffer data, const std::string &messageType); void initServer(SharedBuffer data, const std::string &messageType);
void setStubConnection(const boost::shared_ptr<Connection> c) { m_connection = c; m_useConnection = static_cast<bool>(c); } void setStubConnection(const std::shared_ptr<Connection> &c) { m_connection = c; m_useConnection = static_cast<bool>(c); }
boost::weak_ptr<Connection> getStubConnection() { return m_connection; } std::weak_ptr<Connection> getStubConnection() { return m_connection; }
bool useStubConnection() { return m_useConnection; } bool useStubConnection() { return m_useConnection; }
/** /**
@ -492,13 +466,6 @@ public:
bool getFreeze() const { return m_freeze; } bool getFreeze() const { return m_freeze; }
/**
* step info for engine: whether the engine is blocked by something
* If yes, 'waiting' will be appended as specifiers in the status string.
* see GetStatus documentation.
*/
void setWaiting(bool isWaiting);
SyncStatus getSyncStatus() const { return m_syncStatus; } SyncStatus getSyncStatus() const { return m_syncStatus; }
/** session was just activated */ /** session was just activated */
@ -539,11 +506,7 @@ private:
/** set m_syncFilter and m_sourceFilters to config */ /** set m_syncFilter and m_sourceFilters to config */
virtual bool setFilters(SyncConfig &config); virtual bool setFilters(SyncConfig &config);
void dbusResultCb(const std::string &operation, bool success, const SyncReport &report, const std::string &error) throw(); static void dbusResultCb(const std::weak_ptr<Session> &me, const std::string &operation, bool success, const SyncReport &report, const std::string &error) noexcept;
void setFreezeDone(bool changed, const std::string &error,
bool freeze,
const Result<void (bool)> &result);
/** /**
* to be called inside a catch() clause: returns error for any * to be called inside a catch() clause: returns error for any
@ -556,11 +519,12 @@ private:
* get deleted yet (invoked directly or indirectly from event * get deleted yet (invoked directly or indirectly from event
* loop and thus must not throw exceptions) * loop and thus must not throw exceptions)
* *
* @param destruct called from destructor
* @param success if false, then ensure that m_error is set * @param success if false, then ensure that m_error is set
* before finalizing the session * before finalizing the session
* @param report valid only in case of success * @param report valid only in case of success
*/ */
void doneCb(bool success, const SyncReport &report = SyncReport()) throw(); void doneCb(bool destruct, bool success, const SyncReport &report = SyncReport()) throw();
}; };
SE_END_CXX SE_END_CXX

View File

@ -33,33 +33,6 @@
using namespace SyncEvo; using namespace SyncEvo;
using namespace GDBusCXX; using namespace GDBusCXX;
namespace {
GMainLoop *loop = NULL;
int logLevelDBus = Logger::INFO;
// that one is actually never called. probably a bug in ForkExec - it should
// call m_onFailure instead of throwing an exception
void onFailure(const std::string &error, bool &failed) throw ()
{
SE_LOG_DEBUG(NULL, "failure, quitting now: %s", error.c_str());
failed = true;
}
void onConnect(const DBusConnectionPtr &conn,
const boost::shared_ptr<ForkExecChild> &forkexec,
boost::shared_ptr<SessionHelper> &helper)
{
helper.reset(new SessionHelper(loop, conn, forkexec));
helper->activate();
helper->setDBusLogLevel(Logger::Level(logLevelDBus));
}
void onAbort()
{
g_main_loop_quit(loop);
}
} // anonymous namespace
/** /**
* This program is a helper of syncevo-dbus-server which provides the * This program is a helper of syncevo-dbus-server which provides the
* Connection and Session DBus interfaces and runs individual sync * Connection and Session DBus interfaces and runs individual sync
@ -87,7 +60,7 @@ int main(int argc, char **argv, char **envp)
SyncContext::initMain("syncevo-dbus-helper"); SyncContext::initMain("syncevo-dbus-helper");
loop = g_main_loop_new(NULL, FALSE); GMainLoopCXX loop(g_main_loop_new(NULL, FALSE), TRANSFER_REF);
// Suspend and abort are signaled via SIGINT/SIGTERM // Suspend and abort are signaled via SIGINT/SIGTERM
// respectively. SuspendFlags handle that for us. // respectively. SuspendFlags handle that for us.
@ -95,16 +68,17 @@ int main(int argc, char **argv, char **envp)
// can quite. // can quite.
SuspendFlags &s = SuspendFlags::getSuspendFlags(); SuspendFlags &s = SuspendFlags::getSuspendFlags();
s.setLevel(Logger::DEV); s.setLevel(Logger::DEV);
boost::shared_ptr<SuspendFlags::Guard> guard = s.activate((1<<SIGINT)|(1<<SIGTERM)|(1<<SIGURG)); std::shared_ptr<SuspendFlags::Guard> guard = s.activate((1<<SIGINT)|(1<<SIGTERM)|(1<<SIGURG));
bool debug = getenv("SYNCEVOLUTION_DEBUG"); bool debug = getenv("SYNCEVOLUTION_DEBUG");
int logLevelDBus = Logger::INFO;
// Redirect both stdout and stderr. The only code // Redirect both stdout and stderr. The only code
// writing to it should be third-party libraries // writing to it should be third-party libraries
// which are unaware of the SyncEvolution logging system. // which are unaware of the SyncEvolution logging system.
// Redirecting is useful to get such output into our // Redirecting is useful to get such output into our
// sync logfile, once we have one. // sync logfile, once we have one.
boost::shared_ptr<LogRedirect> redirect; std::shared_ptr<LogRedirect> redirect;
PushLogger<LogRedirect> pushRedirect; PushLogger<LogRedirect> pushRedirect;
if (!debug) { if (!debug) {
redirect.reset(new LogRedirect(LogRedirect::STDERR_AND_STDOUT)); redirect.reset(new LogRedirect(LogRedirect::STDERR_AND_STDOUT));
@ -122,7 +96,7 @@ int main(int argc, char **argv, char **envp)
setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0);
try { try {
static GOptionEntry entries[] = { GOptionEntry entries[] = {
{ "dbus-verbosity", 'v', 0, G_OPTION_ARG_INT, &logLevelDBus, { "dbus-verbosity", 'v', 0, G_OPTION_ARG_INT, &logLevelDBus,
"Choose amount of output via D-Bus signals with Logger::Level; default is INFO = 3.", "Choose amount of output via D-Bus signals with Logger::Level; default is INFO = 3.",
"level" }, "level" },
@ -147,19 +121,34 @@ int main(int argc, char **argv, char **envp)
// the brackets, like the other processes do. // the brackets, like the other processes do.
// Logger::setProcessName("syncevo-dbus-helper"); // Logger::setProcessName("syncevo-dbus-helper");
boost::shared_ptr<ForkExecChild> forkexec = ForkExecChild::create(); auto forkexec = make_weak_shared::make<ForkExecChild>();
boost::shared_ptr<SessionHelper> helper; std::shared_ptr<SessionHelper> helper;
bool failed = false; bool failed = false;
forkexec->m_onConnect.connect(boost::bind(onConnect, _1,
boost::cref(forkexec), // that one is actually never called. probably a bug in ForkExec - it should
boost::ref(helper))); // call m_onFailure instead of throwing an exception
forkexec->m_onFailure.connect(boost::bind(onFailure, _2, boost::ref(failed))); auto onFailure = [&failed] (SyncMLStatus, const std::string &error) noexcept {
SE_LOG_DEBUG(NULL, "failure, quitting now: %s", error.c_str());
failed = true;
};
auto onConnect = [&helper, &forkexec, loop, logLevelDBus] (const DBusConnectionPtr &conn) {
helper.reset(new SessionHelper(loop, conn, forkexec));
helper->activate();
helper->setDBusLogLevel(Logger::Level(logLevelDBus));
};
auto onAbort = [loop] (SuspendFlags &) {
g_main_loop_quit(loop);
};
forkexec->m_onConnect.connect(onConnect);
forkexec->m_onFailure.connect(onFailure);
forkexec->connect(); forkexec->connect();
// Run until we are connected, failed or get interrupted. // Run until we are connected, failed or get interrupted.
boost::signals2::connection c = boost::signals2::connection c = s.m_stateChanged.connect(onAbort);
s.m_stateChanged.connect(boost::bind(&onAbort));
SE_LOG_DEBUG(NULL, "helper (pid %d) finished setup, waiting for parent connection", getpid()); SE_LOG_DEBUG(NULL, "helper (pid %d) finished setup, waiting for parent connection", getpid());
while (true) { while (true) {
if (s.getState() != SuspendFlags::NORMAL) { if (s.getState() != SuspendFlags::NORMAL) {

View File

@ -42,7 +42,7 @@ namespace GDBusCXX {
using namespace SyncEvo; using namespace SyncEvo;
MethodHandler::MethodMap MethodHandler::m_methodMap; MethodHandler::MethodMap MethodHandler::m_methodMap;
boost::function<void (void)> MethodHandler::m_callback; std::function<void (void)> MethodHandler::m_callback;
void appendArgInfo(GPtrArray *pa, const std::string &type) void appendArgInfo(GPtrArray *pa, const std::string &type)
{ {
@ -69,7 +69,7 @@ struct OwnNameAsyncData
}; };
OwnNameAsyncData(const std::string &name, OwnNameAsyncData(const std::string &name,
const boost::function<void (bool)> &obtainedCB) : const std::function<void (bool)> &obtainedCB) :
m_name(name), m_name(name),
m_obtainedCB(obtainedCB), m_obtainedCB(obtainedCB),
m_state(OWN_NAME_WAITING) m_state(OWN_NAME_WAITING)
@ -79,7 +79,7 @@ struct OwnNameAsyncData
const gchar *name, const gchar *name,
gpointer userData) throw () gpointer userData) throw ()
{ {
boost::shared_ptr<OwnNameAsyncData> *data = static_cast< boost::shared_ptr<OwnNameAsyncData> *>(userData); std::shared_ptr<OwnNameAsyncData> *data = static_cast< std::shared_ptr<OwnNameAsyncData> *>(userData);
(*data)->m_state = OWN_NAME_OBTAINED; (*data)->m_state = OWN_NAME_OBTAINED;
try { try {
g_debug("got D-Bus name %s", name); g_debug("got D-Bus name %s", name);
@ -95,7 +95,7 @@ struct OwnNameAsyncData
const gchar *name, const gchar *name,
gpointer userData) throw () gpointer userData) throw ()
{ {
boost::shared_ptr<OwnNameAsyncData> *data = static_cast< boost::shared_ptr<OwnNameAsyncData> *>(userData); std::shared_ptr<OwnNameAsyncData> *data = static_cast< std::shared_ptr<OwnNameAsyncData> *>(userData);
(*data)->m_state = OWN_NAME_LOST; (*data)->m_state = OWN_NAME_LOST;
try { try {
g_debug("lost %s %s", g_debug("lost %s %s",
@ -109,26 +109,26 @@ struct OwnNameAsyncData
} }
} }
static boost::shared_ptr<OwnNameAsyncData> ownName(GDBusConnection *conn, static std::shared_ptr<OwnNameAsyncData> ownName(GDBusConnection *conn,
const std::string &name, const std::string &name,
boost::function<void (bool)> obtainedCB = std::function<void (bool)> obtainedCB =
boost::function<void (bool)>()) { std::function<void (bool)>()) {
boost::shared_ptr<OwnNameAsyncData> data(new OwnNameAsyncData(name, obtainedCB)); auto data = std::make_shared<OwnNameAsyncData>(name, obtainedCB);
auto free_data = [] (gpointer userData) noexcept { auto free_data = [] (gpointer userData) noexcept {
delete static_cast< boost::shared_ptr<OwnNameAsyncData> *>(userData); delete static_cast< std::shared_ptr<OwnNameAsyncData> *>(userData);
}; };
g_bus_own_name_on_connection(conn, g_bus_own_name_on_connection(conn,
data->m_name.c_str(), data->m_name.c_str(),
G_BUS_NAME_OWNER_FLAGS_NONE, G_BUS_NAME_OWNER_FLAGS_NONE,
OwnNameAsyncData::busNameAcquired, OwnNameAsyncData::busNameAcquired,
OwnNameAsyncData::busNameLost, OwnNameAsyncData::busNameLost,
new boost::shared_ptr<OwnNameAsyncData>(data), new std::shared_ptr<OwnNameAsyncData>(data),
free_data); free_data);
return data; return data;
} }
const std::string m_name; const std::string m_name;
const boost::function<void (bool)> m_obtainedCB; const std::function<void (bool)> m_obtainedCB;
State m_state; State m_state;
}; };
@ -136,7 +136,7 @@ void DBusConnectionPtr::undelay() const
{ {
if (!m_name.empty()) { if (!m_name.empty()) {
g_debug("starting to acquire D-Bus name %s", m_name.c_str()); g_debug("starting to acquire D-Bus name %s", m_name.c_str());
boost::shared_ptr<OwnNameAsyncData> data = OwnNameAsyncData::ownName(get(), std::shared_ptr<OwnNameAsyncData> data = OwnNameAsyncData::ownName(get(),
m_name); m_name);
while (data->m_state == OwnNameAsyncData::OWN_NAME_WAITING) { while (data->m_state == OwnNameAsyncData::OWN_NAME_WAITING) {
g_main_context_iteration(NULL, true); g_main_context_iteration(NULL, true);
@ -150,7 +150,7 @@ void DBusConnectionPtr::undelay() const
} }
void DBusConnectionPtr::ownNameAsync(const std::string &name, void DBusConnectionPtr::ownNameAsync(const std::string &name,
const boost::function<void (bool)> &obtainedCB) const const std::function<void (bool)> &obtainedCB) const
{ {
OwnNameAsyncData::ownName(get(), name, obtainedCB); OwnNameAsyncData::ownName(get(), name, obtainedCB);
} }
@ -274,7 +274,7 @@ void DBusConnectionPtr::setDisconnect(const Disconnect_t &func)
true); true);
} }
boost::shared_ptr<DBusServerCXX> DBusServerCXX::listen(const NewConnection_t &newConnection, DBusErrorCXX *) std::shared_ptr<DBusServerCXX> DBusServerCXX::listen(const NewConnection_t &newConnection, DBusErrorCXX *)
{ {
// Create two fds connected via a two-way stream. The parent // Create two fds connected via a two-way stream. The parent
// keeps fd[0] which gets closed automatically when the child // keeps fd[0] which gets closed automatically when the child
@ -317,7 +317,8 @@ boost::shared_ptr<DBusServerCXX> DBusServerCXX::listen(const NewConnection_t &ne
// A fake DBusServerCXX which does nothing more than return the address, aka // A fake DBusServerCXX which does nothing more than return the address, aka
// our FD number, and store data for the idle callback. // our FD number, and store data for the idle callback.
boost::shared_ptr<DBusServerCXX> res(new DBusServerCXX(address)); // Private constructor, can't use make_shared() here.
std::shared_ptr<DBusServerCXX> res(new DBusServerCXX(address));
res->m_newConnection = newConnection; res->m_newConnection = newConnection;
res->m_connection = connection; res->m_connection = connection;
// Will be freed in the idle callback. Caller must have forked by then. // Will be freed in the idle callback. Caller must have forked by then.
@ -399,7 +400,7 @@ void Watch::disconnected()
} }
Watch::Watch(const DBusConnectionPtr &conn, Watch::Watch(const DBusConnectionPtr &conn,
const boost::function<void (void)> &callback) : const std::function<void (void)> &callback) :
m_conn(conn), m_conn(conn),
m_callback(callback), m_callback(callback),
m_called(false), m_called(false),
@ -407,7 +408,7 @@ Watch::Watch(const DBusConnectionPtr &conn,
{ {
} }
void Watch::setCallback(const boost::function<void (void)> &callback) void Watch::setCallback(const std::function<void (void)> &callback)
{ {
m_callback = callback; m_callback = callback;
if (m_called && m_callback) { if (m_called && m_callback) {
@ -480,7 +481,7 @@ Watch::~Watch()
} }
void getWatch(ExtractArgs &context, void getWatch(ExtractArgs &context,
boost::shared_ptr<Watch> &value) std::shared_ptr<Watch> &value)
{ {
std::unique_ptr<Watch> watch(new Watch(context.m_conn)); std::unique_ptr<Watch> watch(new Watch(context.m_conn));
watch->activate((context.m_msg && *context.m_msg) ? watch->activate((context.m_msg && *context.m_msg) ?

View File

@ -62,15 +62,15 @@
#include <gio/gio.h> #include <gio/gio.h>
#include <glib-object.h> #include <glib-object.h>
#include <map>
#include <list>
#include <vector>
#include <deque> #include <deque>
#include <functional>
#include <list>
#include <map>
#include <memory>
#include <utility> #include <utility>
#include <vector>
#include <boost/bind.hpp>
#include <boost/intrusive_ptr.hpp> #include <boost/intrusive_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/variant.hpp> #include <boost/variant.hpp>
#include <boost/variant/get.hpp> #include <boost/variant/get.hpp>
#include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/predicate.hpp>
@ -229,7 +229,7 @@ class DBusConnectionPtr : public boost::intrusive_ptr<GDBusConnection>
*/ */
void flush(); void flush();
typedef boost::function<void ()> Disconnect_t; typedef std::function<void ()> Disconnect_t;
void setDisconnect(const Disconnect_t &func); void setDisconnect(const Disconnect_t &func);
// #define GDBUS_CXX_HAVE_DISCONNECT 1 // #define GDBUS_CXX_HAVE_DISCONNECT 1
@ -258,7 +258,7 @@ class DBusConnectionPtr : public boost::intrusive_ptr<GDBusConnection>
* The callback is allowed to be empty. * The callback is allowed to be empty.
*/ */
void ownNameAsync(const std::string &name, void ownNameAsync(const std::string &name,
const boost::function<void (bool)> &obtainedCB) const; const std::function<void (bool)> &obtainedCB) const;
}; };
class DBusMessagePtr : public boost::intrusive_ptr<GDBusMessage> class DBusMessagePtr : public boost::intrusive_ptr<GDBusMessage>
@ -361,7 +361,7 @@ class DBusServerCXX : private boost::noncopyable
* connection, so the callback can set up objects and then must undelay * connection, so the callback can set up objects and then must undelay
* the connection. * the connection.
*/ */
typedef boost::function<void (DBusServerCXX &, DBusConnectionPtr &)> NewConnection_t; typedef std::function<void (DBusServerCXX &, DBusConnectionPtr &)> NewConnection_t;
/** /**
* Start listening for new connections. Mimics the libdbus DBusServer API, but * Start listening for new connections. Mimics the libdbus DBusServer API, but
@ -372,7 +372,7 @@ class DBusServerCXX : private boost::noncopyable
* *
* All errors are reported via exceptions, not "err". * All errors are reported via exceptions, not "err".
*/ */
static boost::shared_ptr<DBusServerCXX> listen(const NewConnection_t &newConnection, DBusErrorCXX *err); static std::shared_ptr<DBusServerCXX> listen(const NewConnection_t &newConnection, DBusErrorCXX *err);
/** /**
* address used by the server * address used by the server
@ -411,7 +411,7 @@ struct dbus_traits_base
{ {
/** /**
* A C++ method or function can handle a call asynchronously by * A C++ method or function can handle a call asynchronously by
* asking to be passed a "boost::shared_ptr<Result*>" parameter. * asking to be passed a "std::shared_ptr<Result*>" parameter.
* The dbus_traits for those parameters have "asynchronous" set to * The dbus_traits for those parameters have "asynchronous" set to
* true, which skips all processing after calling the method. * true, which skips all processing after calling the method.
*/ */
@ -850,23 +850,23 @@ struct FunctionWrapperBase {
template<typename M> template<typename M>
struct FunctionWrapper : public FunctionWrapperBase { struct FunctionWrapper : public FunctionWrapperBase {
FunctionWrapper(boost::function<M>* func_ptr) FunctionWrapper(std::function<M>* func_ptr)
: FunctionWrapperBase(reinterpret_cast<void*>(func_ptr)) : FunctionWrapperBase(reinterpret_cast<void*>(func_ptr))
{} {}
virtual ~FunctionWrapper() { virtual ~FunctionWrapper() {
delete reinterpret_cast<boost::function<M>*>(m_func_ptr); delete reinterpret_cast<std::function<M>*>(m_func_ptr);
} }
}; };
struct MethodHandler struct MethodHandler
{ {
typedef GDBusMessage *(*MethodFunction)(GDBusConnection *conn, GDBusMessage *msg, void *data); typedef GDBusMessage *(*MethodFunction)(GDBusConnection *conn, GDBusMessage *msg, void *data);
typedef boost::shared_ptr<FunctionWrapperBase> FuncWrapper; typedef std::shared_ptr<FunctionWrapperBase> FuncWrapper;
typedef std::pair<MethodFunction, FuncWrapper > CallbackPair; typedef std::pair<MethodFunction, FuncWrapper > CallbackPair;
typedef std::map<const std::string, CallbackPair > MethodMap; typedef std::map<const std::string, CallbackPair > MethodMap;
static MethodMap m_methodMap; static MethodMap m_methodMap;
static boost::function<void (void)> m_callback; static std::function<void (void)> m_callback;
static std::string make_prefix(const char *object_path) { static std::string make_prefix(const char *object_path) {
return std::string(object_path) + "~"; return std::string(object_path) + "~";
@ -989,7 +989,7 @@ class DBusObjectHelper : public DBusObject
public: public:
typedef boost::function<void (void)> Callback_t; typedef std::function<void (void)> Callback_t;
DBusObjectHelper(const DBusConnectionPtr &conn, DBusObjectHelper(const DBusConnectionPtr &conn,
const std::string &path, const std::string &path,
@ -1047,10 +1047,10 @@ class DBusObjectHelper : public DBusObject
throw std::logic_error("You can't add new methods after registration!"); throw std::logic_error("You can't add new methods after registration!");
} }
typedef MakeMethodEntry< boost::function<M> > entry_type; typedef MakeMethodEntry< std::function<M> > entry_type;
g_ptr_array_add(m_methods, entry_type::make(name)); g_ptr_array_add(m_methods, entry_type::make(name));
boost::function<M> *func = new boost::function<M>(entry_type::boostptr(method, instance)); std::function<M> *func = new std::function<M>(entry_type::boostptr(method, instance));
MethodHandler::FuncWrapper wrapper(new FunctionWrapper<M>(func)); MethodHandler::FuncWrapper wrapper(new FunctionWrapper<M>(func));
MethodHandler::CallbackPair methodAndData = std::make_pair(entry_type::methodFunction, wrapper); MethodHandler::CallbackPair methodAndData = std::make_pair(entry_type::methodFunction, wrapper);
const std::string key(MethodHandler::make_method_key(getPath(), name)); const std::string key(MethodHandler::make_method_key(getPath(), name));
@ -1068,10 +1068,10 @@ class DBusObjectHelper : public DBusObject
throw std::logic_error("You can't add new functions after registration!"); throw std::logic_error("You can't add new functions after registration!");
} }
typedef MakeMethodEntry< boost::function<M> > entry_type; typedef MakeMethodEntry< std::function<M> > entry_type;
g_ptr_array_add(m_methods, entry_type::make(name)); g_ptr_array_add(m_methods, entry_type::make(name));
boost::function<M> *func = new boost::function<M>(function); std::function<M> *func = new std::function<M>(function);
MethodHandler::FuncWrapper wrapper(new FunctionWrapper<M>(func)); MethodHandler::FuncWrapper wrapper(new FunctionWrapper<M>(func));
MethodHandler::CallbackPair methodAndData = std::make_pair(entry_type::methodFunction, MethodHandler::CallbackPair methodAndData = std::make_pair(entry_type::methodFunction,
wrapper); wrapper);
@ -2209,7 +2209,7 @@ static inline GDBusMessage *handleException(GDBusMessage *&callerMsg)
class Watch : private boost::noncopyable class Watch : private boost::noncopyable
{ {
DBusConnectionPtr m_conn; DBusConnectionPtr m_conn;
boost::function<void (void)> m_callback; std::function<void (void)> m_callback;
bool m_called; bool m_called;
guint m_watchID; guint m_watchID;
std::string m_peer; std::string m_peer;
@ -2226,14 +2226,14 @@ class Watch : private boost::noncopyable
public: public:
Watch(const DBusConnectionPtr &conn, Watch(const DBusConnectionPtr &conn,
const boost::function<void (void)> &callback = boost::function<void (void)>()); const std::function<void (void)> &callback = {});
~Watch(); ~Watch();
/** /**
* Changes the callback triggered by this Watch. If the watch has * Changes the callback triggered by this Watch. If the watch has
* already fired, the callback is invoked immediately. * already fired, the callback is invoked immediately.
*/ */
void setCallback(const boost::function<void (void)> &callback); void setCallback(const std::function<void (void)> &callback);
/** /**
* Starts watching for disconnect of that peer * Starts watching for disconnect of that peer
@ -2243,24 +2243,24 @@ class Watch : private boost::noncopyable
void activate(const char *peer); void activate(const char *peer);
}; };
void getWatch(ExtractArgs &context, boost::shared_ptr<Watch> &value); void getWatch(ExtractArgs &context, std::shared_ptr<Watch> &value);
/** /**
* pseudo-parameter: not part of D-Bus signature, * pseudo-parameter: not part of D-Bus signature,
* but rather extracted from message attributes * but rather extracted from message attributes
*/ */
template <> struct dbus_traits< boost::shared_ptr<Watch> > : public dbus_traits_base template <> struct dbus_traits< std::shared_ptr<Watch> > : public dbus_traits_base
{ {
static std::string getType() { return ""; } static std::string getType() { return ""; }
static std::string getSignature() { return ""; } static std::string getSignature() { return ""; }
static std::string getReply() { return ""; } static std::string getReply() { return ""; }
static void get(ExtractArgs &context, static void get(ExtractArgs &context,
GVariantIter &iter, boost::shared_ptr<Watch> &value) { getWatch(context, value); } GVariantIter &iter, std::shared_ptr<Watch> &value) { getWatch(context, value); }
static void append(GVariantBuilder &builder, const boost::shared_ptr<Watch> &value) {} static void append(GVariantBuilder &builder, const std::shared_ptr<Watch> &value) {}
typedef boost::shared_ptr<Watch> host_type; typedef std::shared_ptr<Watch> host_type;
typedef const boost::shared_ptr<Watch> &arg_type; typedef const std::shared_ptr<Watch> &arg_type;
}; };
/** /**
@ -2320,7 +2320,7 @@ template<typename ...A> class DBusResult : virtual public Result<A...>
sendMsg(errMsg); sendMsg(errMsg);
} }
virtual Watch *createWatch(const boost::function<void (void)> &callback) virtual Watch *createWatch(const std::function<void (void)> &callback)
{ {
std::unique_ptr<Watch> watch(new Watch(m_conn, callback)); std::unique_ptr<Watch> watch(new Watch(m_conn, callback));
watch->activate(g_dbus_message_get_sender(m_msg.get())); watch->activate(g_dbus_message_get_sender(m_msg.get()));
@ -2348,14 +2348,14 @@ template<typename ...A> class DBusResult : virtual public Result<A...>
* destructs and transfers the responsibility for sending a reply to * destructs and transfers the responsibility for sending a reply to
* the DBusResult instance. * the DBusResult instance.
*/ */
template <class DBusR> class DBusResultGuard : public boost::shared_ptr<DBusR> template <class DBusR> class DBusResultGuard : public std::shared_ptr<DBusR>
{ {
GDBusMessage **m_msg; GDBusMessage **m_msg;
public: public:
DBusResultGuard() : m_msg(NULL) {} DBusResultGuard() : m_msg(NULL) {}
~DBusResultGuard() throw () ~DBusResultGuard() throw ()
{ {
DBusR *result = boost::shared_ptr<DBusR>::get(); DBusR *result = std::shared_ptr<DBusR>::get();
// Our caller has not cleared its "msg" instance, // Our caller has not cleared its "msg" instance,
// which means that from now on it will be our // which means that from now on it will be our
// responsibility to provide a response. // responsibility to provide a response.
@ -2367,19 +2367,19 @@ template <class DBusR> class DBusResultGuard : public boost::shared_ptr<DBusR>
void initDBusResult(ExtractArgs &context) void initDBusResult(ExtractArgs &context)
{ {
m_msg = context.m_msg; m_msg = context.m_msg;
boost::shared_ptr<DBusR>::reset(new DBusR(context.m_conn, context.m_msg ? *context.m_msg : NULL)); std::shared_ptr<DBusR>::reset(new DBusR(context.m_conn, context.m_msg ? *context.m_msg : NULL));
} }
}; };
template <typename ...A> template <typename ...A>
struct dbus_traits< boost::shared_ptr<Result<A...> > > struct dbus_traits< std::shared_ptr<Result<A...> > >
{ {
static std::string getType() { return DBusResult<A...>::getSignature(); } static std::string getType() { return DBusResult<A...>::getSignature(); }
static std::string getSignature() { return ""; } static std::string getSignature() { return ""; }
static std::string getReply() { return getType(); } static std::string getReply() { return getType(); }
typedef DBusResultGuard< DBusResult<A...> > host_type; typedef DBusResultGuard< DBusResult<A...> > host_type;
typedef boost::shared_ptr< Result<A...> > &arg_type; typedef std::shared_ptr< Result<A...> > &arg_type;
static const bool asynchronous = true; static const bool asynchronous = true;
static void get(ExtractArgs &context, static void get(ExtractArgs &context,
@ -2421,10 +2421,10 @@ namespace {
/** return value */ /** return value */
template <typename R, typename ...A> template <typename R, typename ...A>
struct MakeMethodEntry< boost::function<R (A...)> > struct MakeMethodEntry< std::function<R (A...)> >
{ {
typedef R (Mptr)(A...); typedef R (Mptr)(A...);
typedef boost::function<Mptr> M; typedef std::function<Mptr> M;
template <class I, class C> static auto boostptr(Mptr C::*method, I instance) { template <class I, class C> static auto boostptr(Mptr C::*method, I instance) {
return [method, instance] (A... a) { return [method, instance] (A... a) {
@ -2491,10 +2491,10 @@ struct MakeMethodEntry< boost::function<R (A...)> >
/** no return value */ /** no return value */
template <typename ...A> template <typename ...A>
struct MakeMethodEntry< boost::function<void (A...)> > struct MakeMethodEntry< std::function<void (A...)> >
{ {
typedef void (Mptr)(A...); typedef void (Mptr)(A...);
typedef boost::function<Mptr> M; typedef std::function<Mptr> M;
template <class I, class C> static auto boostptr(Mptr C::*method, I instance) { template <class I, class C> static auto boostptr(Mptr C::*method, I instance) {
return [method, instance] (A... a) { return [method, instance] (A... a) {
@ -2588,7 +2588,7 @@ template<typename R1, typename R2, typename R3, typename ...R> struct DBusClient
template<typename ...R> class DBusClientCall template<typename ...R> class DBusClientCall
{ {
typedef boost::function<void (R..., const std::string &)> Callback_t; typedef std::function<void (R..., const std::string &)> Callback_t;
typedef typename DBusClientCallReturnType<R...>::Return_t Return_t; typedef typename DBusClientCallReturnType<R...>::Return_t Return_t;
typedef typename DBusClientCallReturnType<R...>::Buffer_t Buffer_t; typedef typename DBusClientCallReturnType<R...>::Buffer_t Buffer_t;
@ -2877,7 +2877,7 @@ template <typename ...A> class SignalWatch : public SignalFilter
} }
} }
typedef boost::function<void (A...)> Callback_t; typedef std::function<void (A...)> Callback_t;
const Callback_t &getCallback() const { return m_callback; } const Callback_t &getCallback() const { return m_callback; }
void activate(const Callback_t &callback) void activate(const Callback_t &callback)

View File

@ -22,7 +22,8 @@
#include <string> #include <string>
#include <stdexcept> #include <stdexcept>
#include <boost/function.hpp> #include <functional>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
namespace GDBusCXX { namespace GDBusCXX {
@ -122,10 +123,10 @@ class ResultBase : private boost::noncopyable
* is requested. * is requested.
* *
* Alternatively a method can ask to get called with a life Watch * Alternatively a method can ask to get called with a life Watch
* by specifying "const boost::shared_ptr<Watch> &" as parameter * by specifying "const std::shared_ptr<Watch> &" as parameter
* and then calling its setCallback(). * and then calling its setCallback().
*/ */
virtual Watch *createWatch(const boost::function<void (void)> &callback) = 0; virtual Watch *createWatch(const std::function<void (void)> &callback) = 0;
}; };
template<typename ...A> class Result : public ResultBase template<typename ...A> class Result : public ResultBase
{ {

View File

@ -19,7 +19,7 @@
/** /**
* Including this header file allows to use boost::bind() with * Including this header file allows to use boost::bind() with
* a class member as first parameter and a boost::weak_ptr * a class member as first parameter and a std::weak_ptr
* as second parameter. * as second parameter.
* *
* When the functor is invoked, it will lock the instance * When the functor is invoked, it will lock the instance
@ -44,7 +44,6 @@
#ifndef INCL_SYNCEVOLUTION_BOOST_HELPER #ifndef INCL_SYNCEVOLUTION_BOOST_HELPER
# define INCL_SYNCEVOLUTION_BOOST_HELPER # define INCL_SYNCEVOLUTION_BOOST_HELPER
#include <boost/bind.hpp>
#include <boost/smart_ptr.hpp> #include <boost/smart_ptr.hpp>
#include <syncevo/declarations.h> #include <syncevo/declarations.h>
@ -146,26 +145,26 @@ class WeakPtrInvoker
template <typename T> class WeakPtrAdapter template <typename T> class WeakPtrAdapter
{ {
public: public:
WeakPtrAdapter(const boost::shared_ptr<T> &ptr) : WeakPtrAdapter(const std::shared_ptr<T> &ptr) :
m_ptr(ptr) m_ptr(ptr)
{} {}
template <typename M> template <typename M>
WeakPtrInvoker<boost::shared_ptr<T>, M> operator->*(M member) const WeakPtrInvoker<std::shared_ptr<T>, M> operator->*(M member) const
{ {
return WeakPtrInvoker<boost::shared_ptr<T>, M>(m_ptr, member); return WeakPtrInvoker<std::shared_ptr<T>, M>(m_ptr, member);
} }
private: private:
boost::shared_ptr<T> m_ptr; std::shared_ptr<T> m_ptr;
}; };
SE_END_CXX SE_END_CXX
namespace boost namespace std
{ {
template<class T> template<class T>
SyncEvo::WeakPtrAdapter<T> get_pointer(const boost::weak_ptr<T> &ptr) SyncEvo::WeakPtrAdapter<T> get_pointer(const std::weak_ptr<T> &ptr)
{ {
return SyncEvo::WeakPtrAdapter<T>(ptr.lock()); return SyncEvo::WeakPtrAdapter<T>(ptr.lock());
} }

View File

@ -43,7 +43,6 @@
#include <list> #include <list>
#include <algorithm> #include <algorithm>
#include <boost/shared_ptr.hpp>
#include <boost/algorithm/string/join.hpp> #include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/split.hpp> #include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
@ -441,7 +440,7 @@ bool Cmdline::dontRun() const
} }
} }
void Cmdline::makeObsolete(boost::shared_ptr<SyncConfig> &from) void Cmdline::makeObsolete(std::shared_ptr<SyncConfig> &from)
{ {
string oldname = from->getRootPath(); string oldname = from->getRootPath();
string newname, suffix; string newname, suffix;
@ -454,7 +453,7 @@ void Cmdline::makeObsolete(boost::shared_ptr<SyncConfig> &from)
suffix = newsuffix.str(); suffix = newsuffix.str();
newname = oldname + suffix; newname = oldname + suffix;
if (from->hasPeerProperties()) { if (from->hasPeerProperties()) {
boost::shared_ptr<SyncConfig> renamed(new SyncConfig(from->getPeerName() + suffix)); auto renamed = std::make_shared<SyncConfig>(from->getPeerName() + suffix);
if (renamed->exists()) { if (renamed->exists()) {
// don't pick a config name which has the same peer name // don't pick a config name which has the same peer name
// as some other, existing config // as some other, existing config
@ -489,8 +488,8 @@ void Cmdline::makeObsolete(boost::shared_ptr<SyncConfig> &from)
from.reset(new SyncConfig(newConfigName)); from.reset(new SyncConfig(newConfigName));
} }
void Cmdline::copyConfig(const boost::shared_ptr<SyncConfig> &from, void Cmdline::copyConfig(const std::shared_ptr<SyncConfig> &from,
const boost::shared_ptr<SyncConfig> &to, const std::shared_ptr<SyncConfig> &to,
const set<string> &selectedSources) const set<string> &selectedSources)
{ {
const set<string> *sources = NULL; const set<string> *sources = NULL;
@ -533,8 +532,8 @@ void Cmdline::copyConfig(const boost::shared_ptr<SyncConfig> &from,
to->copy(*from, sources); to->copy(*from, sources);
} }
void Cmdline::finishCopy(const boost::shared_ptr<SyncConfig> &from, void Cmdline::finishCopy(const std::shared_ptr<SyncConfig> &from,
const boost::shared_ptr<SyncContext> &to) const std::shared_ptr<SyncContext> &to)
{ {
// give a change to do something before flushing configs to files // give a change to do something before flushing configs to files
to->preFlush(to->getUserInterfaceNonNull()); to->preFlush(to->getUserInterfaceNonNull());
@ -599,11 +598,11 @@ void Cmdline::finishCopy(const boost::shared_ptr<SyncConfig> &from,
void Cmdline::migratePeer(const std::string &fromPeer, const std::string &toPeer) void Cmdline::migratePeer(const std::string &fromPeer, const std::string &toPeer)
{ {
boost::shared_ptr<SyncConfig> from(new SyncConfig(fromPeer)); auto from = std::make_shared<SyncConfig>(fromPeer);
makeObsolete(from); makeObsolete(from);
// hack: move to different target config for createSyncClient() // hack: move to different target config for createSyncClient()
m_server = toPeer; m_server = toPeer;
boost::shared_ptr<SyncContext> to(createSyncClient()); std::shared_ptr<SyncContext> to(createSyncClient());
// Special case for Memotoo: explicitly set preferred sync format // Special case for Memotoo: explicitly set preferred sync format
// to vCard 3.0 as part of the SyncEvolution 1.1.x -> 1.2 migration, // to vCard 3.0 as part of the SyncEvolution 1.1.x -> 1.2 migration,
@ -613,7 +612,7 @@ void Cmdline::migratePeer(const std::string &fromPeer, const std::string &toPeer
vector<string> urls = from->getSyncURL(); vector<string> urls = from->getSyncURL();
if (urls.size() == 1 && if (urls.size() == 1 &&
urls[0] == "http://sync.memotoo.com/syncML") { urls[0] == "http://sync.memotoo.com/syncML") {
boost::shared_ptr<SyncContext> to(createSyncClient()); std::shared_ptr<SyncContext> to(createSyncClient());
m_props[to->getContextName()].m_sourceProps["addressbook"].insert(make_pair("syncFormat", "text/vcard")); m_props[to->getContextName()].m_sourceProps["addressbook"].insert(make_pair("syncFormat", "text/vcard"));
} }
} }
@ -658,18 +657,6 @@ public:
} }
}; };
static void ShowLUID(SyncSourceLogging *logging, const std::string &luid)
{
string description;
if (logging) {
description = logging->getDescription(luid);
}
SE_LOG_SHOW(NULL, "%s%s%s",
CmdlineLUID::fromLUID(luid).c_str(),
description.empty() ? "" : ": ",
description.c_str());
}
static void ExportLUID(SyncSourceRaw *raw, static void ExportLUID(SyncSourceRaw *raw,
ostream *out, ostream *out,
const std::string &defDelimiter, const std::string &defDelimiter,
@ -754,9 +741,9 @@ bool Cmdline::run() {
} else if (m_printDatabases || m_createDatabase || m_removeDatabase) { } else if (m_printDatabases || m_createDatabase || m_removeDatabase) {
// manipulate databases // manipulate databases
const SourceRegistry &registry(SyncSource::getSourceRegistry()); const SourceRegistry &registry(SyncSource::getSourceRegistry());
boost::shared_ptr<SyncSourceNodes> nodes; std::shared_ptr<SyncSourceNodes> nodes;
std::string header; std::string header;
boost::shared_ptr<SyncContext> context; std::shared_ptr<SyncContext> context;
FilterConfigNode::ConfigFilter sourceFilter; FilterConfigNode::ConfigFilter sourceFilter;
std::string sourceName; std::string sourceName;
FilterConfigNode::ConfigFilter::const_iterator backend; FilterConfigNode::ConfigFilter::const_iterator backend;
@ -789,11 +776,11 @@ bool Cmdline::run() {
sourceFilter = m_props.createSourceFilter(m_server, ""); sourceFilter = m_props.createSourceFilter(m_server, "");
backend = sourceFilter.find("backend"); backend = sourceFilter.find("backend");
context.reset(createSyncClient()); context.reset(createSyncClient());
boost::shared_ptr<FilterConfigNode> sharedNode(new VolatileConfigNode()); auto sharedNode = std::make_shared<VolatileConfigNode>();
boost::shared_ptr<FilterConfigNode> configNode(new VolatileConfigNode()); auto configNode = std::make_shared<VolatileConfigNode>();
boost::shared_ptr<FilterConfigNode> hiddenNode(new VolatileConfigNode()); auto hiddenNode = std::make_shared<VolatileConfigNode>();
boost::shared_ptr<FilterConfigNode> trackingNode(new VolatileConfigNode()); auto trackingNode = std::make_shared<VolatileConfigNode>();
boost::shared_ptr<FilterConfigNode> serverNode(new VolatileConfigNode()); auto serverNode = std::make_shared<VolatileConfigNode>();
nodes.reset(new SyncSourceNodes(true, sharedNode, configNode, hiddenNode, trackingNode, serverNode, "")); nodes.reset(new SyncSourceNodes(true, sharedNode, configNode, hiddenNode, trackingNode, serverNode, ""));
header = backend != sourceFilter.end() ? header = backend != sourceFilter.end() ?
backend->second : backend->second :
@ -844,7 +831,7 @@ bool Cmdline::run() {
} }
} }
} else if (m_printConfig) { } else if (m_printConfig) {
boost::shared_ptr<SyncConfig> config; std::shared_ptr<SyncConfig> config;
ConfigProps syncFilter; ConfigProps syncFilter;
SourceProps sourceFilters; SourceProps sourceFilters;
@ -896,7 +883,7 @@ bool Cmdline::run() {
if (m_sources.empty() || if (m_sources.empty() ||
m_sources.find("main") != m_sources.end()) { m_sources.find("main") != m_sources.end()) {
boost::shared_ptr<FilterConfigNode> syncProps(config->getProperties()); std::shared_ptr<FilterConfigNode> syncProps(config->getProperties());
syncProps->setFilter(syncFilter); syncProps->setFilter(syncFilter);
dumpProperties(*syncProps, config->getRegistry(), flags); dumpProperties(*syncProps, config->getRegistry(), flags);
} }
@ -908,7 +895,7 @@ bool Cmdline::run() {
m_sources.find(name) != m_sources.end()) { m_sources.find(name) != m_sources.end()) {
SE_LOG_SHOW(NULL, "[%s]", name.c_str()); SE_LOG_SHOW(NULL, "[%s]", name.c_str());
SyncSourceNodes nodes = config->getSyncSourceNodes(name); SyncSourceNodes nodes = config->getSyncSourceNodes(name);
boost::shared_ptr<FilterConfigNode> sourceProps = nodes.getProperties(); std::shared_ptr<FilterConfigNode> sourceProps = nodes.getProperties();
sourceProps->setFilter(sourceFilters.createSourceFilter(name)); sourceProps->setFilter(sourceFilters.createSourceFilter(name));
dumpProperties(*sourceProps, SyncSourceConfig::getRegistry(), dumpProperties(*sourceProps, SyncSourceConfig::getRegistry(),
flags | ((name != *(--sources.end())) ? HIDE_LEGEND : DUMP_PROPS_NORMAL)); flags | ((name != *(--sources.end())) ? HIDE_LEGEND : DUMP_PROPS_NORMAL));
@ -953,8 +940,8 @@ bool Cmdline::run() {
// another config (template resp. old one). Migration also moves // another config (template resp. old one). Migration also moves
// the old config. The target configuration is determined by m_server, // the old config. The target configuration is determined by m_server,
// but the exact semantic of it depends on the operation. // but the exact semantic of it depends on the operation.
boost::shared_ptr<SyncConfig> from; std::shared_ptr<SyncConfig> from;
boost::shared_ptr<SyncContext> to; std::shared_ptr<SyncContext> to;
string origPeer; string origPeer;
if (m_migrate) { if (m_migrate) {
if (!m_sources.empty()) { if (!m_sources.empty()) {
@ -1210,7 +1197,7 @@ bool Cmdline::run() {
SuspendFlags &s = SuspendFlags::getSuspendFlags(); SuspendFlags &s = SuspendFlags::getSuspendFlags();
for (const string &source: configuredSources) { for (const string &source: configuredSources) {
boost::shared_ptr<PersistentSyncSourceConfig> sourceConfig(to->getSyncSourceConfig(source)); std::shared_ptr<PersistentSyncSourceConfig> sourceConfig(to->getSyncSourceConfig(source));
string disable = ""; string disable = "";
set<string>::iterator entry = sources.find(source); set<string>::iterator entry = sources.find(source);
bool selected = entry != sources.end(); bool selected = entry != sources.end();
@ -1342,7 +1329,7 @@ bool Cmdline::run() {
usage(false, "too many parameters for --remove"); usage(false, "too many parameters for --remove");
return false; return false;
} else { } else {
boost::shared_ptr<SyncConfig> config; std::shared_ptr<SyncConfig> config;
config.reset(new SyncConfig(m_server)); config.reset(new SyncConfig(m_server));
if (!config->exists()) { if (!config->exists()) {
Exception::throwError(SE_HERE, string("no such configuration: ") + m_server); Exception::throwError(SE_HERE, string("no such configuration: ") + m_server);
@ -1353,7 +1340,7 @@ bool Cmdline::run() {
} }
} else if (m_accessItems) { } else if (m_accessItems) {
// need access to specific source // need access to specific source
boost::shared_ptr<SyncContext> context; std::shared_ptr<SyncContext> context;
context.reset(createSyncClient()); context.reset(createSyncClient());
// operating on exactly one source (can be optional) // operating on exactly one source (can be optional)
@ -1420,7 +1407,17 @@ bool Cmdline::run() {
err = ops.m_startDataRead("", ""); err = ops.m_startDataRead("", "");
CHECK_ERROR("reading items"); CHECK_ERROR("reading items");
source->setReadAheadOrder(SyncSourceBase::READ_ALL_ITEMS); source->setReadAheadOrder(SyncSourceBase::READ_ALL_ITEMS);
processLUIDs(source, boost::bind(ShowLUID, logging, _1)); auto showLUID = [logging] (const std::string &luid) {
string description;
if (logging) {
description = logging->getDescription(luid);
}
SE_LOG_SHOW(NULL, "%s%s%s",
CmdlineLUID::fromLUID(luid).c_str(),
description.empty() ? "" : ": ",
description.c_str());
};
processLUIDs(source, showLUID);
} else if (m_deleteItems) { } else if (m_deleteItems) {
if (!ops.m_deleteItem) { if (!ops.m_deleteItem) {
source->throwError(SE_HERE, "deleting items not supported"); source->throwError(SE_HERE, "deleting items not supported");
@ -1570,14 +1567,10 @@ bool Cmdline::run() {
if (m_luids.empty()) { if (m_luids.empty()) {
// Read all items. // Read all items.
raw->setReadAheadOrder(SyncSourceBase::READ_ALL_ITEMS); raw->setReadAheadOrder(SyncSourceBase::READ_ALL_ITEMS);
processLUIDs(source, boost::bind(ExportLUID, auto exportOne = [this, raw, out, &haveItem, &haveNewline] (const std::string &luid) {
raw, ExportLUID(raw, out, m_delimiter, m_itemPath, haveItem, haveNewline, luid);
out, };
boost::ref(m_delimiter), processLUIDs(source, exportOne);
boost::ref(m_itemPath),
boost::ref(haveItem),
boost::ref(haveNewline),
_1));
} else { } else {
SyncSourceBase::ReadAheadItems luids; SyncSourceBase::ReadAheadItems luids;
luids.reserve(m_luids.size()); luids.reserve(m_luids.size());
@ -1603,7 +1596,7 @@ bool Cmdline::run() {
} }
std::set<std::string> unmatchedSources; std::set<std::string> unmatchedSources;
boost::shared_ptr<SyncContext> context; std::shared_ptr<SyncContext> context;
context.reset(createSyncClient()); context.reset(createSyncClient());
context->setConfigProps(m_props); context->setConfigProps(m_props);
context->setQuiet(m_quiet); context->setQuiet(m_quiet);
@ -1617,7 +1610,7 @@ bool Cmdline::run() {
// accidentally when the sync mode is modified // accidentally when the sync mode is modified
// temporarily. // temporarily.
for (const std::string &source: context->getSyncSources()) { for (const std::string &source: context->getSyncSources()) {
boost::shared_ptr<PersistentSyncSourceConfig> source_config = std::shared_ptr<PersistentSyncSourceConfig> source_config =
context->getSyncSourceConfig(source); context->getSyncSourceConfig(source);
if (!source_config->isDisabled()) { if (!source_config->isDisabled()) {
context->setConfigFilter(false, source, m_props.createSourceFilter(m_server, source)); context->setConfigFilter(false, source, m_props.createSourceFilter(m_server, source));
@ -1626,7 +1619,7 @@ bool Cmdline::run() {
} else { } else {
// apply (possibly empty) source filter to selected sources // apply (possibly empty) source filter to selected sources
for (const std::string &source: m_sources) { for (const std::string &source: m_sources) {
boost::shared_ptr<PersistentSyncSourceConfig> source_config = std::shared_ptr<PersistentSyncSourceConfig> source_config =
context->getSyncSourceConfig(source); context->getSyncSourceConfig(source);
ConfigProps filter = m_props.createSourceFilter(m_server, source); ConfigProps filter = m_props.createSourceFilter(m_server, source);
if (!source_config || !source_config->exists()) { if (!source_config || !source_config->exists()) {
@ -1721,10 +1714,13 @@ bool Cmdline::run() {
void Cmdline::readLUIDs(SyncSource *source, list<string> &luids) void Cmdline::readLUIDs(SyncSource *source, list<string> &luids)
{ {
processLUIDs(source, boost::bind(static_cast<void (list<string>::*)(const string &)>(&list<string>::push_back), boost::ref(luids), _1)); auto append = [&luids] (const std::string &luid) {
luids.push_back(luid);
};
processLUIDs(source, append);
} }
void Cmdline::processLUIDs(SyncSource *source, const boost::function<void (const std::string &)> &process) void Cmdline::processLUIDs(SyncSource *source, const std::function<void (const std::string &)> &process)
{ {
const SyncSource::Operations &ops = source->getOperations(); const SyncSource::Operations &ops = source->getOperations();
sysync::ItemIDType id; sysync::ItemIDType id;
@ -3298,7 +3294,7 @@ protected:
rm_r(m_testDir); rm_r(m_testDir);
{ {
TestCmdline cmdline(NULL, NULL); TestCmdline cmdline(NULL, NULL);
boost::shared_ptr<SyncContext> context = cmdline.parse(); std::shared_ptr<SyncContext> context = cmdline.parse();
CPPUNIT_ASSERT(context); CPPUNIT_ASSERT(context);
InitStateTri keyring = context->getKeyring(); InitStateTri keyring = context->getKeyring();
CPPUNIT_ASSERT_EQUAL(false, keyring.wasSet()); CPPUNIT_ASSERT_EQUAL(false, keyring.wasSet());
@ -3306,7 +3302,7 @@ protected:
} }
{ {
TestCmdline cmdline("--keyring", NULL); TestCmdline cmdline("--keyring", NULL);
boost::shared_ptr<SyncContext> context = cmdline.parse(); std::shared_ptr<SyncContext> context = cmdline.parse();
CPPUNIT_ASSERT(context); CPPUNIT_ASSERT(context);
InitStateTri keyring = context->getKeyring(); InitStateTri keyring = context->getKeyring();
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet()); CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
@ -3314,7 +3310,7 @@ protected:
} }
{ {
TestCmdline cmdline("--sync-property", "keyring=True", NULL); TestCmdline cmdline("--sync-property", "keyring=True", NULL);
boost::shared_ptr<SyncContext> context = cmdline.parse(); std::shared_ptr<SyncContext> context = cmdline.parse();
CPPUNIT_ASSERT(context); CPPUNIT_ASSERT(context);
InitStateTri keyring = context->getKeyring(); InitStateTri keyring = context->getKeyring();
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet()); CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
@ -3322,7 +3318,7 @@ protected:
} }
{ {
TestCmdline cmdline("keyring=True", NULL); TestCmdline cmdline("keyring=True", NULL);
boost::shared_ptr<SyncContext> context = cmdline.parse(); std::shared_ptr<SyncContext> context = cmdline.parse();
CPPUNIT_ASSERT(context); CPPUNIT_ASSERT(context);
InitStateTri keyring = context->getKeyring(); InitStateTri keyring = context->getKeyring();
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet()); CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
@ -3330,7 +3326,7 @@ protected:
} }
{ {
TestCmdline cmdline("--keyring=true", NULL); TestCmdline cmdline("--keyring=true", NULL);
boost::shared_ptr<SyncContext> context = cmdline.parse(); std::shared_ptr<SyncContext> context = cmdline.parse();
CPPUNIT_ASSERT(context); CPPUNIT_ASSERT(context);
InitStateTri keyring = context->getKeyring(); InitStateTri keyring = context->getKeyring();
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet()); CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
@ -3338,7 +3334,7 @@ protected:
} }
{ {
TestCmdline cmdline("--keyring=1", NULL); TestCmdline cmdline("--keyring=1", NULL);
boost::shared_ptr<SyncContext> context = cmdline.parse(); std::shared_ptr<SyncContext> context = cmdline.parse();
CPPUNIT_ASSERT(context); CPPUNIT_ASSERT(context);
InitStateTri keyring = context->getKeyring(); InitStateTri keyring = context->getKeyring();
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet()); CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
@ -3346,7 +3342,7 @@ protected:
} }
{ {
TestCmdline cmdline("--keyring=Yes", NULL); TestCmdline cmdline("--keyring=Yes", NULL);
boost::shared_ptr<SyncContext> context = cmdline.parse(); std::shared_ptr<SyncContext> context = cmdline.parse();
CPPUNIT_ASSERT(context); CPPUNIT_ASSERT(context);
InitStateTri keyring = context->getKeyring(); InitStateTri keyring = context->getKeyring();
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet()); CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
@ -3354,7 +3350,7 @@ protected:
} }
{ {
TestCmdline cmdline("--keyring=false", NULL); TestCmdline cmdline("--keyring=false", NULL);
boost::shared_ptr<SyncContext> context = cmdline.parse(); std::shared_ptr<SyncContext> context = cmdline.parse();
CPPUNIT_ASSERT(context); CPPUNIT_ASSERT(context);
InitStateTri keyring = context->getKeyring(); InitStateTri keyring = context->getKeyring();
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet()); CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
@ -3362,7 +3358,7 @@ protected:
} }
{ {
TestCmdline cmdline("--keyring=0", NULL); TestCmdline cmdline("--keyring=0", NULL);
boost::shared_ptr<SyncContext> context = cmdline.parse(); std::shared_ptr<SyncContext> context = cmdline.parse();
CPPUNIT_ASSERT(context); CPPUNIT_ASSERT(context);
InitStateTri keyring = context->getKeyring(); InitStateTri keyring = context->getKeyring();
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet()); CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
@ -3370,7 +3366,7 @@ protected:
} }
{ {
TestCmdline cmdline("--keyring=NO", NULL); TestCmdline cmdline("--keyring=NO", NULL);
boost::shared_ptr<SyncContext> context = cmdline.parse(); std::shared_ptr<SyncContext> context = cmdline.parse();
CPPUNIT_ASSERT(context); CPPUNIT_ASSERT(context);
InitStateTri keyring = context->getKeyring(); InitStateTri keyring = context->getKeyring();
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet()); CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
@ -3378,7 +3374,7 @@ protected:
} }
{ {
TestCmdline cmdline("--keyring=GNOME", NULL); TestCmdline cmdline("--keyring=GNOME", NULL);
boost::shared_ptr<SyncContext> context = cmdline.parse(); std::shared_ptr<SyncContext> context = cmdline.parse();
CPPUNIT_ASSERT(context); CPPUNIT_ASSERT(context);
InitStateTri keyring = context->getKeyring(); InitStateTri keyring = context->getKeyring();
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet()); CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
@ -3422,7 +3418,7 @@ protected:
{ {
TestCmdline cmdline("@foobar", NULL); TestCmdline cmdline("@foobar", NULL);
boost::shared_ptr<SyncContext> context = cmdline.parse(); std::shared_ptr<SyncContext> context = cmdline.parse();
CPPUNIT_ASSERT(context); CPPUNIT_ASSERT(context);
InitStateTri keyring = context->getKeyring(); InitStateTri keyring = context->getKeyring();
CPPUNIT_ASSERT_EQUAL(false, keyring.wasSet()); CPPUNIT_ASSERT_EQUAL(false, keyring.wasSet());
@ -3433,7 +3429,7 @@ protected:
{ {
TestCmdline cmdline("--keyring", "--configure", "@default", NULL); TestCmdline cmdline("--keyring", "--configure", "@default", NULL);
cmdline.doit(); cmdline.doit();
boost::shared_ptr<SyncContext> context = cmdline.parse(); std::shared_ptr<SyncContext> context = cmdline.parse();
CPPUNIT_ASSERT(context); CPPUNIT_ASSERT(context);
InitStateTri keyring = context->getKeyring(); InitStateTri keyring = context->getKeyring();
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet()); CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
@ -3442,7 +3438,7 @@ protected:
{ {
TestCmdline cmdline("--keyring=KDE", "--configure", "@default", NULL); TestCmdline cmdline("--keyring=KDE", "--configure", "@default", NULL);
cmdline.doit(); cmdline.doit();
boost::shared_ptr<SyncContext> context = cmdline.parse(); std::shared_ptr<SyncContext> context = cmdline.parse();
CPPUNIT_ASSERT(context); CPPUNIT_ASSERT(context);
InitStateTri keyring = context->getKeyring(); InitStateTri keyring = context->getKeyring();
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet()); CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
@ -3456,7 +3452,7 @@ protected:
{ {
TestCmdline cmdline("keyring=KDE", "--configure", "@default", NULL); TestCmdline cmdline("keyring=KDE", "--configure", "@default", NULL);
cmdline.doit(); cmdline.doit();
boost::shared_ptr<SyncContext> context = cmdline.parse(); std::shared_ptr<SyncContext> context = cmdline.parse();
CPPUNIT_ASSERT(context); CPPUNIT_ASSERT(context);
InitStateTri keyring = context->getKeyring(); InitStateTri keyring = context->getKeyring();
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet()); CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
@ -3465,7 +3461,7 @@ protected:
{ {
TestCmdline cmdline("keyring=yes", "--configure", "@default", NULL); TestCmdline cmdline("keyring=yes", "--configure", "@default", NULL);
cmdline.doit(); cmdline.doit();
boost::shared_ptr<SyncContext> context = cmdline.parse(); std::shared_ptr<SyncContext> context = cmdline.parse();
CPPUNIT_ASSERT(context); CPPUNIT_ASSERT(context);
InitStateTri keyring = context->getKeyring(); InitStateTri keyring = context->getKeyring();
CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet()); CPPUNIT_ASSERT_EQUAL(true, keyring.wasSet());
@ -4415,7 +4411,7 @@ private:
*/ */
class TestCmdline : public Logger { class TestCmdline : public Logger {
void init() { void init() {
addLogger(boost::shared_ptr<Logger>(this, NopDestructor())); addLogger(std::shared_ptr<Logger>(this, NopDestructor()));
m_argv.reset(new const char *[m_argvstr.size() + 1]); m_argv.reset(new const char *[m_argvstr.size() + 1]);
m_argv[0] = "client-test"; m_argv[0] = "client-test";
@ -4452,12 +4448,12 @@ private:
removeLogger(this); removeLogger(this);
} }
boost::shared_ptr<SyncContext> parse() std::shared_ptr<SyncContext> parse()
{ {
if (!m_cmdline->parse()) { if (!m_cmdline->parse()) {
return boost::shared_ptr<SyncContext>(); return std::shared_ptr<SyncContext>();
} }
boost::shared_ptr<SyncContext> context(new SyncContext(m_cmdline->m_server)); auto context = std::make_shared<SyncContext>(m_cmdline->m_server);
context->setConfigFilter(true, "", m_cmdline->m_props.createSyncFilter(m_cmdline->m_server)); context->setConfigFilter(true, "", m_cmdline->m_props.createSyncFilter(m_cmdline->m_server));
return context; return context;
} }

View File

@ -25,8 +25,8 @@
#include <syncevo/util.h> #include <syncevo/util.h>
#include <set> #include <set>
#include <memory>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_array.hpp> #include <boost/scoped_array.hpp>
#include <syncevo/declarations.h> #include <syncevo/declarations.h>
@ -178,7 +178,7 @@ protected:
* rename file or directory by appending .old or (if that already * rename file or directory by appending .old or (if that already
* exists) .old.x for x >= 1; updates config to point to the renamed directory * exists) .old.x for x >= 1; updates config to point to the renamed directory
*/ */
void makeObsolete(boost::shared_ptr<SyncConfig> &from); void makeObsolete(std::shared_ptr<SyncConfig> &from);
/** /**
* Copy from one config into another, with filters * Copy from one config into another, with filters
@ -186,15 +186,15 @@ protected:
* if selectedSources is empty, otherwise only * if selectedSources is empty, otherwise only
* those. * those.
*/ */
void copyConfig(const boost::shared_ptr<SyncConfig> &from, void copyConfig(const std::shared_ptr<SyncConfig> &from,
const boost::shared_ptr<SyncConfig> &to, const std::shared_ptr<SyncConfig> &to,
const std::set<std::string> &selectedSources); const std::set<std::string> &selectedSources);
/** /**
* flush, move .synthesis dir, set ConsumerReady, ... * flush, move .synthesis dir, set ConsumerReady, ...
*/ */
void finishCopy(const boost::shared_ptr<SyncConfig> &from, void finishCopy(const std::shared_ptr<SyncConfig> &from,
const boost::shared_ptr<SyncContext> &to); const std::shared_ptr<SyncContext> &to);
/** /**
* migrate peer config; target context must be ready * migrate peer config; target context must be ready
@ -324,7 +324,7 @@ protected:
/** /**
* Invoke a callback for each local ID. * Invoke a callback for each local ID.
*/ */
void processLUIDs(SyncSource *source, const boost::function<void (const std::string &)> &callback); void processLUIDs(SyncSource *source, const std::function<void (const std::string &)> &callback);
/** /**
* Add or update one item. * Add or update one item.

View File

@ -164,7 +164,7 @@ void FullProps::createFilters(const std::string &context,
ConfigProps &syncFilter, ConfigProps &syncFilter,
SourceProps &sourceFilters) SourceProps &sourceFilters)
{ {
boost::shared_ptr<SyncConfig> shared; std::shared_ptr<SyncConfig> shared;
if (!context.empty()) { if (!context.empty()) {
// Read from context. If it does not exist, we simply set no properties // Read from context. If it does not exist, we simply set no properties

View File

@ -26,10 +26,10 @@
SE_BEGIN_CXX SE_BEGIN_CXX
boost::shared_ptr<ConfigNode> ConfigNode::createFileNode(const std::string &filename) std::shared_ptr<ConfigNode> ConfigNode::createFileNode(const std::string &filename)
{ {
std::string::size_type off = filename.rfind('/'); std::string::size_type off = filename.rfind('/');
boost::shared_ptr<ConfigNode> filenode; std::shared_ptr<ConfigNode> filenode;
if (off != filename.npos) { if (off != filename.npos) {
filenode.reset(new IniFileConfigNode(filename.substr(0, off), filenode.reset(new IniFileConfigNode(filename.substr(0, off),
filename.substr(off + 1), filename.substr(off + 1),
@ -37,7 +37,7 @@ boost::shared_ptr<ConfigNode> ConfigNode::createFileNode(const std::string &file
} else { } else {
filenode.reset(new IniFileConfigNode(".", filename, false)); filenode.reset(new IniFileConfigNode(".", filename, false));
} }
boost::shared_ptr<SafeConfigNode> savenode(new SafeConfigNode(filenode)); auto savenode = std::make_shared<SafeConfigNode>(filenode);
savenode->setMode(false); savenode->setMode(false);
return savenode; return savenode;
} }

View File

@ -24,8 +24,8 @@
#include <utility> #include <utility>
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <memory>
#include <boost/shared_ptr.hpp>
#include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/predicate.hpp>
#include <syncevo/declarations.h> #include <syncevo/declarations.h>
@ -47,7 +47,7 @@ class ConfigNode {
virtual ~ConfigNode() {} virtual ~ConfigNode() {}
/** creates a file-backed config node which accepts arbitrary key/value pairs */ /** creates a file-backed config node which accepts arbitrary key/value pairs */
static boost::shared_ptr<ConfigNode> createFileNode(const std::string &filename); static std::shared_ptr<ConfigNode> createFileNode(const std::string &filename);
/** a name for the node that the user can understand */ /** a name for the node that the user can understand */
virtual std::string getName() const = 0; virtual std::string getName() const = 0;

View File

@ -20,7 +20,7 @@
#ifndef INCL_EVOLUTION_CONFIG_TREE #ifndef INCL_EVOLUTION_CONFIG_TREE
# define INCL_EVOLUTION_CONFIG_TREE # define INCL_EVOLUTION_CONFIG_TREE
#include <boost/shared_ptr.hpp> #include <memory>
#include <map> #include <map>
#include <list> #include <list>
#include <string> #include <string>
@ -104,7 +104,7 @@ class ConfigTree {
* node's name (allows having multiple different such * node's name (allows having multiple different such
* nodes); an empty string is allowed * nodes); an empty string is allowed
*/ */
virtual boost::shared_ptr<ConfigNode> open(const std::string &path, virtual std::shared_ptr<ConfigNode> open(const std::string &path,
PropertyType type, PropertyType type,
const std::string &otherId = std::string("")) = 0; const std::string &otherId = std::string("")) = 0;
@ -121,8 +121,8 @@ class ConfigTree {
* @param node default instance if not opened before, discarded if a * @param node default instance if not opened before, discarded if a
* node was registered or opened under the given path before * node was registered or opened under the given path before
*/ */
virtual boost::shared_ptr<ConfigNode> add(const std::string &path, virtual std::shared_ptr<ConfigNode> add(const std::string &path,
const boost::shared_ptr<ConfigNode> &node) = 0; const std::shared_ptr<ConfigNode> &node) = 0;
/** /**
* returns names of all existing nodes beneath the given path * returns names of all existing nodes beneath the given path

View File

@ -21,7 +21,7 @@
# define INCL_EVOLUTION_DATA_BLOB # define INCL_EVOLUTION_DATA_BLOB
#include <iostream> #include <iostream>
#include <boost/shared_ptr.hpp> #include <memory>
#include <syncevo/declarations.h> #include <syncevo/declarations.h>
SE_BEGIN_CXX SE_BEGIN_CXX
@ -41,12 +41,12 @@ class DataBlob
* Create stream for writing data. * Create stream for writing data.
* Always overwrites old data. * Always overwrites old data.
*/ */
virtual boost::shared_ptr<std::ostream> write() = 0; virtual std::shared_ptr<std::ostream> write() = 0;
/** /**
* Create stream for reading data. * Create stream for reading data.
*/ */
virtual boost::shared_ptr<std::istream> read() = 0; virtual std::shared_ptr<std::istream> read() = 0;
/** some kind of user visible name for the data */ /** some kind of user visible name for the data */
virtual std::string getName() const = 0; virtual std::string getName() const = 0;

View File

@ -24,9 +24,9 @@
#include <syncevo/declarations.h> #include <syncevo/declarations.h>
SE_BEGIN_CXX SE_BEGIN_CXX
EDSRegistryLoader &EDSRegistryLoaderSingleton(const boost::shared_ptr<EDSRegistryLoader> &loader) EDSRegistryLoader &EDSRegistryLoaderSingleton(const std::shared_ptr<EDSRegistryLoader> &loader)
{ {
static boost::shared_ptr<EDSRegistryLoader> singleton; static std::shared_ptr<EDSRegistryLoader> singleton;
if (!singleton) { if (!singleton) {
singleton = loader; singleton = loader;
} }

View File

@ -22,16 +22,17 @@
#include <config.h> #include <config.h>
#include <boost/shared_ptr.hpp> #include <memory>
#if defined(HAVE_EDS) && defined(USE_EDS_CLIENT) #if defined(HAVE_EDS) && defined(USE_EDS_CLIENT)
#include <syncevo/GLibSupport.h> #include <syncevo/GLibSupport.h>
#include <libedataserver/libedataserver.h> #include <libedataserver/libedataserver.h>
#include <boost/function.hpp>
#include <boost/utility.hpp> #include <boost/utility.hpp>
#include <boost/bind.hpp> #include <functional>
#include <functional>
#include <list> #include <list>
typedef SyncEvo::GListCXX<ESource, GList, SyncEvo::GObjectDestructor> ESourceListCXX; typedef SyncEvo::GListCXX<ESource, GList, SyncEvo::GObjectDestructor> ESourceListCXX;
@ -48,7 +49,7 @@ SE_BEGIN_CXX
// It may get used by backends which were compiled against // It may get used by backends which were compiled against
// EDS >= 3.6 even when the libsyncevolution itself wasn't. // EDS >= 3.6 even when the libsyncevolution itself wasn't.
class EDSRegistryLoader; class EDSRegistryLoader;
EDSRegistryLoader &EDSRegistryLoaderSingleton(const boost::shared_ptr<EDSRegistryLoader> &loader); EDSRegistryLoader &EDSRegistryLoaderSingleton(const std::shared_ptr<EDSRegistryLoader> &loader);
// The following code implements EDSRegistryLoader. // The following code implements EDSRegistryLoader.
// For the sake of simplicity, its all in the header file, // For the sake of simplicity, its all in the header file,
@ -65,7 +66,7 @@ EDSRegistryLoader &EDSRegistryLoaderSingleton(const boost::shared_ptr<EDSRegistr
class EDSRegistryLoader : private boost::noncopyable class EDSRegistryLoader : private boost::noncopyable
{ {
public: public:
typedef boost::function<void (const ESourceRegistryCXX &registry, typedef std::function<void (const ESourceRegistryCXX &registry,
const GError *gerror)> Callback_t; const GError *gerror)> Callback_t;
/** /**
@ -74,7 +75,7 @@ class EDSRegistryLoader : private boost::noncopyable
*/ */
static void getESourceRegistryAsync(const Callback_t &cb) static void getESourceRegistryAsync(const Callback_t &cb)
{ {
EDSRegistryLoaderSingleton(boost::shared_ptr<EDSRegistryLoader>(new EDSRegistryLoader)).async(cb); EDSRegistryLoaderSingleton(std::make_shared<EDSRegistryLoader>()).async(cb);
} }
/** /**
@ -82,7 +83,7 @@ class EDSRegistryLoader : private boost::noncopyable
*/ */
static ESourceRegistryCXX getESourceRegistry() static ESourceRegistryCXX getESourceRegistry()
{ {
return EDSRegistryLoaderSingleton(boost::shared_ptr<EDSRegistryLoader>(new EDSRegistryLoader)).sync(); return EDSRegistryLoaderSingleton(std::make_shared<EDSRegistryLoader>()).sync();
} }
private: private:

View File

@ -131,7 +131,7 @@ void FileConfigTree::clearNodes(const std::string &fullpath)
} }
} }
boost::shared_ptr<ConfigNode> FileConfigTree::open(const std::string &path, std::shared_ptr<ConfigNode> FileConfigTree::open(const std::string &path,
ConfigTree::PropertyType type, ConfigTree::PropertyType type,
const std::string &otherId) const std::string &otherId)
{ {
@ -167,16 +167,16 @@ boost::shared_ptr<ConfigNode> FileConfigTree::open(const std::string &path,
if (found != m_nodes.end()) { if (found != m_nodes.end()) {
return found->second; return found->second;
} else if(type != other && type != server) { } else if(type != other && type != server) {
boost::shared_ptr<ConfigNode> node(new IniFileConfigNode(fullpath, filename, m_readonly)); auto node = std::make_shared<IniFileConfigNode>(fullpath, filename, m_readonly);
return m_nodes[fullname] = node; return m_nodes[fullname] = node;
} else { } else {
boost::shared_ptr<ConfigNode> node(new IniHashConfigNode(fullpath, filename, m_readonly)); auto node = std::make_shared<IniHashConfigNode>(fullpath, filename, m_readonly);
return m_nodes[fullname] = node; return m_nodes[fullname] = node;
} }
} }
boost::shared_ptr<ConfigNode> FileConfigTree::add(const std::string &path, std::shared_ptr<ConfigNode> FileConfigTree::add(const std::string &path,
const boost::shared_ptr<ConfigNode> &node) const std::shared_ptr<ConfigNode> &node)
{ {
NodeCache_t::iterator found = m_nodes.find(path); NodeCache_t::iterator found = m_nodes.find(path);
if (found != m_nodes.end()) { if (found != m_nodes.end()) {

View File

@ -56,11 +56,11 @@ class FileConfigTree : public ConfigTree {
virtual void reload(); virtual void reload();
virtual void remove(const std::string &path); virtual void remove(const std::string &path);
virtual void reset(); virtual void reset();
virtual boost::shared_ptr<ConfigNode> open(const std::string &path, virtual std::shared_ptr<ConfigNode> open(const std::string &path,
PropertyType type, PropertyType type,
const std::string &otherId = std::string("")); const std::string &otherId = std::string(""));
virtual boost::shared_ptr<ConfigNode> add(const std::string &path, virtual std::shared_ptr<ConfigNode> add(const std::string &path,
const boost::shared_ptr<ConfigNode> &node); const std::shared_ptr<ConfigNode> &node);
std::list<std::string> getChildren(const std::string &path); std::list<std::string> getChildren(const std::string &path);
private: private:
@ -75,7 +75,7 @@ class FileConfigTree : public ConfigTree {
SyncConfig::Layout m_layout; SyncConfig::Layout m_layout;
bool m_readonly; bool m_readonly;
typedef std::map< std::string, boost::shared_ptr<ConfigNode> > NodeCache_t; typedef std::map< std::string, std::shared_ptr<ConfigNode> > NodeCache_t;
/** cache of all nodes ever accessed */ /** cache of all nodes ever accessed */
NodeCache_t m_nodes; NodeCache_t m_nodes;
}; };

View File

@ -39,7 +39,7 @@ FileDataBlob::FileDataBlob(const std::string &fullpath, bool readonly) :
splitPath(fullpath, m_path, m_fileName); splitPath(fullpath, m_path, m_fileName);
} }
boost::shared_ptr<std::ostream> FileDataBlob::write() std::shared_ptr<std::ostream> FileDataBlob::write()
{ {
if (m_readonly) { if (m_readonly) {
SE_THROW(getName() + ": internal error: attempt to write read-only FileDataBlob"); SE_THROW(getName() + ": internal error: attempt to write read-only FileDataBlob");
@ -47,13 +47,13 @@ boost::shared_ptr<std::ostream> FileDataBlob::write()
mkdir_p(m_path); mkdir_p(m_path);
boost::shared_ptr<std::ostream> file(new SafeOstream(getName())); auto file = std::make_shared<SafeOstream>(getName());
return file; return file;
} }
boost::shared_ptr<std::istream> FileDataBlob::read() std::shared_ptr<std::istream> FileDataBlob::read()
{ {
boost::shared_ptr<std::istream> file(new std::ifstream(getName().c_str())); auto file = std::make_shared<std::ifstream>(getName().c_str());
return file; return file;
} }

View File

@ -48,8 +48,8 @@ class FileDataBlob : public DataBlob
FileDataBlob(const std::string &path, const std::string &fileName, bool readonly); FileDataBlob(const std::string &path, const std::string &fileName, bool readonly);
FileDataBlob(const std::string &fullpath, bool readonly); FileDataBlob(const std::string &fullpath, bool readonly);
boost::shared_ptr<std::ostream> write(); std::shared_ptr<std::ostream> write();
boost::shared_ptr<std::istream> read(); std::shared_ptr<std::istream> read();
virtual std::string getName() const; virtual std::string getName() const;
virtual bool exists() const; virtual bool exists() const;

View File

@ -25,7 +25,7 @@
#include <syncevo/declarations.h> #include <syncevo/declarations.h>
SE_BEGIN_CXX SE_BEGIN_CXX
FilterConfigNode::FilterConfigNode(const boost::shared_ptr<ConfigNode> &node, FilterConfigNode::FilterConfigNode(const std::shared_ptr<ConfigNode> &node,
const ConfigFilter &filter) : const ConfigFilter &filter) :
m_filter(filter), m_filter(filter),
m_node(node), m_node(node),
@ -33,7 +33,7 @@ FilterConfigNode::FilterConfigNode(const boost::shared_ptr<ConfigNode> &node,
{ {
} }
FilterConfigNode::FilterConfigNode(const boost::shared_ptr<const ConfigNode> &node, FilterConfigNode::FilterConfigNode(const std::shared_ptr<const ConfigNode> &node,
const ConfigFilter &filter) : const ConfigFilter &filter) :
m_filter(filter), m_filter(filter),
m_readOnlyNode(node) m_readOnlyNode(node)

View File

@ -21,11 +21,11 @@
# define INCL_EVOLUTION_FILTER_CONFIG_NODE # define INCL_EVOLUTION_FILTER_CONFIG_NODE
#include <syncevo/ConfigNode.h> #include <syncevo/ConfigNode.h>
#include <boost/shared_ptr.hpp>
#include <boost/algorithm/string/case_conv.hpp> #include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <map> #include <map>
#include <memory>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <string> #include <string>
@ -48,11 +48,11 @@ class FilterConfigNode : public ConfigNode {
typedef ConfigProps ConfigFilter; typedef ConfigProps ConfigFilter;
/** read-write access to underlying node */ /** read-write access to underlying node */
FilterConfigNode(const boost::shared_ptr<ConfigNode> &node, FilterConfigNode(const std::shared_ptr<ConfigNode> &node,
const ConfigFilter &filter = ConfigFilter()); const ConfigFilter &filter = ConfigFilter());
/** read-only access to underlying node */ /** read-only access to underlying node */
FilterConfigNode(const boost::shared_ptr<const ConfigNode> &node, FilterConfigNode(const std::shared_ptr<const ConfigNode> &node,
const ConfigFilter &filter = ConfigFilter()); const ConfigFilter &filter = ConfigFilter());
virtual std::string getName() const { return m_readOnlyNode->getName(); } virtual std::string getName() const { return m_readOnlyNode->getName(); }
@ -80,8 +80,8 @@ class FilterConfigNode : public ConfigNode {
private: private:
ConfigFilter m_filter; ConfigFilter m_filter;
boost::shared_ptr<ConfigNode> m_node; std::shared_ptr<ConfigNode> m_node;
boost::shared_ptr<const ConfigNode> m_readOnlyNode; std::shared_ptr<const ConfigNode> m_readOnlyNode;
}; };

Some files were not shown because too many files have changed in this diff Show More