summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Ohly <patrick.ohly@intel.com>2013-05-13 21:33:34 +0200
committerPatrick Ohly <patrick.ohly@intel.com>2013-05-16 11:19:32 +0200
commitd3eee8a0390558795ace8be503b44d76be385b13 (patch)
tree1a6d9442af43632cb2e1db172653f97dd005c4b1
parentfb83c468a8ba554e40bb5fbb746154fd1d6cd0c2 (diff)
glib: stricter ref counting
Following the boost::instrusive_ptr example and making "add_ref = true" the default in our CXX GLib and GObject wrappers led to some memory leaks because it didn't enforce thinking about whether the plain pointer is already owned by us or not. It is better to use a mandatory enum value, ADD_REF and TRANSFER_REF, and force explicit construction. Doing that revealed that the assignment operator was implemented as constructing a CXX instance with increased ref count and/or that in some places, a real leak was caused by increasing the ref count unnecessarily. Running under valgrind gave a false sense of security. Some of the real leaks only showed up randomly in tests.
-rw-r--r--src/backends/evolution/EvolutionCalendarSource.cpp8
-rw-r--r--src/backends/evolution/EvolutionContactSource.cpp6
-rw-r--r--src/backends/evolution/EvolutionSyncSource.cpp8
-rw-r--r--src/backends/evolution/EvolutionSyncSource.h2
-rw-r--r--src/dbus/server/pim/edsf-view.cpp8
-rw-r--r--src/dbus/server/pim/folks.cpp18
-rw-r--r--src/dbus/server/pim/full-view.cpp2
-rw-r--r--src/dbus/server/pim/individual-traits.cpp38
-rw-r--r--src/dbus/server/pim/locale-factory-boost.cpp4
-rw-r--r--src/syncevo/GLibSupport.cpp6
-rw-r--r--src/syncevo/GLibSupport.h25
-rw-r--r--src/syncevo/GeeSupport.h6
-rw-r--r--src/syncevo/LocalTransportAgent.cpp4
-rw-r--r--test/dbus-client-server.cpp2
14 files changed, 75 insertions, 62 deletions
diff --git a/src/backends/evolution/EvolutionCalendarSource.cpp b/src/backends/evolution/EvolutionCalendarSource.cpp
index f9cdf1f3..cb01eb44 100644
--- a/src/backends/evolution/EvolutionCalendarSource.cpp
+++ b/src/backends/evolution/EvolutionCalendarSource.cpp
@@ -156,7 +156,7 @@ SyncSource::Databases EvolutionCalendarSource::getDatabases()
throwError("unable to access backend databases", gerror);
}
}
- ESourceListCXX sources(tmp, false);
+ ESourceListCXX sources(tmp, TRANSFER_REF);
bool first = true;
for (GSList *g = sources ? e_source_list_peek_groups (sources) : NULL;
g;
@@ -240,7 +240,7 @@ void EvolutionCalendarSource::open()
if (!e_cal_get_sources(&tmp, sourceType(), gerror)) {
throwError("unable to access backend databases", gerror);
}
- ESourceListCXX sources(tmp, false);
+ ESourceListCXX sources(tmp, TRANSFER_REF);
string id = getDatabaseID();
ESource *source = findSource(sources, id);
@@ -430,7 +430,7 @@ void EvolutionCalendarSource::listAllItems(RevisionMap_t &revisions)
void EvolutionCalendarSource::close()
{
- m_calendar = NULL;
+ m_calendar.reset();
}
void EvolutionCalendarSource::readItem(const string &luid, std::string &item, bool raw)
@@ -858,7 +858,7 @@ void EvolutionCalendarSource::removeItem(const string &luid)
* remove all items with the given uid and if we only wanted to
* delete the parent, then recreate the children.
*/
- ICalComps_t children = removeEvents(id.m_uid, true, false);
+ ICalComps_t children = removeEvents(id.m_uid, true, TRANSFER_REF);
// recreate children
bool first = true;
diff --git a/src/backends/evolution/EvolutionContactSource.cpp b/src/backends/evolution/EvolutionContactSource.cpp
index 05821055..ea23d615 100644
--- a/src/backends/evolution/EvolutionContactSource.cpp
+++ b/src/backends/evolution/EvolutionContactSource.cpp
@@ -177,7 +177,7 @@ void EvolutionContactSource::open()
if (!e_book_get_addressbooks(&tmp, gerror)) {
throwError("unable to access address books", gerror);
}
- ESourceListCXX sources(tmp, false);
+ ESourceListCXX sources(tmp, TRANSFER_REF);
string id = getDatabaseID();
ESource *source = findSource(sources, id);
@@ -347,7 +347,7 @@ void EvolutionContactSource::listAllItems(RevisionMap_t &revisions)
GErrorCXX gerror;
EBookClientView *view;
- EBookQueryCXX allItemsQuery(e_book_query_any_field_contains(""), false);
+ EBookQueryCXX allItemsQuery(e_book_query_any_field_contains(""), TRANSFER_REF);
PlainGStr sexp(e_book_query_to_string (allItemsQuery.get()));
if (!e_book_client_get_view_sync(m_addressbook, sexp, &view, NULL, gerror)) {
@@ -403,7 +403,7 @@ void EvolutionContactSource::listAllItems(RevisionMap_t &revisions)
void EvolutionContactSource::close()
{
- m_addressbook = NULL;
+ m_addressbook.reset();
}
string EvolutionContactSource::getRevision(const string &luid)
diff --git a/src/backends/evolution/EvolutionSyncSource.cpp b/src/backends/evolution/EvolutionSyncSource.cpp
index e39a5302..f569082b 100644
--- a/src/backends/evolution/EvolutionSyncSource.cpp
+++ b/src/backends/evolution/EvolutionSyncSource.cpp
@@ -36,7 +36,7 @@ void EvolutionSyncSource::getDatabasesFromRegistry(SyncSource::Databases &result
ESourceRegistryCXX registry = EDSRegistryLoader::getESourceRegistry();
ESourceListCXX sources(e_source_registry_list_sources(registry, extension));
ESourceCXX def(refDef ? refDef(registry) : NULL,
- false);
+ TRANSFER_REF);
BOOST_FOREACH (ESource *source, sources) {
result.push_back(Database(e_source_get_display_name(source),
e_source_get_uid(source),
@@ -64,7 +64,7 @@ EClientCXX EvolutionSyncSource::openESource(const char *extension,
if (!source) {
if (refBuiltin && (id.empty() || id == "<<system>>")) {
- ESourceCXX builtin(refBuiltin(registry), false);
+ ESourceCXX builtin(refBuiltin(registry), TRANSFER_REF);
client = EClientCXX::steal(newClient(builtin, gerror));
// } else if (!id.compare(0, 7, "file://")) {
// TODO: create source
@@ -129,7 +129,7 @@ SyncSource::Database EvolutionSyncSource::createDatabase(const Database &databas
e_source_new(NULL, NULL, gerror) :
e_source_new_with_uid(database.m_uri.c_str(),
NULL, gerror),
- false);
+ TRANSFER_REF);
if (!source) {
gerror.throwError("e_source_new()");
}
@@ -179,7 +179,7 @@ SyncSource::Database EvolutionSyncSource::createDatabase(const Database &databas
void EvolutionSyncSource::deleteDatabase(const std::string &uri)
{
ESourceRegistryCXX registry = EDSRegistryLoader::getESourceRegistry();
- ESourceCXX source(e_source_registry_ref_source(registry, uri.c_str()), false);
+ ESourceCXX source(e_source_registry_ref_source(registry, uri.c_str()), TRANSFER_REF);
if (!source) {
throwError(StringPrintf("EDS database with URI '%s' cannot be deleted, does not exist",
uri.c_str()));
diff --git a/src/backends/evolution/EvolutionSyncSource.h b/src/backends/evolution/EvolutionSyncSource.h
index dfaa67c2..9e1ca618 100644
--- a/src/backends/evolution/EvolutionSyncSource.h
+++ b/src/backends/evolution/EvolutionSyncSource.h
@@ -120,7 +120,7 @@ class EvolutionAsync {
public:
EvolutionAsync()
{
- m_loop = GMainLoopCXX(g_main_loop_new(NULL, TRUE), false);
+ m_loop = GMainLoopStealCXX(g_main_loop_new(NULL, TRUE));
}
/** start processing events */
diff --git a/src/dbus/server/pim/edsf-view.cpp b/src/dbus/server/pim/edsf-view.cpp
index e0c1c531..8bc2a418 100644
--- a/src/dbus/server/pim/edsf-view.cpp
+++ b/src/dbus/server/pim/edsf-view.cpp
@@ -51,7 +51,7 @@ void EDSFView::doStart()
{
// This function may get entered again, see retry code in opened() below.
- ESourceCXX source(e_source_registry_ref_source(m_registry, m_uuid.c_str()), false);
+ ESourceCXX source(e_source_registry_ref_source(m_registry, m_uuid.c_str()), TRANSFER_REF);
if (!source) {
SE_LOG_DEBUG(NULL, "edsf %s: address book not found", m_uuid.c_str());
return;
@@ -139,10 +139,10 @@ void EDSFView::read(gboolean success, GSList *contactslist, const GError *gerror
}
BOOST_FOREACH (EContact *contact, contacts) {
- EdsfPersonaCXX persona(edsf_persona_new(m_store, contact), false);
- GeeHashSetCXX personas(gee_hash_set_new(G_TYPE_OBJECT, g_object_ref, g_object_unref, NULL, NULL, NULL, NULL, NULL, NULL), false);
+ EdsfPersonaCXX persona(edsf_persona_new(m_store, contact), TRANSFER_REF);
+ GeeHashSetCXX personas(gee_hash_set_new(G_TYPE_OBJECT, g_object_ref, g_object_unref, NULL, NULL, NULL, NULL, NULL, NULL), TRANSFER_REF);
gee_collection_add(GEE_COLLECTION(personas.get()), persona.get());
- FolksIndividualCXX individual(folks_individual_new(GEE_SET(personas.get())), false);
+ FolksIndividualCXX individual(folks_individual_new(GEE_SET(personas.get())), TRANSFER_REF);
m_addedSignal(individual);
}
m_isQuiescent = true;
diff --git a/src/dbus/server/pim/folks.cpp b/src/dbus/server/pim/folks.cpp
index 7997b2db..1a409dd1 100644
--- a/src/dbus/server/pim/folks.cpp
+++ b/src/dbus/server/pim/folks.cpp
@@ -94,7 +94,7 @@ void IndividualData::init(const IndividualCompare *compare,
const LocaleFactory *locale,
FolksIndividual *individual)
{
- m_individual = individual;
+ m_individual = FolksIndividualCXX(individual, ADD_REF);
if (compare) {
m_criteria.clear();
compare->createCriteria(individual, m_criteria);
@@ -135,7 +135,7 @@ bool IndividualCompare::compare(const Criteria_t &a, const Criteria_t &b) const
IndividualAggregator::IndividualAggregator(const boost::shared_ptr<LocaleFactory> &locale) :
m_locale(locale),
- m_databases(gee_hash_set_new(G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, g_free, NULL, NULL, NULL, NULL, NULL, NULL), false)
+ m_databases(gee_hash_set_new(G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, g_free, NULL, NULL, NULL, NULL, NULL, NULL), TRANSFER_REF)
{
}
@@ -215,7 +215,7 @@ void IndividualAggregator::storePrepared()
void IndividualAggregator::backendsLoaded()
{
SE_LOG_DEBUG(NULL, "backend store has loaded backends");
- GeeCollectionCXX coll(folks_backend_store_list_backends(m_backendStore));
+ GeeCollectionCXX coll(folks_backend_store_list_backends(m_backendStore), TRANSFER_REF);
BOOST_FOREACH (FolksBackend *backend, GeeCollCXX<FolksBackend *>(coll.get())) {
SE_LOG_DEBUG(NULL, "folks backend: %s", folks_backend_get_name(backend));
}
@@ -225,7 +225,7 @@ void IndividualAggregator::backendsLoaded()
// Remember system store, for writing contacts.
GeeMap *stores = folks_backend_get_persona_stores(m_eds);
FolksPersonaStore *systemStore = static_cast<FolksPersonaStore *>(gee_map_get(stores, "system-address-book"));
- m_systemStore = systemStore;
+ m_systemStore = FolksPersonaStoreCXX(systemStore, TRANSFER_REF);
// Tell the backend which databases we want.
SE_LOG_DEBUG(NULL, "backends loaded: setting EDS persona stores: [%s]",
@@ -541,7 +541,7 @@ private:
}
void open() {
- FolksIndividualAggregatorCXX aggregator(folks_individual_aggregator_new(), false);
+ FolksIndividualAggregatorCXX aggregator(folks_individual_aggregator_new(), TRANSFER_REF);
bool done = false, failed = false;
SYNCEVO_GLIB_CALL_ASYNC(folks_individual_aggregator_prepare,
boost::bind(asyncCB, _1,
@@ -561,11 +561,11 @@ private:
GeeMap *individuals = folks_individual_aggregator_get_individuals(aggregator);
SE_LOG_DEBUG(NULL, "%d individuals", gee_map_get_size(individuals));
- GeeMapIteratorCXX it(gee_map_map_iterator(individuals), false);
+ GeeMapIteratorCXX it(gee_map_map_iterator(individuals), TRANSFER_REF);
while (gee_map_iterator_next(it)) {
PlainGStr id(reinterpret_cast<gchar *>(gee_map_iterator_get_key(it)));
FolksIndividualCXX individual(reinterpret_cast<FolksIndividual *>(gee_map_iterator_get_value(it)),
- false);
+ TRANSFER_REF);
GValueStringCXX fullname;
g_object_get_property(G_OBJECT(individual.get()), "full-name", &fullname);
SE_LOG_DEBUG(NULL, "map: id %s name %s = %s",
@@ -574,9 +574,9 @@ private:
fullname.get());
}
- GeeIteratorCXX it2(gee_iterable_iterator(GEE_ITERABLE(individuals)), false);
+ GeeIteratorCXX it2(gee_iterable_iterator(GEE_ITERABLE(individuals)), TRANSFER_REF);
while (gee_iterator_next(it2)) {
- GeeMapEntryCXX entry(reinterpret_cast<GeeMapEntry *>(gee_iterator_get(it2)), false);
+ GeeMapEntryCXX entry(reinterpret_cast<GeeMapEntry *>(gee_iterator_get(it2)), TRANSFER_REF);
gchar *id(reinterpret_cast<gchar *>(const_cast<gpointer>(gee_map_entry_get_key(entry))));
FolksIndividual *individual(reinterpret_cast<FolksIndividual *>(const_cast<gpointer>(gee_map_entry_get_value(entry))));
GValueStringCXX fullname;
diff --git a/src/dbus/server/pim/full-view.cpp b/src/dbus/server/pim/full-view.cpp
index fb86c77d..b154a171 100644
--- a/src/dbus/server/pim/full-view.cpp
+++ b/src/dbus/server/pim/full-view.cpp
@@ -144,7 +144,7 @@ void FullView::individualModified(gpointer gobject,
//
// See https://bugzilla.gnome.org/show_bug.cgi?id=684764
// "too many FolksIndividual modification signals"
- m_pendingModifications.insert(individual);
+ m_pendingModifications.insert(FolksIndividualCXX(individual, ADD_REF));
waitForIdle();
}
diff --git a/src/dbus/server/pim/individual-traits.cpp b/src/dbus/server/pim/individual-traits.cpp
index 7c054e52..9f0e6c83 100644
--- a/src/dbus/server/pim/individual-traits.cpp
+++ b/src/dbus/server/pim/individual-traits.cpp
@@ -344,7 +344,7 @@ template <> struct dbus_traits<GDateTime *> {
// GTimeZone local = g_time_zone_new_local()
// and use that throughout the runtime of the process, like
// folks-eds does.
- GDateTimeCXX local(g_date_time_to_local(value), false);
+ GDateTimeCXX local(g_date_time_to_local(value), TRANSFER_REF);
gint year, month, day;
g_date_time_get_ymd(local.get(), &year, &month, &day);
g_variant_builder_open(&builder, G_VARIANT_TYPE("(iii)")); // tuple with year, month, day
@@ -399,11 +399,11 @@ static void DBus2AbstractField(GDBusCXX::ExtractArgs &context,
g_object_unref,
FolksAbstractFieldDetailsHash, NULL, NULL,
FolksAbstractFieldDetailsEqual, NULL, NULL),
- false);
+ TRANSFER_REF);
BOOST_FOREACH (const Details_t::value_type &entry, value) {
const Details_t::value_type::first_type &val = entry.first;
const Details_t::value_type::second_type &flags = entry.second;
- FolksAbstractFieldDetailsCXX field(fieldNew(val.c_str(), NULL), false);
+ FolksAbstractFieldDetailsCXX field(fieldNew(val.c_str(), NULL), TRANSFER_REF);
BOOST_FOREACH (const std::string &type, flags) {
folks_abstract_field_details_add_parameter(field.get(),
FOLKS_ABSTRACT_FIELD_DETAILS_PARAM_TYPE,
@@ -438,9 +438,9 @@ static void DBus2SimpleAbstractField(GDBusCXX::ExtractArgs &context,
g_object_unref,
FolksAbstractFieldDetailsHash, NULL, NULL,
FolksAbstractFieldDetailsEqual, NULL, NULL),
- false);
+ TRANSFER_REF);
BOOST_FOREACH (const std::string &val, value) {
- FolksAbstractFieldDetailsCXX field(fieldNew(val.c_str(), NULL), false);
+ FolksAbstractFieldDetailsCXX field(fieldNew(val.c_str(), NULL), TRANSFER_REF);
gee_collection_add(GEE_COLLECTION(set.get()),
field.get());
}
@@ -466,10 +466,10 @@ static void DBus2Role(GDBusCXX::ExtractArgs &context,
g_object_unref,
FolksAbstractFieldDetailsHash, NULL, NULL,
FolksAbstractFieldDetailsEqual, NULL, NULL),
- false);
+ TRANSFER_REF);
BOOST_FOREACH (const StringMap &entry, value) {
FolksRoleCXX role(folks_role_new(NULL, NULL, NULL),
- false);
+ TRANSFER_REF);
BOOST_FOREACH (const StringPair &aspect, entry) {
const std::string &k = aspect.first;
const std::string &v = aspect.second;
@@ -482,7 +482,7 @@ static void DBus2Role(GDBusCXX::ExtractArgs &context,
}
}
FolksRoleFieldDetailsCXX field(folks_role_field_details_new(role.get(), NULL),
- false);
+ TRANSFER_REF);
gee_collection_add(GEE_COLLECTION(set.get()),
field.get());
}
@@ -500,7 +500,7 @@ static void DBus2Groups(GDBusCXX::ExtractArgs &context,
{
std::list<std::string> value;
GDBusCXX::dbus_traits<typeof(value)>::get(context, valueIter, value);
- GeeHashSetCXX set(gee_hash_set_new(G_TYPE_STRING, (GBoxedCopyFunc)g_strdup, g_free, NULL, NULL, NULL, NULL, NULL, NULL), false);
+ GeeHashSetCXX set(gee_hash_set_new(G_TYPE_STRING, (GBoxedCopyFunc)g_strdup, g_free, NULL, NULL, NULL, NULL, NULL, NULL), TRANSFER_REF);
BOOST_FOREACH(const std::string &entry, value) {
gee_collection_add(GEE_COLLECTION(set.get()),
entry.c_str());
@@ -527,7 +527,7 @@ static void DBus2Addr(GDBusCXX::ExtractArgs &context,
g_object_unref,
FolksAbstractFieldDetailsHash, NULL, NULL,
FolksAbstractFieldDetailsEqual, NULL, NULL),
- false);
+ TRANSFER_REF);
BOOST_FOREACH (const Details_t::value_type &entry, value) {
const StringMap &fields = entry.first;
const std::vector<std::string> &flags = entry.second;
@@ -540,9 +540,9 @@ static void DBus2Addr(GDBusCXX::ExtractArgs &context,
GetWithDef(fields, CONTACT_HASH_ADDRESSES_COUNTRY).c_str(),
NULL /* address format */,
NULL /* uid */),
- false);
+ TRANSFER_REF);
FolksAbstractFieldDetailsCXX field(FOLKS_ABSTRACT_FIELD_DETAILS(folks_postal_address_field_details_new(address.get(), NULL)),
- false);
+ TRANSFER_REF);
BOOST_FOREACH (const std::string &type, flags) {
folks_abstract_field_details_add_parameter(field.get(),
FOLKS_ABSTRACT_FIELD_DETAILS_PARAM_TYPE,
@@ -596,15 +596,15 @@ void DBus2PersonaDetails(GDBusCXX::ExtractArgs &context,
GetWithDef(value, CONTACT_HASH_STRUCTURED_NAME_ADDITIONAL).c_str(),
GetWithDef(value, CONTACT_HASH_STRUCTURED_NAME_PREFIXES).c_str(),
GetWithDef(value, CONTACT_HASH_STRUCTURED_NAME_SUFFIXES).c_str()),
- false));
+ TRANSFER_REF));
} else if (key == CONTACT_HASH_PHOTO) {
std::string value;
GDBusCXX::dbus_traits<std::string>::get(context, valueIter, value);
GFileCXX file(g_file_new_for_uri(value.c_str()),
- false);
+ TRANSFER_REF);
g_hash_table_insert(details.get(),
const_cast<gchar *>(folks_persona_store_detail_key(FOLKS_PERSONA_DETAIL_AVATAR)),
- new GValueObjectCXX(g_file_icon_new(file.get()), false));
+ new GValueObjectCXX(g_file_icon_new(file.get()), TRANSFER_REF));
} else if (key == CONTACT_HASH_BIRTHDAY) {
boost::tuple<int, int, int> value;
GDBusCXX::dbus_traits<typeof(value)>::get(context, valueIter, value);
@@ -612,16 +612,16 @@ void DBus2PersonaDetails(GDBusCXX::ExtractArgs &context,
value.get<1>(),
value.get<2>(),
0, 0, 0),
- false);
+ TRANSFER_REF);
g_hash_table_insert(details.get(),
const_cast<gchar *>(folks_persona_store_detail_key(FOLKS_PERSONA_DETAIL_BIRTHDAY)),
- new GValueDateTimeCXX(g_date_time_to_utc(local.get()), false));
+ new GValueDateTimeCXX(g_date_time_to_utc(local.get()), TRANSFER_REF));
} else if (key == CONTACT_HASH_LOCATION) {
boost::tuple<double, double> value;
GDBusCXX::dbus_traits<typeof(value)>::get(context, valueIter, value);
FolksLocationCXX location(folks_location_new(value.get<0>(),
value.get<1>()),
- false);
+ TRANSFER_REF);
g_hash_table_insert(details.get(),
const_cast<gchar *>(folks_persona_store_detail_key(FOLKS_PERSONA_DETAIL_LOCATION)),
new GValueObjectCXX(location.get()));
@@ -660,7 +660,7 @@ struct Pending
Pending(const Result<void ()> &result,
FolksPersona *persona) :
m_result(result),
- m_persona(persona),
+ m_persona(persona, ADD_REF),
m_current(0)
{}
diff --git a/src/dbus/server/pim/locale-factory-boost.cpp b/src/dbus/server/pim/locale-factory-boost.cpp
index b266b19b..accf142d 100644
--- a/src/dbus/server/pim/locale-factory-boost.cpp
+++ b/src/dbus/server/pim/locale-factory-boost.cpp
@@ -370,7 +370,7 @@ public:
// to the search term.
e_book_query_field_test(E_CONTACT_TEL, E_BOOK_QUERY_EQUALS_NATIONAL_PHONE_NUMBER,
m_tel.c_str()),
- false);
+ TRANSFER_REF);
PlainGStr filter(e_book_query_to_string(query.get()));
return filter.get();
}
@@ -554,7 +554,7 @@ public:
//
// We restore the right order by sorting, which puts the
// country code first, and then joining.
- GeeCollectionCXX coll(folks_abstract_field_details_get_parameter_values(phone, "x-evolution-e164"), false);
+ GeeCollectionCXX coll(folks_abstract_field_details_get_parameter_values(phone, "x-evolution-e164"), TRANSFER_REF);
if (coll) {
std::vector<std::string> components;
components.reserve(2);
diff --git a/src/syncevo/GLibSupport.cpp b/src/syncevo/GLibSupport.cpp
index af8ecfaf..6dc45868 100644
--- a/src/syncevo/GLibSupport.cpp
+++ b/src/syncevo/GLibSupport.cpp
@@ -191,9 +191,9 @@ GLibNotify::GLibNotify(const char *file,
const callback_t &callback) :
m_callback(callback)
{
- GFileCXX filecxx(g_file_new_for_path(file));
+ GFileCXX filecxx(g_file_new_for_path(file), TRANSFER_REF);
GErrorCXX gerror;
- GFileMonitorCXX monitor(g_file_monitor_file(filecxx.get(), G_FILE_MONITOR_NONE, NULL, gerror));
+ GFileMonitorCXX monitor(g_file_monitor_file(filecxx.get(), G_FILE_MONITOR_NONE, NULL, gerror), TRANSFER_REF);
m_monitor.swap(monitor);
if (!m_monitor) {
gerror.throwError(std::string("monitoring ") + file);
@@ -240,7 +240,7 @@ class GLibTest : public CppUnit::TestFixture {
list<Event> events;
static const char *name = "GLibTest.out";
unlink(name);
- GMainLoopCXX loop(g_main_loop_new(NULL, FALSE), false);
+ GMainLoopCXX loop(g_main_loop_new(NULL, FALSE), TRANSFER_REF);
if (!loop) {
SE_THROW("could not allocate main loop");
}
diff --git a/src/syncevo/GLibSupport.h b/src/syncevo/GLibSupport.h
index f6224192..36a431f5 100644
--- a/src/syncevo/GLibSupport.h
+++ b/src/syncevo/GLibSupport.h
@@ -172,6 +172,19 @@ template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, c
}
};
+enum RefOwnership
+{
+ TRANSFER_REF = false, /**<
+ * Create new smart pointer which steals an existing reference without
+ * increasing the reference count of the object.
+ */
+ ADD_REF = true /**<
+ * Create new smart pointer which increases the reference count when
+ * storing the pointer to the object.
+ */
+};
+
+
template<class C> class TrackGObject : public boost::intrusive_ptr<C> {
typedef boost::intrusive_ptr<C> Base_t;
@@ -186,14 +199,14 @@ template<class C> class TrackGObject : public boost::intrusive_ptr<C> {
}
public:
- TrackGObject(C *ptr, bool add_ref = true) : Base_t(ptr, add_ref) {}
+ TrackGObject(C *ptr, RefOwnership ownership) : Base_t(ptr, (bool)ownership) {}
TrackGObject() {}
TrackGObject(const TrackGObject &other) : Base_t(other) {}
operator C * () const { return Base_t::get(); }
operator bool () const { return Base_t::get() != NULL; }
C * ref() const { return static_cast<C *>(g_object_ref(Base_t::get())); }
- static TrackGObject steal(C *ptr) { return TrackGObject(ptr, false); }
+ static TrackGObject steal(C *ptr) { return TrackGObject(ptr, TRANSFER_REF); }
template<class S> guint connectSignal(const char *signal,
const boost::function<S> &callback) {
@@ -211,7 +224,7 @@ template<class C> class TrackGObject : public boost::intrusive_ptr<C> {
template<class C> class StealGObject : public TrackGObject<C> {
public:
- StealGObject(C *ptr) : TrackGObject<C>(ptr, false) {}
+ StealGObject(C *ptr) : TrackGObject<C>(ptr, TRANSFER_REF) {}
StealGObject() {}
StealGObject(const StealGObject &other) : TrackGObject<C>(other) {}
};
@@ -220,19 +233,19 @@ template<class C> class TrackGLib : public boost::intrusive_ptr<C> {
typedef boost::intrusive_ptr<C> Base_t;
public:
- TrackGLib(C *ptr, bool add_ref = true) : Base_t(ptr, add_ref) {}
+ TrackGLib(C *ptr, RefOwnership ownership) : Base_t(ptr, (bool)ownership) {}
TrackGLib() {}
TrackGLib(const TrackGLib &other) : Base_t(other) {}
operator C * () const { return Base_t::get(); }
operator bool () const { return Base_t::get() != NULL; }
C * ref() const { return static_cast<C *>(g_object_ref(Base_t::get())); }
- static TrackGLib steal(C *ptr) { return TrackGLib(ptr, false); }
+ static TrackGLib steal(C *ptr) { return TrackGLib(ptr, TRANSFER_REF); }
};
template<class C> class StealGLib : public TrackGLib<C> {
public:
- StealGLib(C *ptr) : TrackGLib<C>(ptr, false) {}
+ StealGLib(C *ptr) : TrackGLib<C>(ptr, TRANSFER_REF) {}
StealGLib() {}
StealGLib(const StealGLib &other) : TrackGLib<C>(other) {}
};
diff --git a/src/syncevo/GeeSupport.h b/src/syncevo/GeeSupport.h
index 08cda36d..cfbe5cd3 100644
--- a/src/syncevo/GeeSupport.h
+++ b/src/syncevo/GeeSupport.h
@@ -89,7 +89,7 @@ template<class Entry> class GeeCollCXX
public:
template<class Collection> GeeCollCXX(Collection *collection) :
- m_collection(GEE_ITERABLE(collection))
+ m_collection(GEE_ITERABLE(collection), ADD_REF)
{}
class Iterator
@@ -110,7 +110,7 @@ template<class Entry> class GeeCollCXX
* Takes ownership of iterator, which may be NULL for the end Iterator.
*/
Iterator(GeeIterator *iterator) :
- m_it(iterator, false),
+ m_it(iterator, TRANSFER_REF),
m_valid(false)
{}
@@ -181,7 +181,7 @@ template<class Key, class Value> class GeeMapEntryWrapper {
/** take ownership of entry instance */
GeeMapEntryWrapper(GeeMapEntry *entry = NULL) :
- m_entry(entry, false)
+ m_entry(entry, TRANSFER_REF)
{}
GeeMapEntryWrapper(const GeeMapEntryWrapper &other):
m_entry(other.m_entry)
diff --git a/src/syncevo/LocalTransportAgent.cpp b/src/syncevo/LocalTransportAgent.cpp
index 179c0ea9..8b56542c 100644
--- a/src/syncevo/LocalTransportAgent.cpp
+++ b/src/syncevo/LocalTransportAgent.cpp
@@ -56,8 +56,8 @@ LocalTransportAgent::LocalTransportAgent(SyncContext *server,
m_clientContext(SyncConfig::normalizeConfigString(clientContext)),
m_status(INACTIVE),
m_loop(loop ?
- GMainLoopCXX(static_cast<GMainLoop *>(loop)) /* increase reference */ :
- GMainLoopCXX(g_main_loop_new(NULL, false), false) /* use reference handed to us by _new */)
+ GMainLoopCXX(static_cast<GMainLoop *>(loop), ADD_REF) :
+ GMainLoopCXX(g_main_loop_new(NULL, false), TRANSFER_REF))
{
}
diff --git a/test/dbus-client-server.cpp b/test/dbus-client-server.cpp
index 6bef63dd..60fd6514 100644
--- a/test/dbus-client-server.cpp
+++ b/test/dbus-client-server.cpp
@@ -273,7 +273,7 @@ int main(int argc, char **argv)
// throw stdruntime_error("The --allow-anonymous option only makes sense when used with --server.");
// }
- loop = SyncEvo::GMainLoopCXX(g_main_loop_new (NULL, FALSE), false);
+ loop = SyncEvo::GMainLoopStealCXX(g_main_loop_new (NULL, FALSE));
if (!loop) {
throw std::runtime_error("could not allocate main loop");
}