qlibrary.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "qlibrary_p.h"
00023
00024
00025
00026
00027
00028
00029 #ifndef QT_DEBUG_COMPONENT
00030 # if defined(QT_DEBUG)
00031 # define QT_DEBUG_COMPONENT 1
00032 # endif
00033 #endif
00034
00035 #ifndef QT_NO_COMPONENT
00036
00037
00038
00039 #if defined(Q_CC_KAI) || defined(Q_OS_MAC)
00040 #define QT_NO_LIBRARY_UNLOAD
00041 #endif
00042
00043 #if defined(Q_WS_WIN) && !defined(QT_MAKEDLL)
00044 #define QT_NO_LIBRARY_UNLOAD
00045 #endif
00046
00047
00048 #ifndef QT_LITE_COMPONENT
00049
00050 #include "qtimer.h"
00051
00052 extern Q_EXPORT QApplication *qApp;
00053
00054 QLibraryPrivate::QLibraryPrivate( QLibrary *lib )
00055 : QObject( 0, lib->library().latin1() ), pHnd( 0 ), libIface( 0 ), unloadTimer( 0 ), library( lib )
00056 {
00057 }
00058
00059 QLibraryPrivate::~QLibraryPrivate()
00060 {
00061 if ( libIface )
00062 libIface->release();
00063 killTimer();
00064 }
00065
00066
00067
00068
00069
00070 void QLibraryPrivate::tryUnload()
00071 {
00072 if ( library->policy() == QLibrary::Manual || !pHnd || !libIface )
00073 return;
00074
00075 if ( !libIface->canUnload() )
00076 return;
00077
00078 #if defined(QT_DEBUG_COMPONENT) && QT_DEBUG_COMPONENT == 2
00079 if ( library->unload() )
00080 qDebug( "%s has been automatically unloaded", library->library().latin1() );
00081 #else
00082 library->unload();
00083 #endif
00084 }
00085
00086 #else // QT_LITE_COMPOINENT
00087
00088 QLibraryPrivate::QLibraryPrivate( QLibrary *lib )
00089 : pHnd( 0 ), libIface( 0 ), library( lib )
00090 {
00091 }
00092
00093 #endif // QT_LITE_COMPOINENT
00094
00095 void QLibraryPrivate::startTimer()
00096 {
00097 #ifndef QT_LITE_COMPONENT
00098 unloadTimer = new QTimer( this );
00099 connect( unloadTimer, SIGNAL( timeout() ), this, SLOT( tryUnload() ) );
00100 unloadTimer->start( 5000, FALSE );
00101 #endif
00102 }
00103
00104 void QLibraryPrivate::killTimer()
00105 {
00106 #ifndef QT_LITE_COMPONENT
00107 delete unloadTimer;
00108 unloadTimer = 0;
00109 #endif
00110 }
00111
00154 QLibrary::QLibrary( const QString& filename, Policy pol )
00155 : libfile( filename ), libPol( pol ), entry( 0 )
00156 {
00157 d = new QLibraryPrivate( this );
00158 if ( pol == Immediately )
00159 load();
00160 }
00161
00168 QLibrary::~QLibrary()
00169 {
00170 if ( libPol == Manual || !unload() ) {
00171 if ( entry ) {
00172 entry->release();
00173 entry = 0;
00174 }
00175 }
00176 delete d;
00177 }
00178
00179 void QLibrary::createInstanceInternal()
00180 {
00181 if ( libfile.isEmpty() )
00182 return;
00183
00184 if ( !d->pHnd ) {
00185 ASSERT( entry == 0 );
00186 load();
00187 }
00188
00189 if ( d->pHnd && !entry ) {
00190 #if defined(QT_DEBUG_COMPONENT) && QT_DEBUG_COMPONENT == 2
00191 qWarning( "%s has been loaded.", library().latin1() );
00192 #endif
00193 typedef QUnknownInterface* (*UCMInstanceProc)();
00194 UCMInstanceProc ucmInstanceProc;
00195 ucmInstanceProc = (UCMInstanceProc) resolve( "ucm_instantiate" );
00196 entry = ucmInstanceProc ? ucmInstanceProc() : 0;
00197 if ( entry ) {
00198 entry->queryInterface( IID_QLibrary, (QUnknownInterface**)&d->libIface);
00199 if ( d->libIface ) {
00200 if ( !d->libIface->init() ) {
00201 #if defined(QT_DEBUG_COMPONENT)
00202 qWarning( "%s: QLibraryInterface::init() failed.", library().latin1() );
00203 #endif
00204 unload();
00205 return;
00206 }
00207
00208 d->killTimer();
00209 if ( libPol != Manual )
00210 d->startTimer();
00211 }
00212 } else {
00213 #if defined(QT_DEBUG_COMPONENT)
00214 qWarning( "%s: No interface implemented.", library().latin1() );
00215 #endif
00216 unload();
00217 }
00218 }
00219 }
00220
00238 void *QLibrary::resolve( const char* symb )
00239 {
00240 if ( !d->pHnd )
00241 load();
00242 if ( !d->pHnd )
00243 return 0;
00244
00245 void *address = d->resolveSymbol( symb );
00246 if ( !address ) {
00247 #if defined(QT_DEBUG_COMPONENT)
00248
00249 qWarning( QString("Trying to resolve symbol \"_%1\" instead").arg( symb ) );
00250 #endif
00251 address = d->resolveSymbol( QString( "_" ) + symb );
00252 }
00253 return address;
00254 }
00255
00266 void *QLibrary::resolve( const QString &filename, const char *symb )
00267 {
00268 QLibrary lib( filename, Manual );
00269 return lib.resolve( symb );
00270 }
00271
00277 bool QLibrary::isLoaded() const
00278 {
00279 return d->pHnd != 0;
00280 }
00281
00285 bool QLibrary::load()
00286 {
00287 return d->loadLibrary();
00288 }
00289
00307 bool QLibrary::unload( bool force )
00308 {
00309 if ( !d->pHnd )
00310 return TRUE;
00311
00312 if ( entry ) {
00313 if ( d->libIface ) {
00314 d->libIface->cleanup();
00315
00316 bool can = d->libIface->canUnload();
00317 can = ( d->libIface->release() <= 1 ) && can;
00318
00319 if ( can || force ) {
00320 d->libIface = 0;
00321 } else {
00322 #if defined(QT_DEBUG_COMPONENT)
00323 qWarning( "%s prevents unloading!", library().latin1() );
00324 #endif
00325 d->libIface->addRef();
00326 return FALSE;
00327 }
00328 }
00329
00330 if ( entry->release() ) {
00331 #if defined(QT_DEBUG_COMPONENT)
00332 qWarning( "%s is still in use!", library().latin1() );
00333 #endif
00334 if ( force ) {
00335 delete entry;
00336 } else {
00337 entry->addRef();
00338 return FALSE;
00339 }
00340 }
00341 d->killTimer();
00342
00343 entry = 0;
00344 }
00345
00346
00347
00348 #if !defined(QT_NO_LIBRARY_UNLOAD)
00349 if ( !d->freeLibrary() ) {
00350 #if defined(QT_DEBUG_COMPONENT)
00351 qWarning( "%s could not be unloaded.", library().latin1() );
00352 #endif
00353 return FALSE;
00354 #else
00355 return TRUE;
00356 #endif
00357 #if !defined(QT_NO_LIBRARY_UNLOAD)
00358 }
00359
00360 #if defined(QT_DEBUG_COMPONENT) && QT_DEBUG_COMPONENT == 2
00361 qWarning( "%s has been unloaded.", library().latin1() );
00362 #endif
00363
00364 d->pHnd = 0;
00365 return TRUE;
00366 #endif
00367 }
00368
00373 void QLibrary::setPolicy( Policy pol )
00374 {
00375 libPol = pol;
00376
00377 if ( libPol == Immediately && !d->pHnd )
00378 load();
00379 }
00380
00386 QLibrary::Policy QLibrary::policy() const
00387 {
00388 return libPol;
00389 }
00390
00402 QString QLibrary::library() const
00403 {
00404 if ( libfile.isEmpty() )
00405 return libfile;
00406
00407 QString filename = libfile;
00408 #if defined(Q_WS_WIN)
00409 if ( filename.find( ".dll" ) == -1 )
00410 filename += ".dll";
00411 #elif defined(Q_OS_MACX)
00412 if ( filename.find( ".dylib" ) == -1 )
00413 filename += ".dylib";
00414 #else
00415 if ( filename.find( ".so" ) == -1 )
00416 filename = QString( "lib%1.so" ).arg( filename );
00417 #endif
00418
00419 return filename;
00420 }
00421
00428 QRESULT QLibrary::queryInterface( const QUuid& request, QUnknownInterface** iface )
00429 {
00430 if ( !entry ) {
00431 createInstanceInternal();
00432 }
00433
00434 return entry ? entry->queryInterface( request, iface ) : QE_NOINTERFACE;
00435 }
00436
00437 #endif // QT_NO_COMPONENT
This file is part of the documentation for OPIE Version 1.5.5.