[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