SVN commit 1215095 by trueg: If a service goes down, also shutdown all services depending on it and schedule them for restart. M +3 -0 servicecontroller.cpp M +7 -1 servicecontroller.h M +33 -8 servicemanager.cpp M +1 -0 servicemanager.h --- trunk/KDE/kdebase/runtime/nepomuk/server/servicecontroller.cpp #1215094:1215095 @@ -305,6 +305,9 @@ // on its restart-on-crash feature and have to do it manually. Afterwards it is back // to normal if( serviceName == dbusServiceName( name() ) ) { + + emit serviceStopped( this ); + if( d->attached && d->started ) { kDebug() << "Attached service" << name() << "went down. Restarting ourselves."; start(); --- trunk/KDE/kdebase/runtime/nepomuk/server/servicecontroller.h #1215094:1215095 @@ -78,15 +78,21 @@ */ void serviceInitialized( ServiceController* ); + /** + * Emitted once the service has stopped, i.e. + * once its DBus service is gone. + */ + void serviceStopped( ServiceController* ); + private Q_SLOTS: void slotProcessFinished( bool ); void slotServiceRegistered( const QString& serviceName ); void slotServiceUnregistered( const QString& serviceName ); void slotServiceInitialized( bool success ); - private: void createServiceControlInterface(); + private: class Private; Private* const d; }; --- trunk/KDE/kdebase/runtime/nepomuk/server/servicemanager.cpp #1215094:1215095 @@ -170,6 +170,12 @@ */ void _k_serviceInitialized( ServiceController* ); + /** + * Slot connected to all ServiceController::serviceStopped + * signals. + */ + void _k_serviceStopped( ServiceController* ); + private: bool m_initialized; ServiceManager* q; @@ -198,6 +204,8 @@ ServiceController* sc = new ServiceController( service, q ); connect( sc, SIGNAL(serviceInitialized(ServiceController*)), q, SLOT(_k_serviceInitialized(ServiceController*)) ); + connect( sc, SIGNAL(serviceStopped(ServiceController*)), + q, SLOT(_k_serviceStopped(ServiceController*)) ); services.insert( sc->name(), sc ); } } @@ -226,7 +234,7 @@ bool needToQueue = false; foreach( const QString &dependency, dependencyTree[sc->name()] ) { ServiceController* depSc = findService( dependency ); - if ( !depSc->isInitialized() ) { + if ( !needToQueue && !depSc->isInitialized() ) { kDebug() << "Queueing" << sc->name() << "due to dependency" << dependency; pendingServices.insert( sc ); needToQueue = true; @@ -247,16 +255,13 @@ bool Nepomuk::ServiceManager::Private::stopService( ServiceController* sc ) { - // make sure the service is not scheduled to be started later anymore - pendingServices.remove( sc ); - - // stop it if already running - if( sc->isRunning() ) { // shut down any service depending of this one first foreach( const QString &dep, dependencyTree.servicesDependingOn( sc->name() ) ) { stopService( services[dep] ); } + // stop it if already running + if( sc->isRunning() ) { sc->stop(); return true; } @@ -268,6 +273,8 @@ void Nepomuk::ServiceManager::Private::startPendingServices( ServiceController* newService ) { + kDebug() << newService->name() << pendingServices; + // check the list of pending services and start as many as possible // (we can start services whose dependencies are initialized) QList sl = pendingServices.toList(); @@ -284,14 +291,29 @@ void Nepomuk::ServiceManager::Private::_k_serviceInitialized( ServiceController* sc ) { kDebug() << "Service initialized:" << sc->name(); - if ( !pendingServices.isEmpty() ) { + startPendingServices( sc ); - } emit q->serviceInitialized( sc->name() ); } +void Nepomuk::ServiceManager::Private::_k_serviceStopped( ServiceController* sc ) +{ + kDebug() << "Service stopped:" << sc->name(); + // stop and queue all services depending on the stopped one + // this will re-trigger this method until all reverse-deps are stopped + foreach( const QString &dep, dependencyTree.servicesDependingOn( sc->name() ) ) { + ServiceController* depsc = services[dep]; + if( depsc->isRunning() ) { + kDebug() << "Stopping and queuing rev-dep" << depsc->name(); + depsc->stop(); + pendingServices.insert( depsc ); + } + } +} + + Nepomuk::ServiceManager::ServiceManager( QObject* parent ) : QObject(parent), d(new Private(this)) @@ -350,6 +372,9 @@ bool Nepomuk::ServiceManager::stopService( const QString& name ) { if( ServiceController* sc = d->findService( name ) ) { + // make sure the service is not scheduled to be started later anymore + d->pendingServices.remove( sc ); + return d->stopService( sc ); } return false; --- trunk/KDE/kdebase/runtime/nepomuk/server/servicemanager.h #1215094:1215095 @@ -124,6 +124,7 @@ Private* const d; Q_PRIVATE_SLOT( d, void _k_serviceInitialized(ServiceController*) ) + Q_PRIVATE_SLOT( d, void _k_serviceStopped(ServiceController*) ) }; }