-rw-r--r-- | qmake/tools/qcomlibrary.cpp | 43 |
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 @@ | |||
18 | ** | 18 | ** |
19 | ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition | 19 | ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition |
20 | ** licenses may use this file in accordance with the Qt Commercial License | 20 | ** licenses may use this file in accordance with the Qt Commercial License |
21 | ** Agreement provided with the Software. | 21 | ** Agreement provided with the Software. |
22 | ** | 22 | ** |
23 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | 23 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE |
24 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | 24 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
25 | ** | 25 | ** |
26 | ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for | 26 | ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for |
27 | ** information about Qt Commercial License Agreements. | 27 | ** information about Qt Commercial License Agreements. |
28 | ** See http://www.trolltech.com/qpl/ for QPL licensing information. | 28 | ** See http://www.trolltech.com/qpl/ for QPL licensing information. |
29 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | 29 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. |
30 | ** | 30 | ** |
31 | ** Contact info@trolltech.com if any conditions of this licensing are | 31 | ** Contact info@trolltech.com if any conditions of this licensing are |
32 | ** not clear to you. | 32 | ** not clear to you. |
33 | ** | 33 | ** |
34 | **********************************************************************/ | 34 | **********************************************************************/ |
35 | 35 | ||
36 | #include "qcomlibrary_p.h" | 36 | #include "qcomlibrary_p.h" |
37 | 37 | ||
38 | #ifndef QT_NO_COMPONENT | 38 | #ifndef QT_NO_COMPONENT |
39 | #include <qapplication.h> | 39 | #include <qapplication.h> |
40 | #include <qsettings.h> | 40 | #include <qsettings.h> |
41 | #include <qfileinfo.h> | 41 | #include <qfileinfo.h> |
42 | #include <qdatetime.h> | 42 | #include <qdatetime.h> |
43 | #include <qcleanuphandler.h> | 43 | #include <qcleanuphandler.h> |
44 | #include <errno.h> | 44 | #include <errno.h> |
45 | 45 | ||
46 | #ifdef QT_THREAD_SUPPORT | 46 | #ifdef QT_THREAD_SUPPORT |
47 | # include "qmutexpool_p.h" | 47 | # include "qmutexpool_p.h" |
48 | #endif // QT_THREAD_SUPPORT | 48 | #endif // QT_THREAD_SUPPORT |
49 | 49 | ||
50 | #ifndef QT_DEBUG_COMPONENT | 50 | #ifndef QT_DEBUG_COMPONENT |
51 | # if defined(QT_DEBUG) | 51 | # if defined(QT_DEBUG) |
52 | # define QT_DEBUG_COMPONENT 1 | 52 | # define QT_DEBUG_COMPONENT 1 |
53 | # endif | 53 | # endif |
54 | #endif | 54 | #endif |
55 | 55 | ||
56 | 56 | ||
57 | QComLibrary::QComLibrary( const QString &filename ) | 57 | QComLibrary::QComLibrary( const QString &filename ) |
58 | : QLibrary( filename ), entry( 0 ), libiface( 0 ), qt_version( 0 ) | 58 | : QLibrary( filename ), entry( 0 ), libiface( 0 ), qt_version( 0 ) |
59 | { | 59 | { |
60 | } | 60 | } |
61 | 61 | ||
62 | QComLibrary::~QComLibrary() | 62 | QComLibrary::~QComLibrary() |
63 | { | 63 | { |
64 | if ( autoUnload() ) | 64 | if ( autoUnload() ) |
65 | unload(); | 65 | unload(); |
66 | if ( libiface ) | ||
67 | libiface->release(); | ||
68 | if ( entry ) | ||
69 | entry->release(); | ||
66 | } | 70 | } |
67 | 71 | ||
68 | bool QComLibrary::unload() | 72 | bool QComLibrary::unload() |
69 | { | 73 | { |
70 | if ( libiface ) { | 74 | if ( libiface ) { |
71 | libiface->cleanup(); | 75 | libiface->cleanup(); |
72 | if ( !libiface->canUnload() ) | 76 | if ( !libiface->canUnload() ) |
73 | return FALSE; | 77 | return FALSE; |
74 | libiface->release(); | 78 | libiface->release(); |
75 | libiface = 0; | 79 | libiface = 0; |
76 | } | 80 | } |
77 | int refs = entry ? entry->release() : 0; | 81 | int refs = entry ? entry->release() : 0; |
78 | if ( refs ) | 82 | if ( refs ) |
79 | return FALSE; | 83 | return FALSE; |
80 | 84 | ||
81 | entry = 0; | 85 | entry = 0; |
82 | 86 | ||
83 | return QLibrary::unload(); | 87 | return QLibrary::unload(); |
84 | } | 88 | } |
85 | 89 | ||
86 | static bool qt_verify( const QString& library, uint version, uint flags, | 90 | static bool qt_verify( const QString& library, uint version, uint flags, |
87 | const QCString &key, bool warn ) | 91 | const QCString &key, bool warn ) |
88 | { | 92 | { |
89 | uint our_flags = 1; | 93 | uint our_flags = 1; |
90 | #if defined(QT_THREAD_SUPPORT) | 94 | #if defined(QT_THREAD_SUPPORT) |
91 | our_flags |= 2; | 95 | our_flags |= 2; |
92 | #endif | 96 | #endif |
93 | 97 | ||
94 | if ( (flags & 1) == 0 ) { | 98 | if ( (flags & 1) == 0 ) { |
95 | if ( warn ) | 99 | if ( warn ) |
96 | qWarning( "Conflict in %s:\n" | 100 | qWarning( "Conflict in %s:\n" |
97 | " Plugin cannot be queried successfully!", | 101 | " Plugin cannot be queried successfully!", |
98 | (const char*) QFile::encodeName(library) ); | 102 | (const char*) QFile::encodeName(library) ); |
99 | } else if ( ( version > QT_VERSION ) || | 103 | } else if ( ( version > QT_VERSION ) || |
100 | ( ( QT_VERSION & 0xff0000 ) > ( version & 0xff0000 ) ) ) { | 104 | ( ( QT_VERSION & 0xff0000 ) > ( version & 0xff0000 ) ) ) { |
101 | if ( warn ) | 105 | if ( warn ) |
102 | qWarning( "Conflict in %s:\n" | 106 | qWarning( "Conflict in %s:\n" |
103 | " Plugin uses incompatible Qt library (%d.%d.%d)!", | 107 | " Plugin uses incompatible Qt library (%d.%d.%d)!", |
104 | (const char*) QFile::encodeName(library), | 108 | (const char*) QFile::encodeName(library), |
105 | (version&0xff0000) >> 16, (version&0xff00) >> 8, version&0xff ); | 109 | (version&0xff0000) >> 16, (version&0xff00) >> 8, version&0xff ); |
106 | } else if ( (flags & 2) != (our_flags & 2) ) { | 110 | } else if ( (flags & 2) != (our_flags & 2) ) { |
107 | if ( warn ) | 111 | if ( warn ) |
108 | qWarning( "Conflict in %s:\n" | 112 | qWarning( "Conflict in %s:\n" |
109 | " Plugin uses %s Qt library!", | 113 | " Plugin uses %s Qt library!", |
110 | (const char*) QFile::encodeName(library), | 114 | (const char*) QFile::encodeName(library), |
111 | (flags & 2) ? "multi threaded" : "single threaded" ); | 115 | (flags & 2) ? "multi threaded" : "single threaded" ); |
112 | } else if ( key != QT_BUILD_KEY ) { | 116 | } else if ( key != QT_BUILD_KEY ) { |
113 | if ( warn ) | 117 | if ( warn ) |
@@ -346,171 +350,164 @@ static bool qt_unix_query( const QString &library, uint *version, uint *flags, | |||
346 | fdlen = data.size(); | 350 | fdlen = data.size(); |
347 | #ifdef USE_MMAP | 351 | #ifdef USE_MMAP |
348 | } | 352 | } |
349 | #endif // USE_MMAP | 353 | #endif // USE_MMAP |
350 | 354 | ||
351 | // verify that the pattern is present in the plugin | 355 | // verify that the pattern is present in the plugin |
352 | const char *pattern = "pattern=QT_UCM_VERIFICATION_DATA"; | 356 | const char *pattern = "pattern=QT_UCM_VERIFICATION_DATA"; |
353 | const ulong plen = qstrlen( pattern ); | 357 | const ulong plen = qstrlen( pattern ); |
354 | long pos = qt_find_pattern( filedata, fdlen, pattern, plen ); | 358 | long pos = qt_find_pattern( filedata, fdlen, pattern, plen ); |
355 | 359 | ||
356 | bool ret = FALSE; | 360 | bool ret = FALSE; |
357 | if ( pos >= 0 ) { | 361 | if ( pos >= 0 ) { |
358 | ret = qt_parse_pattern( filedata + pos, version, flags, key ); | 362 | ret = qt_parse_pattern( filedata + pos, version, flags, key ); |
359 | } | 363 | } |
360 | 364 | ||
361 | #ifdef USE_MMAP | 365 | #ifdef USE_MMAP |
362 | if ( mapaddr != MAP_FAILED && munmap(mapaddr, maplen) != 0 ) { | 366 | if ( mapaddr != MAP_FAILED && munmap(mapaddr, maplen) != 0 ) { |
363 | qWarning( "munmap: %s", strerror( errno ) ); | 367 | qWarning( "munmap: %s", strerror( errno ) ); |
364 | } | 368 | } |
365 | #endif // USE_MMAP | 369 | #endif // USE_MMAP |
366 | 370 | ||
367 | file.close(); | 371 | file.close(); |
368 | return ret; | 372 | return ret; |
369 | } | 373 | } |
370 | 374 | ||
371 | #endif // Q_OS_UNIX | 375 | #endif // Q_OS_UNIX |
372 | 376 | ||
373 | 377 | ||
374 | static QSettings *cache = 0; | 378 | static QSettings *cache = 0; |
375 | static QSingleCleanupHandler<QSettings> cleanup_cache; | 379 | static QSingleCleanupHandler<QSettings> cleanup_cache; |
376 | 380 | ||
377 | void QComLibrary::createInstanceInternal() | 381 | void QComLibrary::createInstanceInternal() |
378 | { | 382 | { |
379 | if ( library().isEmpty() ) | 383 | if ( library().isEmpty() ) |
380 | return; | 384 | return; |
381 | 385 | ||
382 | QFileInfo fileinfo( library() ); | 386 | QFileInfo fileinfo( library() ); |
383 | QString lastModified = fileinfo.lastModified().toString(); | 387 | QString lastModified = fileinfo.lastModified().toString(); |
384 | QString regkey = QString("/Qt Plugins %1.%2/%3") | 388 | QString regkey = QString("/Qt Plugins %1.%2/%3") |
385 | .arg( ( QT_VERSION & 0xff0000 ) >> 16 ) | 389 | .arg( ( QT_VERSION & 0xff0000 ) >> 16 ) |
386 | .arg( ( QT_VERSION & 0xff00 ) >> 8 ) | 390 | .arg( ( QT_VERSION & 0xff00 ) >> 8 ) |
387 | .arg( library() ); | 391 | .arg( library() ); |
388 | QStringList reg; | 392 | QStringList reg; |
389 | uint flags = 0; | 393 | uint flags = 0; |
390 | QCString key; | 394 | QCString key; |
391 | bool query_done = FALSE; | 395 | bool query_done = FALSE; |
392 | bool warn_mismatch = TRUE; | 396 | bool warn_mismatch = TRUE; |
393 | 397 | ||
394 | if ( ! query_done ) { | ||
395 | |||
396 | #ifdef QT_THREAD_SUPPORT | 398 | #ifdef QT_THREAD_SUPPORT |
397 | QMutexLocker locker( qt_global_mutexpool->get( &cache ) ); | 399 | QMutexLocker locker( qt_global_mutexpool ? |
400 | qt_global_mutexpool->get( &cache ) : 0 ); | ||
398 | #endif // QT_THREAD_SUPPORT | 401 | #endif // QT_THREAD_SUPPORT |
399 | 402 | ||
400 | if ( ! cache ) { | 403 | if ( ! cache ) { |
401 | cache = new QSettings; | 404 | cache = new QSettings; |
402 | cache->insertSearchPath( QSettings::Windows, "/Trolltech" ); | 405 | cache->insertSearchPath( QSettings::Windows, "/Trolltech" ); |
403 | cleanup_cache.set( &cache ); | 406 | cleanup_cache.set( &cache ); |
404 | } | 407 | } |
405 | 408 | ||
406 | reg = cache->readListEntry( regkey ); | 409 | reg = cache->readListEntry( regkey ); |
407 | if ( reg.count() == 4 ) { | 410 | if ( reg.count() == 4 ) { |
408 | // check timestamp | 411 | // check timestamp |
409 | if ( lastModified == reg[3] ) { | 412 | if ( lastModified == reg[3] ) { |
410 | qt_version = reg[0].toUInt(0, 16); | 413 | qt_version = reg[0].toUInt(0, 16); |
411 | flags = reg[1].toUInt(0, 16); | 414 | flags = reg[1].toUInt(0, 16); |
412 | key = reg[2].latin1(); | 415 | key = reg[2].latin1(); |
413 | 416 | ||
414 | query_done = TRUE; | 417 | query_done = TRUE; |
415 | warn_mismatch = FALSE; | 418 | warn_mismatch = FALSE; |
416 | } | ||
417 | } | 419 | } |
418 | } | 420 | } |
419 | 421 | ||
420 | #if defined(Q_OS_UNIX) | 422 | #if defined(Q_OS_UNIX) |
421 | if ( ! query_done ) { | 423 | if ( ! query_done ) { |
422 | // get the query information directly from the plugin without loading | 424 | // get the query information directly from the plugin without loading |
423 | if ( qt_unix_query( library(), &qt_version, &flags, &key ) ) { | 425 | if ( qt_unix_query( library(), &qt_version, &flags, &key ) ) { |
424 | // info read succesfully from library | 426 | // info read succesfully from library |
425 | query_done = TRUE; | 427 | query_done = TRUE; |
426 | } | 428 | } |
427 | } | 429 | } |
428 | #else // !Q_OS_UNIX | 430 | #else // !Q_OS_UNIX |
429 | if ( ! query_done ) { | 431 | if ( ! query_done ) { |
430 | // get the query information by loading the plugin | 432 | // get the query information by loading the plugin |
431 | if ( !isLoaded() ) { | 433 | if ( !isLoaded() ) { |
432 | Q_ASSERT( entry == 0 ); | 434 | Q_ASSERT( entry == 0 ); |
433 | if ( !load() ) | 435 | if ( !load() ) |
434 | return; | 436 | return; |
435 | } | 437 | } |
436 | 438 | ||
437 | # ifdef Q_CC_BOR | 439 | # ifdef Q_CC_BOR |
438 | typedef const char * __stdcall (*UCMQueryVerificationDataProc)(); | 440 | typedef const char * __stdcall (*UCMQueryVerificationDataProc)(); |
439 | # else | 441 | # else |
440 | typedef const char * (*UCMQueryVerificationDataProc)(); | 442 | typedef const char * (*UCMQueryVerificationDataProc)(); |
441 | # endif | 443 | # endif |
442 | UCMQueryVerificationDataProc ucmQueryVerificationdataProc; | 444 | UCMQueryVerificationDataProc ucmQueryVerificationdataProc; |
443 | ucmQueryVerificationdataProc = | 445 | ucmQueryVerificationdataProc = |
444 | (UCMQueryVerificationDataProc) resolve( "qt_ucm_query_verification_data" ); | 446 | (UCMQueryVerificationDataProc) resolve( "qt_ucm_query_verification_data" ); |
445 | 447 | ||
446 | if ( !ucmQueryVerificationdataProc || | 448 | if ( !ucmQueryVerificationdataProc || |
447 | !qt_parse_pattern( ucmQueryVerificationdataProc(), | 449 | !qt_parse_pattern( ucmQueryVerificationdataProc(), |
448 | &qt_version, &flags, &key ) ) { | 450 | &qt_version, &flags, &key ) ) { |
449 | qt_version = flags = 0; | 451 | qt_version = flags = 0; |
450 | key = "unknown"; | 452 | key = "unknown"; |
451 | } else { | 453 | } else { |
452 | query_done = TRUE; | 454 | query_done = TRUE; |
453 | } | 455 | } |
454 | } | 456 | } |
455 | #endif // Q_OS_UNIX | 457 | #endif // Q_OS_UNIX |
456 | 458 | ||
457 | QStringList queried; | 459 | QStringList queried; |
458 | queried << QString::number( qt_version,16 ) | 460 | queried << QString::number( qt_version,16 ) |
459 | << QString::number( flags, 16 ) | 461 | << QString::number( flags, 16 ) |
460 | << key | 462 | << key |
461 | << lastModified; | 463 | << lastModified; |
462 | 464 | ||
463 | if ( queried != reg ) { | 465 | if ( queried != reg ) { |
464 | |||
465 | #ifdef QT_THREAD_SUPPORT | ||
466 | QMutexLocker locker( qt_global_mutexpool->get( &cache ) ); | ||
467 | #endif // QT_THREAD_SUPPORT | ||
468 | |||
469 | cache->writeEntry( regkey, queried ); | 466 | cache->writeEntry( regkey, queried ); |
470 | // delete the cache, which forces the settings to be written | 467 | // delete the cache, which forces the settings to be written |
471 | delete cache; | 468 | delete cache; |
472 | cache = 0; | 469 | cache = 0; |
473 | } | 470 | } |
474 | 471 | ||
475 | if ( ! query_done ) { | 472 | if ( ! query_done ) { |
476 | if ( warn_mismatch ) { | 473 | if ( warn_mismatch ) { |
477 | qWarning( "Conflict in %s:\n Plugin cannot be queried successfully!", | 474 | qWarning( "Conflict in %s:\n Plugin cannot be queried successfully!", |
478 | (const char*) QFile::encodeName( library() ) ); | 475 | (const char*) QFile::encodeName( library() ) ); |
479 | } | 476 | } |
480 | unload(); | 477 | unload(); |
481 | return; | 478 | return; |
482 | } | 479 | } |
483 | 480 | ||
484 | if ( ! qt_verify( library(), qt_version, flags, key, warn_mismatch ) ) { | 481 | if ( ! qt_verify( library(), qt_version, flags, key, warn_mismatch ) ) { |
485 | unload(); | 482 | unload(); |
486 | return; | 483 | return; |
487 | } else if ( !isLoaded() ) { | 484 | } else if ( !isLoaded() ) { |
488 | Q_ASSERT( entry == 0 ); | 485 | Q_ASSERT( entry == 0 ); |
489 | if ( !load() ) | 486 | if ( !load() ) |
490 | return; | 487 | return; |
491 | } | 488 | } |
492 | 489 | ||
493 | #ifdef Q_CC_BOR | 490 | #ifdef Q_CC_BOR |
494 | typedef QUnknownInterface* __stdcall (*UCMInstanceProc)(); | 491 | typedef QUnknownInterface* __stdcall (*UCMInstanceProc)(); |
495 | #else | 492 | #else |
496 | typedef QUnknownInterface* (*UCMInstanceProc)(); | 493 | typedef QUnknownInterface* (*UCMInstanceProc)(); |
497 | #endif | 494 | #endif |
498 | UCMInstanceProc ucmInstanceProc; | 495 | UCMInstanceProc ucmInstanceProc; |
499 | ucmInstanceProc = (UCMInstanceProc) resolve( "ucm_instantiate" ); | 496 | ucmInstanceProc = (UCMInstanceProc) resolve( "ucm_instantiate" ); |
500 | #if defined(QT_DEBUG_COMPONENT) | 497 | #if defined(QT_DEBUG_COMPONENT) |
501 | if ( !ucmInstanceProc ) | 498 | if ( !ucmInstanceProc ) |
502 | qWarning( "%s: Not a UCOM library.", (const char*) QFile::encodeName(library()) ); | 499 | qWarning( "%s: Not a UCOM library.", (const char*) QFile::encodeName(library()) ); |
503 | #endif | 500 | #endif |
504 | entry = ucmInstanceProc ? ucmInstanceProc() : 0; | 501 | entry = ucmInstanceProc ? ucmInstanceProc() : 0; |
505 | 502 | ||
506 | if ( entry ) { | 503 | if ( entry ) { |
507 | if ( entry->queryInterface( IID_QLibrary, (QUnknownInterface**)&libiface ) == QS_OK ) { | 504 | if ( entry->queryInterface( IID_QLibrary, (QUnknownInterface**)&libiface ) == QS_OK ) { |
508 | if ( libiface && !libiface->init() ) { | 505 | if ( libiface && !libiface->init() ) { |
509 | libiface->release(); | 506 | libiface->release(); |
510 | libiface = 0; | 507 | libiface = 0; |
511 | unload(); | 508 | unload(); |
512 | return; | 509 | return; |
513 | } | 510 | } |
514 | } | 511 | } |
515 | } else { | 512 | } else { |
516 | #if defined(QT_DEBUG_COMPONENT) | 513 | #if defined(QT_DEBUG_COMPONENT) |