[Kde-pim] Proposal for a solution for bug 77862
Guy Maurel
guy.j at maurel.de
Sun May 9 10:41:09 BST 2010
Hi!
Thanks for the many comments. I made the changes, try to answer your questions:
On Friday 07 May 2010 21:18:02 Thomas McGuire wrote:
> Hi,
> I think you mean bug 77862 instead (kio_imap hangs when connection status
> changes, one of the most popular KMail bugs)
YES, it is a typo
> On Friday 07 May 2010 18:27:53 Guy Maurel wrote:
> > The bug reports that the problem occurs as the network changes.
> > No part of imap within kmail takes care of this.
> >
> > Use the NetworkManager. If your distribution hasn't it, have a look at:
> > git clone git://git.freedesktop.org/git/NetworkManager/NetworkManager.git
> >
> > I propose to connect to the "Solid::Networking::notifier",
> > which sends informations about the network as described at:
> > kdelibs/solid/solid/networking.h:42
> > /**
> > * Describes the state of the networking system
> > */
> > enum Status {
> > Unknown, /**< the networking system is not active or unable to
> > report its status - proceed with caution */
> > Unconnected,/**< the system is not connected to any network */
> > Disconnecting, /**< the system is breaking the connection */
> > Connecting, /**< the system is not connected to any network */
> > Connected /**< the system is currently connected to a network */
> > };
> >
> > Create a new slot within "kmkernel".
> > Make the connect at "void KMKernel::init()".
> >
> > The new slot
> > "void KMKernel::slotNetworkStatusHasChanged( Solid::Networking::Status
> > status)" gets the changes of the network.
> >
> > If "Solid::Networking::Unconnected" occurs, we check all the accounts for
> > "KAccount::Imap".
> >
> > Get the slave address
> > lmSlave = imapAcct->slave();
> > and the pid of the slave
> > pid = lmSlave->slave_pid();
> > prepare the kill-command
> > killCommand = "kill "+ s_pid;
> > and let it works
> > system( killCommand.toAscii());
> >
> > Test and what happens:
> > After having a connection to the imap-server we have the processes:
> > 3996 19:00 pts/1 00:00:06 kmail --nofork
> > 4001 19:00 ? 00:00:00 kdeinit4: kio_imap4 [kdeinit] imap
> > local:/tmp/ksocket-guy-kde
> >
> > as we unplug (to test it) the ethernet (after a maximum of 60 seconds) we
> > get kmail(3996) KMKernel::slotNetworkStatusHasChanged: Networking is now:
> > Unconnected kmail(3996) KMKernel::slotNetworkStatusHasChanged:
> > imapAcct->slave: KIO::Slave(0xbc3960) kmail(3996)
> > KMKernel::slotNetworkStatusHasChanged: slave_pid: 4001 kmail(3996)
> > KMKernel::slotNetworkStatusHasChanged: kill-command "kill 4001"
> >
> > as the process is killed, the slave get an input
> > kmail(3996)/kio (Slave) KIO::Slave::gotInput: slave died pid = 4001
> > kmail(3996)/kio (Scheduler) KIO::SchedulerPrivate::disconnectSlave:
> > _disconnectSlave( KIO::Slave(0xbc3960) ) kmail(3996)/kdeui
> > (KNotification) KNotificationManager::notificationClosed: 234
> >
> > kmail is now able to go on for a new imap-connection after the network is
> > on again.
>
> The general idea of using Solid is good.
> KMail already has some online/offline status handling, and I think Solid
> should be integrated with that.
> See the onlineStatusChanged() signal of KMKernel. The main widget connects to
> that and changes the state of the "Work online/offline" action accordingly.
>
> So I think the stopNetworkJobs()/resumeNetworkJobs() should be called when the
> Solid network status changes.
>
> Right now, stopNetworkJobs() doesn't actually change the network status. I
> think simply calling AccountManager::cancelMailCheck() might already be enough
> for this. Can you check if that works?
I try (again) the proposal:
the_acctMgr->cancelMailCheck();
but it is not enough. We get:
kmail(2169)/kio (Scheduler) KIO::SchedulerPrivate::disconnectSlave: _disconnectSlave( KIO::Slave(0x1577d70) )
The slave is "only" disconnected. The kio_imap process is still leaving.
===========
As the IP-topology is changing, the kio_imap-slave *cannot* be use anymore, because it is only
valid with the old IP-address. We must kill this process, so kmail have to create a new one.
Allready the description from Mike Culbertson 2004-03-17 tell us that:
"... have to manually kill the kio_imap4 processes"
The next confirmations are:
Comment #7 From Petr Burian: "... quick solution to solve this is to kill all kio_imap processes"
Comment #13 From Michael Kreitzer: "... kio_imap processes are killed"
Comment #16 From Apollon Oikonomopoulos: "... I have to kill all kio_imap4 instances manually"
and many more.
I experience a bit and found three possible ways to do this.
The first solution:
===========
The must pretty one, is that the kio_imap-process kills itself. Something like that.
First, the class IMAP4Protocol needs to derived also from QOject.
kdepimlibs/kioslave/imap4/imap4.cpp at
IMAP4Protocol::IMAP4Protocol (const QByteArray & pool,...
bool b;
kDebug(7116) <<"IMAP4: connect it";
b= connect( Solid::Networking::notifier(), SIGNAL( statusChanged( Solid::Networking::Status ) ),
this, SLOT( slotNetworkStatusHasChanged( Solid::Networking::Status ) ) );
kDebug(7116) <<"IMAP4: connect it is=" << b;
and the slot should call the "IMAP4Protocol::closeConnection()"
*BUT* it doesn't work. The slot doesn't get the signal. I don't anderstand why not!
The second solution:
=============
It could be to send the command CMD_DISCONNECT, defined by kdelibs/kio/kio/global.h.
The command is received at kdelibs/kio/kio/slavebase.cpp:940
void SlaveBase::dispatch( int command, const QByteArray &data )
and makes the right call at line 963
case CMD_DISCONNECT: {
closeConnection( );
*BUT* this command is not used (not implemented) by the imap part of kmail.
The third solution:
===========
This is the one I propose today. This could be used immediately.
> So I'd like the patch to be changed to take the above into account.
> Some other comments on the patch:
> - Declare variables as late as possible. In the patch, they are declared at
> the beginning of the function. It is generally better to only declare them
> when actually using them. This helps readability and reduces the chance of
> using uninitialized variables
> - Disconnected IMAP is not covered, only online IMAP
yes. I like to make only little step at one time...
> - The cases inside the switch miss break statements
no, I have put them at the end of the line. Now, they are in a new line...
> - calling system() with a kill command for the slave is not a good idea, that
> is much to brutal. Also, it is not portable, for example it won't work on
> Mac or Windows. I'd really prefer to use AccountManager::cancelMailCheck
> instead, if that works.
Yes, you are right with your comments: "brutal" and "not portable to Mac or Windows".
*BUT* it works today on Linux. I have no experience on other OS. May be we found somebody
who is able to make it for us.
The "system"-command is allready used by
kmfoldermbox.cpp (12 times)
libkleo/tests/test_cryptoconfig.cpp ( 3 times)
Another approche, with kprocess.h, is used by
libkleo/backends/qgpgme/qgpgmecryptoconfig.cpp
What is the better way?
> I'm a bit uneasy about committing such a big patch to the 4.4 branch. However,
> if it fixes the bug and is tested by multiple persons before committing, it
YES, I am hopping that may people are testing me...
> can go in, as many users are waiting for the fix for this particular bug.
It is why I am working on it!
> Luckily, this bug does not affect KMail trunk, since we don't use KIO slaves
> there for IMAP :)
I am not sure! Not using the KIO slaves is only one part of the solution. The new solution
should also take care of the sifgnal emmited for Solid::Networking...
Thanks for reading, thanks for testing and comments
--
guy
-------------- next part --------------
A non-text attachment was scrubbed...
Name: kmkernel-b.diff
Type: text/x-patch
Size: 3593 bytes
Desc: not available
URL: <http://mail.kde.org/pipermail/kde-pim/attachments/20100509/ac849c79/attachment.bin>
-------------- next part --------------
_______________________________________________
KDE PIM mailing list kde-pim at kde.org
https://mail.kde.org/mailman/listinfo/kde-pim
KDE PIM home page at http://pim.kde.org/
More information about the kde-pim
mailing list