Version: 2.1.4 (using KDE 3.5.5, Kubuntu (dapper) 4:3.5.5-0ubuntu1~dapper2) Compiler: Target: i486-linux-gnu OS: Linux (i686) release 2.6.15-28-686 KTorrent crashed when I unloaded the scheduler plugin. Wasn't able to reproduce it. Backtrace below: [KCrash handler] #6 0xb5ab4ea0 in kt::InfoWidget::update () from /usr/lib/kde3/ktinfowidgetplugin.so #7 0xb5aabc6c in kt::InfoWidgetPlugin::guiUpdate () from /usr/lib/kde3/ktinfowidgetplugin.so #8 0xb7de3982 in kt::PluginManager::updateGuiPlugins () from /usr/lib/libktorrent-2.1.4.so #9 0x080690de in QGList::count () #10 0x08069665 in QGList::count () #11 0xb6ece051 in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #12 0xb6eceaec in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #13 0xb7263686 in QTimer::timeout () from /usr/lib/libqt-mt.so.3 #14 0xb6ef3049 in QTimer::event () from /usr/lib/libqt-mt.so.3 #15 0xb6e63f3e in QApplication::internalNotify () from /usr/lib/libqt-mt.so.3 #16 0xb6e6413a in QApplication::notify () from /usr/lib/libqt-mt.so.3 #17 0xb75fc1cd in KApplication::notify () from /usr/lib/libkdecore.so.4 #18 0xb6df5157 in QApplication::sendEvent () from /usr/lib/libqt-mt.so.3 #19 0xb6e5592b in QEventLoop::activateTimers () from /usr/lib/libqt-mt.so.3 #20 0xb6e08f67 in QEventLoop::processEvents () from /usr/lib/libqt-mt.so.3 #21 0xb6e7ca2f in QEventLoop::enterLoop () from /usr/lib/libqt-mt.so.3 #22 0xb6e62a79 in QApplication::enter_loop () from /usr/lib/libqt-mt.so.3 #23 0xb7ad0ecf in KIO::NetAccess::enter_loop () from /usr/lib/libkio.so.4 #24 0xb7b144b5 in KIO::NetAccess::synchronousRunInternal () from /usr/lib/libkio.so.4 #25 0xb7b145e2 in KIO::NetAccess::synchronousRun () from /usr/lib/libkio.so.4 #26 0xb7e0f641 in bt::WaitJob::execute () from /usr/lib/libktorrent-2.1.4.so #27 0xb5b214c4 in kt::UPnPPrefWidget::~UPnPPrefWidget () from /usr/lib/kde3/ktupnpplugin.so #28 0xb5b20321 in kt::UPnPPrefPage::deleteWidget () from /usr/lib/kde3/ktupnpplugin.so #29 0x0807110e in QValueList<QCString>::detachInternal () #30 0xb5b1f6c4 in kt::UPnPPlugin::unload () from /usr/lib/kde3/ktupnpplugin.so #31 0xb7de3c4c in kt::PluginManager::unloadAll () from /usr/lib/libktorrent-2.1.4.so #32 0xb7de890b in kt::PluginManagerPrefPage::onUnloadAll () from /usr/lib/libktorrent-2.1.4.so #33 0xb7df3c5c in kt::PluginManagerPrefPage::qt_invoke () from /usr/lib/libktorrent-2.1.4.so #34 0xb6ece051 in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #35 0xb6eceaec in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #36 0xb726a007 in QButton::clicked () from /usr/lib/libqt-mt.so.3 #37 0xb6f696f6 in QButton::mouseReleaseEvent () from /usr/lib/libqt-mt.so.3 #38 0xb6f08825 in QWidget::event () from /usr/lib/libqt-mt.so.3 #39 0xb6e63f3e in QApplication::internalNotify () from /usr/lib/libqt-mt.so.3 #40 0xb6e644c8 in QApplication::notify () from /usr/lib/libqt-mt.so.3 #41 0xb75fc1cd in KApplication::notify () from /usr/lib/libkdecore.so.4 #42 0xb6df51c5 in QApplication::sendSpontaneousEvent () from /usr/lib/libqt-mt.so.3 #43 0xb6df0873 in QETWidget::translateMouseEvent () from /usr/lib/libqt-mt.so.3 #44 0xb6deed59 in QApplication::x11ProcessEvent () from /usr/lib/libqt-mt.so.3 #45 0xb6e084db in QEventLoop::processEvents () from /usr/lib/libqt-mt.so.3 #46 0xb6e7ca2f in QEventLoop::enterLoop () from /usr/lib/libqt-mt.so.3 #47 0xb6e62a79 in QApplication::enter_loop () from /usr/lib/libqt-mt.so.3 #48 0xb70815c4 in QDialog::exec () from /usr/lib/libqt-mt.so.3 #49 0x080695e9 in QGList::count () #50 0xb6ece051 in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #51 0xb6eceaec in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #52 0xb7801607 in KAction::activated () from /usr/lib/libkdeui.so.4 #53 0xb78346a2 in KAction::slotActivated () from /usr/lib/libkdeui.so.4 #54 0xb78e33d4 in KAction::slotPopupActivated () from /usr/lib/libkdeui.so.4 #55 0xb78e38e5 in KAction::qt_invoke () from /usr/lib/libkdeui.so.4 #56 0xb6ece051 in QObject::activate_signal () from /usr/lib/libqt-mt.so.3 #57 0xb7261582 in QSignal::signal () from /usr/lib/libqt-mt.so.3 #58 0xb6eeb7c8 in QSignal::activate () from /usr/lib/libqt-mt.so.3 #59 0xb6ff3149 in QPopupMenu::mouseReleaseEvent () from /usr/lib/libqt-mt.so.3 #60 0xb780ccfd in KPopupMenu::mouseReleaseEvent () from /usr/lib/libkdeui.so.4 #61 0xb6f08825 in QWidget::event () from /usr/lib/libqt-mt.so.3 #62 0xb6e63f3e in QApplication::internalNotify () from /usr/lib/libqt-mt.so.3 #63 0xb6e644c8 in QApplication::notify () from /usr/lib/libqt-mt.so.3 #64 0xb75fc1cd in KApplication::notify () from /usr/lib/libkdecore.so.4 #65 0xb6df51c5 in QApplication::sendSpontaneousEvent () from /usr/lib/libqt-mt.so.3 #66 0xb6df05c0 in QETWidget::translateMouseEvent () from /usr/lib/libqt-mt.so.3 #67 0xb6deed59 in QApplication::x11ProcessEvent () from /usr/lib/libqt-mt.so.3 #68 0xb6e084db in QEventLoop::processEvents () from /usr/lib/libqt-mt.so.3 #69 0xb6e7ca2f in QEventLoop::enterLoop () from /usr/lib/libqt-mt.so.3 #70 0xb6e7c952 in QEventLoop::exec () from /usr/lib/libqt-mt.so.3 #71 0xb6e62a4d in QApplication::exec () from /usr/lib/libqt-mt.so.3 #72 0x08063f70 in ?? () #73 0xb66eaea2 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 #74 0x08063a21 in ?? ()
We will see if we can reproduce this
SVN commit 668722 by guisson: Revamped unloading of plugins, there is now a shutdown method which can be overriden by plugins who which to do some ExitOperations when they are unloaded. This fixes bug 144727. BUG: 144727 M +4 -0 libktorrent/interfaces/plugin.cpp M +12 -0 libktorrent/interfaces/plugin.h M +36 -0 libktorrent/pluginmanager.cpp M +5 -0 plugins/upnp/upnpplugin.cpp M +1 -0 plugins/upnp/upnpplugin.h M +4 -0 plugins/upnp/upnpprefpage.cpp M +7 -1 plugins/upnp/upnpprefpage.h M +15 -23 plugins/upnp/upnpprefwidget.cpp M +7 -0 plugins/upnp/upnpprefwidget.h --- trunk/extragear/network/ktorrent/libktorrent/interfaces/plugin.cpp #668721:668722 @@ -40,5 +40,9 @@ void Plugin::guiUpdate() { } + + void Plugin::shutdown(bt::WaitJob* ) + { + } } #include "plugin.moc" --- trunk/extragear/network/ktorrent/libktorrent/interfaces/plugin.h #668721:668722 @@ -23,6 +23,11 @@ #include <ktversion.h> #include <kparts/plugin.h> +namespace bt +{ + class WaitJob; +} + namespace kt { class CoreInterface; @@ -78,6 +83,13 @@ * GUI updates. */ virtual void guiUpdate(); + + /** + * This should be implemented by plugins who need finish of some stuff which might take some time. + * These operations must be finished or killed by a timeout before we can proceed with unloading the plugin. + * @param job The WaitJob which monitors the plugin + */ + virtual void shutdown(bt::WaitJob* job); const QString & getName() const {return name;} const QString & getAuthor() const {return author;} --- trunk/extragear/network/ktorrent/libktorrent/pluginmanager.cpp #668721:668722 @@ -23,6 +23,7 @@ #include <util/log.h> #include <util/error.h> #include <util/fileops.h> +#include <util/waitjob.h> #include <torrent/globals.h> #include <interfaces/guiinterface.h> #include "pluginmanager.h" @@ -114,6 +115,20 @@ Plugin* p = plugins.find(name); if (!p) return; + + // first shut it down properly + bt::WaitJob* wjob = new WaitJob(2000); + try + { + p->shutdown(wjob); + if (wjob->needToWait()) + bt::WaitJob::execute(wjob); + } + catch (Error & err) + { + Out(SYS_GEN|LOG_NOTICE) << "Error when unloading plugin: " << err.toString() << endl; + } + delete wjob; gui->removePluginGui(p); p->unload(); @@ -146,6 +161,27 @@ void PluginManager::unloadAll(bool save) { + // first properly shutdown all plugins + bt::WaitJob* wjob = new WaitJob(2000); + try + { + bt::PtrMap<QString,Plugin>::iterator i = plugins.begin(); + while (i != plugins.end()) + { + Plugin* p = i->second; + p->shutdown(wjob); + i++; + } + if (wjob->needToWait()) + bt::WaitJob::execute(wjob); + } + catch (Error & err) + { + Out(SYS_GEN|LOG_NOTICE) << "Error when unloading all plugins: " << err.toString() << endl; + } + delete wjob; + + // then unload them bt::PtrMap<QString,Plugin>::iterator i = plugins.begin(); while (i != plugins.end()) { --- trunk/extragear/network/ktorrent/plugins/upnp/upnpplugin.cpp #668721:668722 @@ -82,6 +82,11 @@ sock = 0; } + void UPnPPlugin::shutdown(bt::WaitJob* job) + { + pref->shutdown(job); + } + bool UPnPPlugin::versionCheck(const QString & version) const { return version == KT_VERSION_MACRO; --- trunk/extragear/network/ktorrent/plugins/upnp/upnpplugin.h #668721:668722 @@ -39,6 +39,7 @@ virtual void load(); virtual void unload(); + virtual void shutdown(bt::WaitJob* job); virtual bool versionCheck(const QString& version) const; private: UPnPMCastSocket* sock; --- trunk/extragear/network/ktorrent/plugins/upnp/upnpprefpage.cpp #668721:668722 @@ -59,4 +59,8 @@ void UPnPPrefPage::updateData() { } + + void UPnPPrefPage::shutdown(bt::WaitJob* job) + { + } } --- trunk/extragear/network/ktorrent/plugins/upnp/upnpprefpage.h #668721:668722 @@ -22,6 +22,11 @@ #include <interfaces/prefpageinterface.h> +namespace bt +{ + class WaitJob; +} + namespace kt { class UPnPMCastSocket; @@ -44,7 +49,8 @@ virtual void createWidget(QWidget* parent); virtual void deleteWidget(); virtual void updateData(); - + + void shutdown(bt::WaitJob* job); }; } --- trunk/extragear/network/ktorrent/plugins/upnp/upnpprefwidget.cpp #668721:668722 @@ -50,30 +50,22 @@ UPnPPrefWidget::~UPnPPrefWidget() { bt::Globals::instance().getPortList().setListener(0); - if (def_router) + } + + void UPnPPrefWidget::shutdown(bt::WaitJob* job) + { + if (!def_router) + return; + + net::PortList & pl = bt::Globals::instance().getPortList(); + if (pl.count() == 0) + return; + + for (net::PortList::iterator i = pl.begin(); i != pl.end();i++) { - try - { - net::PortList & pl = bt::Globals::instance().getPortList(); - - if (pl.count() == 0) - return; - - bt::WaitJob* job = new WaitJob(1000); - for (net::PortList::iterator i = pl.begin(); i != pl.end();i++) - { - net::Port & p = *i; - if (p.forward) - def_router->undoForward(p,job); - } - - // wait for operations to finish or timeout - bt::WaitJob::execute(job); - } - catch (Error & e) - { - Out(SYS_PNP|LOG_DEBUG) << "Error : " << e.toString() << endl; - } + net::Port & p = *i; + if (p.forward) + def_router->undoForward(p,job); } } --- trunk/extragear/network/ktorrent/plugins/upnp/upnpprefwidget.h #668721:668722 @@ -27,6 +27,11 @@ class KListViewItem; +namespace bt +{ + class WaitJob; +} + namespace kt { @@ -41,6 +46,8 @@ UPnPPrefWidget(QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); virtual ~UPnPPrefWidget(); + void shutdown(bt::WaitJob* job); + public slots: /**