summaryrefslogtreecommitdiff
path: root/qmake/tools/qcomlibrary.cpp
Side-by-side diff
Diffstat (limited to 'qmake/tools/qcomlibrary.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--qmake/tools/qcomlibrary.cpp43
1 files changed, 20 insertions, 23 deletions
diff --git a/qmake/tools/qcomlibrary.cpp b/qmake/tools/qcomlibrary.cpp
index a7162fc..2a1b75a 100644
--- a/qmake/tools/qcomlibrary.cpp
+++ b/qmake/tools/qcomlibrary.cpp
@@ -18,96 +18,100 @@
**
** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
** licenses may use this file in accordance with the Qt Commercial License
** Agreement provided with the Software.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
** information about Qt Commercial License Agreements.
** See http://www.trolltech.com/qpl/ for QPL licensing information.
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#include "qcomlibrary_p.h"
#ifndef QT_NO_COMPONENT
#include <qapplication.h>
#include <qsettings.h>
#include <qfileinfo.h>
#include <qdatetime.h>
#include <qcleanuphandler.h>
#include <errno.h>
#ifdef QT_THREAD_SUPPORT
# include "qmutexpool_p.h"
#endif // QT_THREAD_SUPPORT
#ifndef QT_DEBUG_COMPONENT
# if defined(QT_DEBUG)
# define QT_DEBUG_COMPONENT 1
# endif
#endif
QComLibrary::QComLibrary( const QString &filename )
: QLibrary( filename ), entry( 0 ), libiface( 0 ), qt_version( 0 )
{
}
QComLibrary::~QComLibrary()
{
if ( autoUnload() )
unload();
+ if ( libiface )
+ libiface->release();
+ if ( entry )
+ entry->release();
}
bool QComLibrary::unload()
{
if ( libiface ) {
libiface->cleanup();
if ( !libiface->canUnload() )
return FALSE;
libiface->release();
libiface = 0;
}
int refs = entry ? entry->release() : 0;
if ( refs )
return FALSE;
entry = 0;
return QLibrary::unload();
}
static bool qt_verify( const QString& library, uint version, uint flags,
const QCString &key, bool warn )
{
uint our_flags = 1;
#if defined(QT_THREAD_SUPPORT)
our_flags |= 2;
#endif
if ( (flags & 1) == 0 ) {
if ( warn )
qWarning( "Conflict in %s:\n"
" Plugin cannot be queried successfully!",
(const char*) QFile::encodeName(library) );
} else if ( ( version > QT_VERSION ) ||
( ( QT_VERSION & 0xff0000 ) > ( version & 0xff0000 ) ) ) {
if ( warn )
qWarning( "Conflict in %s:\n"
" Plugin uses incompatible Qt library (%d.%d.%d)!",
(const char*) QFile::encodeName(library),
(version&0xff0000) >> 16, (version&0xff00) >> 8, version&0xff );
} else if ( (flags & 2) != (our_flags & 2) ) {
if ( warn )
qWarning( "Conflict in %s:\n"
" Plugin uses %s Qt library!",
(const char*) QFile::encodeName(library),
(flags & 2) ? "multi threaded" : "single threaded" );
} else if ( key != QT_BUILD_KEY ) {
if ( warn )
@@ -346,171 +350,164 @@ static bool qt_unix_query( const QString &library, uint *version, uint *flags,
fdlen = data.size();
#ifdef USE_MMAP
}
#endif // USE_MMAP
// verify that the pattern is present in the plugin
const char *pattern = "pattern=QT_UCM_VERIFICATION_DATA";
const ulong plen = qstrlen( pattern );
long pos = qt_find_pattern( filedata, fdlen, pattern, plen );
bool ret = FALSE;
if ( pos >= 0 ) {
ret = qt_parse_pattern( filedata + pos, version, flags, key );
}
#ifdef USE_MMAP
if ( mapaddr != MAP_FAILED && munmap(mapaddr, maplen) != 0 ) {
qWarning( "munmap: %s", strerror( errno ) );
}
#endif // USE_MMAP
file.close();
return ret;
}
#endif // Q_OS_UNIX
static QSettings *cache = 0;
static QSingleCleanupHandler<QSettings> cleanup_cache;
void QComLibrary::createInstanceInternal()
{
if ( library().isEmpty() )
return;
QFileInfo fileinfo( library() );
QString lastModified = fileinfo.lastModified().toString();
QString regkey = QString("/Qt Plugins %1.%2/%3")
.arg( ( QT_VERSION & 0xff0000 ) >> 16 )
.arg( ( QT_VERSION & 0xff00 ) >> 8 )
.arg( library() );
QStringList reg;
uint flags = 0;
QCString key;
bool query_done = FALSE;
bool warn_mismatch = TRUE;
- if ( ! query_done ) {
-
#ifdef QT_THREAD_SUPPORT
- QMutexLocker locker( qt_global_mutexpool->get( &cache ) );
+ QMutexLocker locker( qt_global_mutexpool ?
+ qt_global_mutexpool->get( &cache ) : 0 );
#endif // QT_THREAD_SUPPORT
- if ( ! cache ) {
- cache = new QSettings;
- cache->insertSearchPath( QSettings::Windows, "/Trolltech" );
- cleanup_cache.set( &cache );
- }
+ if ( ! cache ) {
+ cache = new QSettings;
+ cache->insertSearchPath( QSettings::Windows, "/Trolltech" );
+ cleanup_cache.set( &cache );
+ }
- reg = cache->readListEntry( regkey );
- if ( reg.count() == 4 ) {
- // check timestamp
- if ( lastModified == reg[3] ) {
- qt_version = reg[0].toUInt(0, 16);
- flags = reg[1].toUInt(0, 16);
- key = reg[2].latin1();
+ reg = cache->readListEntry( regkey );
+ if ( reg.count() == 4 ) {
+ // check timestamp
+ if ( lastModified == reg[3] ) {
+ qt_version = reg[0].toUInt(0, 16);
+ flags = reg[1].toUInt(0, 16);
+ key = reg[2].latin1();
- query_done = TRUE;
- warn_mismatch = FALSE;
- }
+ query_done = TRUE;
+ warn_mismatch = FALSE;
}
}
#if defined(Q_OS_UNIX)
if ( ! query_done ) {
// get the query information directly from the plugin without loading
if ( qt_unix_query( library(), &qt_version, &flags, &key ) ) {
// info read succesfully from library
query_done = TRUE;
}
}
#else // !Q_OS_UNIX
if ( ! query_done ) {
// get the query information by loading the plugin
if ( !isLoaded() ) {
Q_ASSERT( entry == 0 );
if ( !load() )
return;
}
# ifdef Q_CC_BOR
typedef const char * __stdcall (*UCMQueryVerificationDataProc)();
# else
typedef const char * (*UCMQueryVerificationDataProc)();
# endif
UCMQueryVerificationDataProc ucmQueryVerificationdataProc;
ucmQueryVerificationdataProc =
(UCMQueryVerificationDataProc) resolve( "qt_ucm_query_verification_data" );
if ( !ucmQueryVerificationdataProc ||
!qt_parse_pattern( ucmQueryVerificationdataProc(),
&qt_version, &flags, &key ) ) {
qt_version = flags = 0;
key = "unknown";
} else {
query_done = TRUE;
}
}
#endif // Q_OS_UNIX
QStringList queried;
queried << QString::number( qt_version,16 )
<< QString::number( flags, 16 )
<< key
<< lastModified;
if ( queried != reg ) {
-
-#ifdef QT_THREAD_SUPPORT
- QMutexLocker locker( qt_global_mutexpool->get( &cache ) );
-#endif // QT_THREAD_SUPPORT
-
cache->writeEntry( regkey, queried );
// delete the cache, which forces the settings to be written
delete cache;
cache = 0;
}
if ( ! query_done ) {
if ( warn_mismatch ) {
qWarning( "Conflict in %s:\n Plugin cannot be queried successfully!",
(const char*) QFile::encodeName( library() ) );
}
unload();
return;
}
if ( ! qt_verify( library(), qt_version, flags, key, warn_mismatch ) ) {
unload();
return;
} else if ( !isLoaded() ) {
Q_ASSERT( entry == 0 );
if ( !load() )
return;
}
#ifdef Q_CC_BOR
typedef QUnknownInterface* __stdcall (*UCMInstanceProc)();
#else
typedef QUnknownInterface* (*UCMInstanceProc)();
#endif
UCMInstanceProc ucmInstanceProc;
ucmInstanceProc = (UCMInstanceProc) resolve( "ucm_instantiate" );
#if defined(QT_DEBUG_COMPONENT)
if ( !ucmInstanceProc )
qWarning( "%s: Not a UCOM library.", (const char*) QFile::encodeName(library()) );
#endif
entry = ucmInstanceProc ? ucmInstanceProc() : 0;
if ( entry ) {
if ( entry->queryInterface( IID_QLibrary, (QUnknownInterface**)&libiface ) == QS_OK ) {
if ( libiface && !libiface->init() ) {
libiface->release();
libiface = 0;
unload();
return;
}
}
} else {
#if defined(QT_DEBUG_COMPONENT)