Пример #1
0
void KLibLoader::unloadLibrary(const char *libname)
{
    KLibWrapPrivate *wrap = m_libs[libname];
    if(!wrap)
        return;
    if(--wrap->ref_count)
        return;

    //  kdDebug(150) << "closing library " << libname << endl;

    m_libs.remove(libname);

    disconnect(wrap->lib, SIGNAL(destroyed()), this, SLOT(slotLibraryDestroyed()));
    close_pending(wrap);
}
Пример #2
0
void KLibLoader::close_pending(KLibWrapPrivate *wrap)
{
  if (wrap && !d->pending_close.containsRef( wrap ))
    d->pending_close.append( wrap );

  /* First delete all KLibrary objects in pending_close, but _don't_ unload
     the DSO behind it.  */
  QPtrListIterator<KLibWrapPrivate> it(d->pending_close);
  for (; it.current(); ++it) {
    wrap = it.current();
    if (wrap->lib) {
      disconnect( wrap->lib, SIGNAL( destroyed() ),
                  this, SLOT( slotLibraryDestroyed() ) );
      KLibrary* to_delete = wrap->lib;
      wrap->lib = 0L; // unset first, because KLibrary dtor can cause
      delete to_delete; // recursive call to close_pending()
    }
  }

  if (d->unload_mode == KLibLoaderPrivate::DONT_UNLOAD) {
    d->pending_close.clear();
    return;
  }

  bool deleted_one = false;
  while ((wrap = d->loaded_stack.first())) {
    /* Let's first see, if we want to try to unload this lib.
       If the env. var KDE_DOUNLOAD is set, we try to unload every lib.
       If not, we look at the lib itself, and unload it only, if it exports
       the symbol __kde_do_unload. */
    if (d->unload_mode != KLibLoaderPrivate::UNLOAD
        && wrap->unload_mode != KLibWrapPrivate::UNLOAD)
      break;

    /* Now ensure, that the libs are only unloaded in the reverse direction
       they were loaded.  */
    if (!d->pending_close.containsRef( wrap )) {
      if (!deleted_one)
        /* Only diagnose, if we really haven't deleted anything. */
//        kdDebug(150) << "try to dlclose " << wrap->name << ": not yet" << endl;
      break;
    }

//    kdDebug(150) << "try to dlclose " << wrap->name << ": yes, done." << endl;

    if ( !deleted_one ) {
      /* Only do the hack once in this loop.
         WABA: *HACK*
         We need to make sure to clear the clipboard before unloading a DSO
         because the DSO could have defined an object derived from QMimeSource
         and placed that on the clipboard. */
      /*kapp->clipboard()->clear();*/

      /* Well.. let's do something more subtle... convert the clipboard context
         to text. That should be safe as it only uses objects defined by Qt. */
      if( kapp->clipboard()->ownsSelection()) {
	kapp->clipboard()->setText(
            kapp->clipboard()->text( QClipboard::Selection ), QClipboard::Selection );
      }
      if( kapp->clipboard()->ownsClipboard()) {
	kapp->clipboard()->setText(
            kapp->clipboard()->text( QClipboard::Clipboard ), QClipboard::Clipboard );
      }
    }

    deleted_one = true;
    lt_dlclose(wrap->handle);
    d->pending_close.removeRef(wrap);
    /* loaded_stack is AutoDelete, so wrap is freed */
    d->loaded_stack.remove();
  }
}
Пример #3
0
KLibrary* KLibLoader::library( const char *name )
{
    if (!name)
        return 0;

    KLibWrapPrivate* wrap = m_libs[name];
    if (wrap) {
      /* Nothing to do to load the library.  */
      wrap->ref_count++;
      return wrap->lib;
    }

    /* Test if this library was loaded at some time, but got
       unloaded meanwhile, whithout being dlclose()'ed.  */
    QPtrListIterator<KLibWrapPrivate> it(d->loaded_stack);
    for (; it.current(); ++it) {
      if (it.current()->name == name)
        wrap = it.current();
    }

    if (wrap) {
      d->pending_close.removeRef(wrap);
      if (!wrap->lib) {
        /* This lib only was in loaded_stack, but not in m_libs.  */
        wrap->lib = new KLibrary( name, wrap->filename, wrap->handle );
      }
      wrap->ref_count++;
    } else {
      QString libfile = findLibrary( name );
      if ( libfile.isEmpty() )
      {
        const QCString libname = makeLibName( name );
#ifndef NDEBUG
        kdDebug(150) << "library=" << name << ": No file named " << libname << " found in paths." << endl;
#endif
        d->errorMessage = i18n("Library files for \"%1\" not found in paths.").arg(libname);
        return 0;
      }

      lt_dlhandle handle = lt_dlopen( QFile::encodeName(libfile) );
      if ( !handle )
      {
        const char* errmsg = lt_dlerror();
        if(errmsg)
            d->errorMessage = QString::fromLocal8Bit(errmsg);
        else
            d->errorMessage = QString::null;
        return 0;
      }
      else
        d->errorMessage = QString::null;

      KLibrary *lib = new KLibrary( name, libfile, handle );
      wrap = new KLibWrapPrivate(lib, handle);
      d->loaded_stack.prepend(wrap);
    }
    m_libs.insert( name, wrap );

    connect( wrap->lib, SIGNAL( destroyed() ),
             this, SLOT( slotLibraryDestroyed() ) );

    return wrap->lib;
}