From 65f953407a3a1726db3949743c28e1f9e2ad0e8b Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 14 May 2013 11:45:32 +0200 Subject: Change the ownership semantics of metatype converter functions. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Destroying the instances is a problem because the instances might have been created in a plugin. In that case, the destructor of the instance will be implemented in the plugin. As the instance destruction code is run very late, the plugin might have already been unloaded by the time an attempt is made to destroy the instance. The workaround is to create static instances on the stack. Task-number: QTBUG-31142 Change-Id: Ic2632c3548a734b742da46d90249916c35705d46 Reviewed-by: Stephen Kelly Reviewed-by: Jędrzej Nowacki --- src/corelib/kernel/qmetatype.cpp | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) (limited to 'src/corelib/kernel/qmetatype.cpp') diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 5551880e30..5c3f252395 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -428,8 +428,6 @@ public: ~QMetaTypeConversionRegistry() { const QWriteLocker locker(&lock); - Q_FOREACH (QtPrivate::AbstractConverterFunction *f, map) - f->destroy(f); map.clear(); } @@ -440,27 +438,33 @@ public: return map.contains(k); } - bool insertIfNotContains(int from, int to, QtPrivate::AbstractConverterFunction *f) + bool insertIfNotContains(int from, int to, const QtPrivate::AbstractConverterFunction *f) { const Key k(from, to); const QWriteLocker locker(&lock); - QtPrivate::AbstractConverterFunction* &fun = map[k]; + const QtPrivate::AbstractConverterFunction* &fun = map[k]; if (fun != 0) return false; fun = f; return true; } - QtPrivate::AbstractConverterFunction *function(int from, int to) const + const QtPrivate::AbstractConverterFunction *function(int from, int to) const { const Key k(from, to); const QReadLocker locker(&lock); return map.value(k, 0); } + void remove(int from, int to) + { + const Key k(from, to); + const QWriteLocker locker(&lock); + map.remove(k); + } private: mutable QReadWriteLock lock; - QHash map; + QHash map; }; namespace @@ -514,18 +518,26 @@ Q_GLOBAL_STATIC(QMetaTypeConversionRegistry, customTypesConversionRegistry) \since 5.2 \internal */ -bool QMetaType::registerConverterFunction(QtPrivate::AbstractConverterFunction *f, int from, int to) +bool QMetaType::registerConverterFunction(const QtPrivate::AbstractConverterFunction *f, int from, int to) { if (!customTypesConversionRegistry()->insertIfNotContains(from, to, f)) { qWarning("Type conversion already registered from type %s to type %s", QMetaType::typeName(from), QMetaType::typeName(to)); - if (f) - f->destroy(f); return false; } return true; } +/*! + \internal + + Invoked automatically when a converter function object is destroyed. + */ +void QMetaType::unregisterConverterFunction(int from, int to) +{ + customTypesConversionRegistry()->remove(from, to); +} + /*! Converts the object at \a from from \a fromTypeId to the preallocated space at \a to typed \a toTypeId. Returns true, if the conversion succeeded, otherwise false. -- cgit v1.2.3