Fix long delay at session termination on certain systems

This resolves Bug 760
Add shutdown profiling code and disable at compile time
(cherry picked from commit 1c7bdfda1e)
v3.5.13-sru
Timothy Pearson 12 years ago committed by Slávek Banko
parent 52921d802e
commit 67afcf177e

@ -927,6 +927,16 @@ bool KSMServer::isCM( const TQString& program ) const
return (program == "kompmgr"); return (program == "kompmgr");
} }
bool KSMServer::isNotifier( const KSMClient* client ) const
{
return isNotifier( client->program());
}
bool KSMServer::isNotifier( const TQString& program ) const
{
return (program == "knotify");
}
bool KSMServer::defaultSession() const bool KSMServer::defaultSession() const
{ {
return sessionGroup.isEmpty(); return sessionGroup.isEmpty();

@ -142,11 +142,13 @@ private:
const TQString& clientMachine = TQString::null, const TQString& clientMachine = TQString::null,
const TQString& userId = TQString::null ); const TQString& userId = TQString::null );
void executeCommand( const TQStringList& command ); void executeCommand( const TQStringList& command );
bool isWM( const KSMClient* client ) const; bool isWM( const KSMClient* client ) const;
bool isWM( const TQString& program ) const; bool isWM( const TQString& program ) const;
bool isCM( const KSMClient* client ) const; bool isCM( const KSMClient* client ) const;
bool isCM( const TQString& program ) const; bool isCM( const TQString& program ) const;
bool isNotifier( const KSMClient* client ) const;
bool isNotifier( const TQString& program ) const;
bool defaultSession() const; // empty session bool defaultSession() const; // empty session
void setupXIOErrorHandler(); void setupXIOErrorHandler();

@ -88,6 +88,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "shutdowndlg.h" #include "shutdowndlg.h"
#include "client.h" #include "client.h"
// #define PROFILE_SHUTDOWN 1
#ifdef PROFILE_SHUTDOWN
#define SHUTDOWN_MARKER(x) printf("[ksmserver] '%s' [%s]\n\r", x, TQTime::currentTime().toString("hh:mm:ss:zzz").ascii()); fflush(stdout);
#else // PROFILE_SHUTDOWN
#define SHUTDOWN_MARKER(x)
#endif // PROFILE_SHUTDOWN
void KSMServer::logout( int confirm, int sdtype, int sdmode ) void KSMServer::logout( int confirm, int sdtype, int sdmode )
{ {
shutdown( (KApplication::ShutdownConfirm)confirm, shutdown( (KApplication::ShutdownConfirm)confirm,
@ -190,7 +198,7 @@ void KSMServer::shutdownInternal( KApplication::ShutdownConfirm confirm,
} }
if ( logoutConfirmed ) { if ( logoutConfirmed ) {
SHUTDOWN_MARKER("Shutdown initiated");
shutdownType = sdtype; shutdownType = sdtype;
shutdownMode = sdmode; shutdownMode = sdmode;
bootOption = bopt; bootOption = bopt;
@ -199,8 +207,9 @@ void KSMServer::shutdownInternal( KApplication::ShutdownConfirm confirm,
// shall we save the session on logout? // shall we save the session on logout?
saveSession = ( config->readEntry( "loginMode", "restorePreviousLogout" ) == "restorePreviousLogout" ); saveSession = ( config->readEntry( "loginMode", "restorePreviousLogout" ) == "restorePreviousLogout" );
if ( saveSession ) if ( saveSession ) {
sessionGroup = TQString("Session: ") + SESSION_PREVIOUS_LOGOUT; sessionGroup = TQString("Session: ") + SESSION_PREVIOUS_LOGOUT;
}
// Set the real desktop background to black so that exit looks // Set the real desktop background to black so that exit looks
// clean regardless of what was on "our" desktop. // clean regardless of what was on "our" desktop.
@ -211,6 +220,7 @@ void KSMServer::shutdownInternal( KApplication::ShutdownConfirm confirm,
wmPhase1WaitingCount = 0; wmPhase1WaitingCount = 0;
saveType = saveSession?SmSaveBoth:SmSaveGlobal; saveType = saveSession?SmSaveBoth:SmSaveGlobal;
performLegacySessionSave(); performLegacySessionSave();
SHUTDOWN_MARKER("Legacy save complete");
startProtection(); startProtection();
for ( KSMClient* c = clients.first(); c; c = clients.next() ) { for ( KSMClient* c = clients.first(); c; c = clients.next() ) {
c->resetState(); c->resetState();
@ -240,8 +250,9 @@ void KSMServer::shutdownInternal( KApplication::ShutdownConfirm confirm,
SmsSaveYourself( c->connection(), saveType, SmsSaveYourself( c->connection(), saveType,
true, SmInteractStyleAny, false ); true, SmInteractStyleAny, false );
} }
if ( clients.isEmpty() ) if ( clients.isEmpty() ) {
completeShutdownOrCheckpoint(); completeShutdownOrCheckpoint();
}
} }
else { else {
if (showLogoutStatusDlg) { if (showLogoutStatusDlg) {
@ -474,12 +485,15 @@ void KSMServer::protectionTimeout()
void KSMServer::completeShutdownOrCheckpoint() void KSMServer::completeShutdownOrCheckpoint()
{ {
if ( state != Shutdown && state != Checkpoint ) SHUTDOWN_MARKER("completeShutdownOrCheckpoint");
if ( state != Shutdown && state != Checkpoint ) {
return; return;
}
for ( KSMClient* c = clients.first(); c; c = clients.next() ) { for ( KSMClient* c = clients.first(); c; c = clients.next() ) {
if ( !c->saveYourselfDone && !c->waitForPhase2 ) if ( !c->saveYourselfDone && !c->waitForPhase2 ) {
return; // not done yet return; // not done yet
}
} }
// do phase 2 // do phase 2
@ -491,8 +505,10 @@ void KSMServer::completeShutdownOrCheckpoint()
waitForPhase2 = true; waitForPhase2 = true;
} }
} }
if ( waitForPhase2 ) if ( waitForPhase2 ) {
return; return;
}
SHUTDOWN_MARKER("Phase 2 complete");
bool showLogoutStatusDlg = KConfigGroup(KGlobal::config(), "Logout").readBoolEntry("showLogoutStatusDlg", true); bool showLogoutStatusDlg = KConfigGroup(KGlobal::config(), "Logout").readBoolEntry("showLogoutStatusDlg", true);
if (showLogoutStatusDlg && state != Checkpoint) { if (showLogoutStatusDlg && state != Checkpoint) {
@ -513,10 +529,14 @@ void KSMServer::completeShutdownOrCheckpoint()
static_cast<KSMShutdownIPDlg*>(shutdownNotifierIPDlg)->setStatusMessage(i18n("Saving your settings...")); static_cast<KSMShutdownIPDlg*>(shutdownNotifierIPDlg)->setStatusMessage(i18n("Saving your settings..."));
} }
if ( saveSession ) if ( saveSession ) {
storeSession(); storeSession();
else SHUTDOWN_MARKER("Session stored");
}
else {
discardSession(); discardSession();
SHUTDOWN_MARKER("Session discarded");
}
if ( state == Shutdown ) { if ( state == Shutdown ) {
bool waitForKNotify = true; bool waitForKNotify = true;
@ -532,8 +552,9 @@ void KSMServer::completeShutdownOrCheckpoint()
} }
// event() can return -1 if KNotifyClient short-circuits and avoids KNotify // event() can return -1 if KNotifyClient short-circuits and avoids KNotify
logoutSoundEvent = KNotifyClient::event( 0, "exitkde" ); // KDE says good bye logoutSoundEvent = KNotifyClient::event( 0, "exitkde" ); // KDE says good bye
if( logoutSoundEvent <= 0 ) if( logoutSoundEvent <= 0 ) {
waitForKNotify = false; waitForKNotify = false;
}
if( waitForKNotify ) { if( waitForKNotify ) {
state = WaitingForKNotify; state = WaitingForKNotify;
knotifyTimeoutTimer.start( 20000, true ); knotifyTimeoutTimer.start( 20000, true );
@ -546,15 +567,17 @@ void KSMServer::completeShutdownOrCheckpoint()
} }
state = Idle; state = Idle;
} }
SHUTDOWN_MARKER("Fully shutdown");
} }
void KSMServer::startKilling() void KSMServer::startKilling()
{ {
SHUTDOWN_MARKER("startKilling");
knotifyTimeoutTimer.stop(); knotifyTimeoutTimer.stop();
// kill all clients // kill all clients
state = Killing; state = Killing;
for ( KSMClient* c = clients.first(); c; c = clients.next() ) { for ( KSMClient* c = clients.first(); c; c = clients.next() ) {
if( isWM( c ) || isCM( c ) ) // kill the WM and CM as the last one in order to reduce flicker if( isWM( c ) || isCM( c ) || isNotifier( c ) ) // kill the WM and CM as the last one in order to reduce flicker. Also wait to kill knotify to avoid logout delays
continue; continue;
kdDebug( 1218 ) << "completeShutdown: client " << c->program() << "(" << c->clientId() << ")" << endl; kdDebug( 1218 ) << "completeShutdown: client " << c->program() << "(" << c->clientId() << ")" << endl;
SmsDie( c->connection() ); SmsDie( c->connection() );
@ -568,12 +591,13 @@ void KSMServer::startKilling()
void KSMServer::completeKilling() void KSMServer::completeKilling()
{ {
SHUTDOWN_MARKER("completeKilling");
kdDebug( 1218 ) << "KSMServer::completeKilling clients.count()=" << kdDebug( 1218 ) << "KSMServer::completeKilling clients.count()=" <<
clients.count() << endl; clients.count() << endl;
if( state == Killing ) { if( state == Killing ) {
bool wait = false; bool wait = false;
for( KSMClient* c = clients.first(); c; c = clients.next()) { for( KSMClient* c = clients.first(); c; c = clients.next()) {
if( isWM( c ) || isCM( c ) ) if( isWM( c ) || isCM( c ) || isNotifier( c ) )
continue; continue;
wait = true; // still waiting for clients to go away wait = true; // still waiting for clients to go away
} }
@ -585,6 +609,7 @@ void KSMServer::completeKilling()
void KSMServer::killWM() void KSMServer::killWM()
{ {
SHUTDOWN_MARKER("killWM");
state = KillingWM; state = KillingWM;
bool iswm = false; bool iswm = false;
if (shutdownNotifierIPDlg) { if (shutdownNotifierIPDlg) {
@ -600,6 +625,9 @@ void KSMServer::killWM()
if( isCM( c )) { if( isCM( c )) {
SmsDie( c->connection() ); SmsDie( c->connection() );
} }
if( isNotifier( c )) {
SmsDie( c->connection() );
}
} }
if( iswm ) { if( iswm ) {
completeKillingWM(); completeKillingWM();
@ -611,6 +639,7 @@ void KSMServer::killWM()
void KSMServer::completeKillingWM() void KSMServer::completeKillingWM()
{ {
SHUTDOWN_MARKER("completeKillingWM");
kdDebug( 1218 ) << "KSMServer::completeKillingWM clients.count()=" << kdDebug( 1218 ) << "KSMServer::completeKillingWM clients.count()=" <<
clients.count() << endl; clients.count() << endl;
if( state == KillingWM ) { if( state == KillingWM ) {
@ -622,18 +651,26 @@ void KSMServer::completeKillingWM()
// shutdown is fully complete // shutdown is fully complete
void KSMServer::killingCompleted() void KSMServer::killingCompleted()
{ {
SHUTDOWN_MARKER("killingCompleted");
kapp->quit(); kapp->quit();
} }
// called when KNotify performs notification for logout (not when sound is finished though) // called when KNotify performs notification for logout (not when sound is finished though)
void KSMServer::notifySlot(TQString event ,TQString app,TQString,TQString,TQString,int present,int,int,int) void KSMServer::notifySlot(TQString event ,TQString app,TQString,TQString,TQString,int present,int,int,int)
{ {
if( state != WaitingForKNotify ) SHUTDOWN_MARKER("notifySlot");
if( state != WaitingForKNotify ) {
SHUTDOWN_MARKER("notifySlot state != WaitingForKNotify");
return; return;
if( event != "exitkde" || app != "ksmserver" ) }
if( event != "exitkde" || app != "ksmserver" ) {
SHUTDOWN_MARKER("notifySlot event != \"exitkde\" || app != \"ksmserver\"");
return; return;
if( present & KNotifyClient::Sound ) // logoutSoundFinished() will be called }
if( present & KNotifyClient::Sound ) { // logoutSoundFinished() will be called
SHUTDOWN_MARKER("notifySlot present & KNotifyClient::Sound");
return; return;
}
startKilling(); startKilling();
} }
@ -641,23 +678,30 @@ void KSMServer::notifySlot(TQString event ,TQString app,TQString,TQString,TQStri
// emitted in KNotify only after the sound is finished playing. // emitted in KNotify only after the sound is finished playing.
void KSMServer::logoutSoundFinished( int event, int ) void KSMServer::logoutSoundFinished( int event, int )
{ {
if( state != WaitingForKNotify ) SHUTDOWN_MARKER("logoutSoundFinished");
if( state != WaitingForKNotify ) {
return; return;
if( event != logoutSoundEvent ) }
if( event != logoutSoundEvent ) {
return; return;
}
startKilling(); startKilling();
} }
void KSMServer::knotifyTimeout() void KSMServer::knotifyTimeout()
{ {
if( state != WaitingForKNotify ) SHUTDOWN_MARKER("knotifyTimeout");
if( state != WaitingForKNotify ) {
return; return;
}
startKilling(); startKilling();
} }
void KSMServer::timeoutQuit() void KSMServer::timeoutQuit()
{ {
SHUTDOWN_MARKER("timeoutQuit");
for (KSMClient *c = clients.first(); c; c = clients.next()) { for (KSMClient *c = clients.first(); c; c = clients.next()) {
SHUTDOWN_MARKER(TQString("SmsDie timeout, client %1 (%2)").arg(c->program()).arg(c->clientId()).ascii());
kdWarning( 1218 ) << "SmsDie timeout, client " << c->program() << "(" << c->clientId() << ")" << endl; kdWarning( 1218 ) << "SmsDie timeout, client " << c->program() << "(" << c->clientId() << ")" << endl;
} }
killWM(); killWM();
@ -665,6 +709,7 @@ void KSMServer::timeoutQuit()
void KSMServer::timeoutWMQuit() void KSMServer::timeoutWMQuit()
{ {
SHUTDOWN_MARKER("timeoutWMQuit");
if( state == KillingWM ) { if( state == KillingWM ) {
kdWarning( 1218 ) << "SmsDie WM timeout" << endl; kdWarning( 1218 ) << "SmsDie WM timeout" << endl;
} }

Loading…
Cancel
Save