From 8dafd3ca3855921cb36a7020a567b1ee534cec5d Mon Sep 17 00:00:00 2001 From: Sebastian Goth Date: Wed, 22 Jul 2009 11:52:50 +0200 Subject: [PATCH] Detect and kill unused CoreSessions --- src/core/core.cpp | 3 +++ src/core/core.h | 5 +++++ src/core/coresession.cpp | 24 ++++++++++++++++++++++-- src/core/coresession.h | 18 +++++++++++++++++- 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index b2e3ee4..f7b6ca1 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -985,6 +985,9 @@ QVariantMap Core::promptForSettings(const Storage *storage) { return settings; } +void Core::deleteCoreSession(UserId id) { + sessions.take(id)->deleteLater(); +} #ifdef Q_OS_WIN32 void Core::stdInEcho(bool on) { diff --git a/src/core/core.h b/src/core/core.h index c1f397a..16c47b9 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -391,6 +391,11 @@ public slots: void syncStorage(); void setupInternalClientSession(SignalProxy *proxy); + //! Delete an unused CoreSession and its corresponding thread + /** \param id The UserId of the Session + */ + void deleteCoreSession(UserId id); + signals: //! Sent when a BufferInfo is updated in storage. void bufferInfoUpdated(UserId user, const BufferInfo &info); diff --git a/src/core/coresession.cpp b/src/core/coresession.cpp index 9f21056..fdc9669 100644 --- a/src/core/coresession.cpp +++ b/src/core/coresession.cpp @@ -89,9 +89,15 @@ CoreSession::CoreSession(UserId uid, bool restoreState, QObject *parent) p->synchronize(ircListHelper()); p->synchronize(&_coreInfo); + // let core remove the session from its structures and delete it afterwards + connect(this, SIGNAL(deleteCoreSession(UserId)), Core::instance(), SLOT(deleteCoreSession(UserId)), Qt::QueuedConnection); + connect(this, SIGNAL(deleteCoreSessionLater(UserId)), this, SIGNAL(deleteCoreSession(UserId)), Qt::QueuedConnection); // Restore session state if(restoreState) - restoreSessionState(); + if(!restoreSessionState()) + // if we have nothing to restore, this CoreSession is useless + // until the user decides to connect + emit deleteCoreSessionLater(_user); emit initialized(); } @@ -150,14 +156,21 @@ void CoreSession::saveSessionState() const { _bufferViewManager->saveBufferViews(); } -void CoreSession::restoreSessionState() { +bool CoreSession::restoreSessionState() { QList nets = Core::connectedNetworks(user()); + + if(nets.empty()) + return false; + CoreNetwork *net = 0; + bool restored = false; foreach(NetworkId id, nets) { net = network(id); Q_ASSERT(net); net->connectToIrc(); + restored = true; } + return restored; } void CoreSession::addClient(QIODevice *device) { @@ -462,10 +475,14 @@ void CoreSession::clientsDisconnected() { CoreNetwork *net = 0; IrcUser *me = 0; QString awayReason; + bool activeNetworks = false; + while(netIter != _networks.end()) { net = *netIter; netIter++; + if(net->connectionState() != Network::Disconnected) + activeNetworks = true; if(!net->isConnected()) continue; identity = net->identityPtr(); @@ -482,4 +499,7 @@ void CoreSession::clientsDisconnected() { net->userInputHandler()->handleAway(BufferInfo(), awayReason); } } + // if no networks are active and the last client disconnected, we assume the session is useless + if(!activeNetworks) + emit deleteCoreSessionLater(_user); } diff --git a/src/core/coresession.h b/src/core/coresession.h index 48d83f8..7c7b9ac 100644 --- a/src/core/coresession.h +++ b/src/core/coresession.h @@ -68,7 +68,10 @@ public: //! Return necessary data for restoring the session after restarting the core void saveSessionState() const; - void restoreSessionState(); + //! Restore session after restarting the core + /** Returns true if anything is restored, false if not. + */ + bool restoreSessionState(); public slots: void addClient(QIODevice *device); @@ -131,6 +134,19 @@ signals: void networkCreated(NetworkId); void networkRemoved(NetworkId); + //! CoreSession assumed useless + /** This signal is propagated to the core to request the destruction of the senders session. + * \param id The UserId of this session + */ + void deleteCoreSession(UserId id); + + //! CoreSession assumed useles + /** This signal is only a helper to deleteCoreSession and emits that whenever the eventloop is + * running. + * \param id The UserId of this session + */ + void deleteCoreSessionLater(UserId id); + private slots: void removeClient(QIODevice *dev); -- 1.6.3.3