Summary: | Crash when unloading plugin | ||
---|---|---|---|
Product: | [Applications] ktorrent | Reporter: | Thomas Tanghus <thomas> |
Component: | general | Assignee: | Joris Guisson <joris.guisson> |
Status: | RESOLVED FIXED | ||
Severity: | crash | ||
Priority: | NOR | ||
Version: | unspecified | ||
Target Milestone: | --- | ||
Platform: | unspecified | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: |
Description
Thomas Tanghus
2007-04-26 22:42:58 UTC
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: /** |