From 6b87084678fa63695b05e38112a05ea2b904ed91 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Wed, 28 Feb 2018 08:37:40 +0100 Subject: [PATCH] memory leaks fixed --- src/common/QskMetaCall.cpp | 19 +++++++++++++--- src/common/QskMetaCall.h | 1 + src/common/QskMetaCallback.cpp | 40 +++++++++++++++------------------- src/common/QskMetaCallback.h | 10 ++------- 4 files changed, 37 insertions(+), 33 deletions(-) diff --git a/src/common/QskMetaCall.cpp b/src/common/QskMetaCall.cpp index a6b33121..e6cda416 100644 --- a/src/common/QskMetaCall.cpp +++ b/src/common/QskMetaCall.cpp @@ -12,12 +12,21 @@ #include +namespace +{ + // to get access to the private section of QSlotObjectBase + struct SlotObject + { + QAtomicInt ref; + QskMetaCall::Invokable::InvokeFunction invoke; + }; +} + namespace QskMetaCall { inline Invokable::InvokeFunction invokeCall( const Invokable* invokable ) { - struct Data { QAtomicInt dummy; Invokable::InvokeFunction invoke; }; - return ( ( Data* )( invokable ) )->invoke; + return ( ( SlotObject* )( invokable ) )->invoke; } int Invokable::typeInfo() const @@ -31,6 +40,11 @@ namespace QskMetaCall return value; } + + int Invokable::refCount() const + { + return ( ( SlotObject* )( this ) )->ref.load(); + } } namespace @@ -45,7 +59,6 @@ namespace QMetaCallEvent( invokable, nullptr, 0, nargs, types, args, semaphore ), m_invokable ( invokable ) { - invokable->ref(); } virtual ~FunctionCallEvent() diff --git a/src/common/QskMetaCall.h b/src/common/QskMetaCall.h index cda99b7f..c9c20b28 100644 --- a/src/common/QskMetaCall.h +++ b/src/common/QskMetaCall.h @@ -35,6 +35,7 @@ namespace QskMetaCall enum { TypeInfo = NumOperations + 1 }; int typeInfo() const; + int refCount() const; protected: explicit Invokable( InvokeFunction f ): diff --git a/src/common/QskMetaCallback.cpp b/src/common/QskMetaCallback.cpp index 14a77a91..a35d2521 100644 --- a/src/common/QskMetaCallback.cpp +++ b/src/common/QskMetaCallback.cpp @@ -10,7 +10,7 @@ QskMetaCallback::QskMetaCallback( const QObject* object, const QMetaMethod& method, Qt::ConnectionType connectionType ): m_object( const_cast< QObject* >( object ) ), - m_method( method ), + m_method( new QMetaMethod( method ) ), m_type( MetaMethod ), m_connectionType( static_cast< ushort >( connectionType & ~Qt::UniqueConnection ) ) { @@ -19,7 +19,7 @@ QskMetaCallback::QskMetaCallback( const QObject* object, QskMetaCallback::QskMetaCallback( const QObject* object, const QskMetaFunction& function, Qt::ConnectionType connectionType ): m_object( const_cast< QObject* >( object ) ), - m_function( function ), + m_function( new QskMetaFunction( function ) ), m_type( MetaFunction ), m_connectionType( static_cast< ushort >( connectionType & ~Qt::UniqueConnection ) ) { @@ -40,11 +40,11 @@ QskMetaCallback::QskMetaCallback( const QskMetaCallback& other ): switch( m_type ) { case MetaMethod: - m_method = other.m_method; + m_method = new QMetaMethod( *other.m_method ); break; case MetaFunction: - m_function = other.m_function; + m_function = new QskMetaFunction( *other.m_function ); break; default: @@ -68,18 +68,12 @@ QskMetaCallback& QskMetaCallback::operator=( const QskMetaCallback& other ) m_type = other.m_type; } - switch( m_type ) + if ( other.m_type != Invalid ) { - case MetaMethod: - m_method = other.m_method; - break; - - case MetaFunction: - m_function = other.m_function; - break; - - default: - break; + if ( other.m_type == MetaMethod ) + m_method = new QMetaMethod( *other.m_method ); + else + m_function = new QskMetaFunction( *other.m_function ); } return *this; @@ -95,11 +89,13 @@ void QskMetaCallback::reset() switch( m_type ) { case MetaMethod: - m_method.~QMetaMethod(); + delete m_method; + m_method = nullptr; break; case MetaFunction: - m_function.~QskMetaFunction(); + delete m_function; + m_function = nullptr; break; default: @@ -117,17 +113,17 @@ QVector< int > QskMetaCallback::parameterTypes() const { case MetaMethod: { - const int paramCount = m_method.parameterCount(); + const int paramCount = m_method->parameterCount(); paramTypes.reserve( paramCount ); for ( int i = 0; i < paramCount; i++ ) - paramTypes += m_method.parameterType( i ); + paramTypes += m_method->parameterType( i ); break; } case MetaFunction: { - auto types = m_function.parameterTypes(); + auto types = m_function->parameterTypes(); if ( types ) { while ( *types ) @@ -152,12 +148,12 @@ void QskMetaCallback::invoke( void* args[] ) case MetaMethod: { if ( object ) - QskMetaCall::invoke( object, m_method, args, connectionType() ); + QskMetaCall::invoke( object, *m_method, args, connectionType() ); break; } case MetaFunction: { - m_function.invoke( object, args, connectionType() ); + m_function->invoke( object, args, connectionType() ); break; } diff --git a/src/common/QskMetaCallback.h b/src/common/QskMetaCallback.h index 09097434..2207b3c6 100644 --- a/src/common/QskMetaCallback.h +++ b/src/common/QskMetaCallback.h @@ -59,17 +59,11 @@ private: QPointer< const QObject > m_object; -#if 1 - /* - This union does not work - call of constructors - are missing - */ union { - QskMetaFunction m_function; - QMetaMethod m_method; + QskMetaFunction* m_function; + QMetaMethod* m_method; }; -#endif int m_type : 3; ushort m_connectionType : 3;