147948

From ThorstensHome
Revision as of 14:25, 29 March 2009 by WikiSysop (Talk)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

KDE bug 147948 is about kio_fish stalling. The bug can be reproduced with the following testcase.

Contents

Testcase

files

CMakeLists.txt

PROJECT( browser )
FIND_PACKAGE(KDE4 REQUIRED)
INCLUDE_DIRECTORIES( ${KDE4_INCLUDES} . )


SET(kde4startSources main.cpp browser.cpp )


KDE4_ADD_EXECUTABLE(browser ${kde4startSources} )

TARGET_LINK_LIBRARIES(browser ${KDE4_KDEUI_LIBS} ${KDE4_KPARTS_LIBS} )

install(TARGETS browser  DESTINATION ${BIN_INSTALL_DIR} )

main.cpp

#include <QString>
#include <kapplication.h>
#include <kaboutdata.h>
#include <klocalizedstring.h>
#include <kmessagebox.h>
#include <kcmdlineargs.h>
#include <KMainWindow>
#include <browser.h>

int main (int argc, char *argv[])
{
  const QByteArray& ba=QByteArray("test");
  const KLocalizedString name=ki18n("myName");
  KAboutData aboutData( ba, ba, name, ba, name);
  KCmdLineArgs::init( argc, argv, &aboutData );
  KApplication khello;

  Browser *mw = new Browser();
  mw->show();
  khello.exec();
}

browser.cpp

#include <kio/scheduler.h>       
#include <kurl.h>                
#include <kio/jobclasses.h>      
#include <kdebug.h>              
#include <browser.h>             
#include <kio/copyjob.h>         

class TransferJob;

Browser::Browser() : QWidget(NULL)
{
  slotButtonClicked();
}

void Browser::slotButtonClicked()
{
  kDebug() << "entering function";
  // creating a kioslave
  kDebug() << "getting via fish*************************************************************";
  KUrl::List selectedUrls;

  for (int i=1; i<100; i++)
  {
    QString filename=QString("/tmp/fishtest");
    filename.append(QString::number(i)).append(".txt");
    kDebug() << filename;
    selectedUrls.push_back(KUrl(filename));
  }
  KUrl destUrl("fish://root@localhost/tmp/test");
  KIO::CopyJob* job0 = KIO::copy( selectedUrls, destUrl );
  job0->start();
}

void Browser::dataishere(KIO::Job *,const QByteArray & data )
{
  static int counter=0;
  kDebug() << ++counter << " data is here*************************************************************";
  kDebug() << data;
}

browser.h

#ifndef KDE4START_H__
#define KDE4START_H__

#include <kmainwindow.h>
#include <kio/scheduler.h>
#include <kurl.h>
#include <kio/jobclasses.h>

class Browser : public QWidget
{
  Q_OBJECT
  public:
    Browser();
  public slots:
    void slotButtonClicked();
    void dataishere(KIO::Job *,const QByteArray &);
};
#endif

procedure

for i in $(seq 1 1 100); do touch /tmp/fishtest${i}.txt; done
mkdir /tmp/test
cmake . && make && ./browser &

expected result

all files are copied

actual result

Only some files are copied. fishProtocol loops endlessly over while (isRunning) in run(). This is because select returns 0.

See also

Analysis of kio_fish

The last words on konsole of kio_fish should be:

fish(2273)/kio_fish fishProtocol::writeStdin: 1231 :  ---------
fish(2273)/kio_fish fishProtocol::handleResponse: 824 :  handling:  "### 200"
fish(2273)/kio_fish fishProtocol::handleResponse: 831 :  result:  200 , errorCount:  0
fish(2273)/kio_fish fishProtocol::finished: 1403 :  _______ emitting finished()

The functions are implemented in /kdebase/runtime/kioslave/fish/fish.cpp

Important commands: fishProtocol::sendCommand; writeStdin

The problem is line

       rc = select(childFd+1, &rfds, &wfds, NULL, &timeout);

it returns only 0s in case of error. Can we get to the next fd by adding 1 to the childfd?

Call graph

  • get
    • oPenConnectIOn
      • ConnectionStArt
  • put
  • stat
  • mimetype
  • listDir
  • mkdir
    • oPenConnectIOn
      • ConnectionStArt
  • rename
    • oPenConnectIOn
      • ConnectionStArt
  • symlink
    • oPenConnectIOn
      • ConnectionStArt
  • chmod
    • oPenConnectIOn
      • ConnectionStArt
  • copy
    • oPenConnectIOn
      • ConnectionStArt
  • del
    • oPenConnectIOn
      • ConnectionStArt
  • special
    • oPenConnectIOn
      • ConnectionStArt
    • run
      • received
        • manageConnection
          • handleResponse
          • finished
            • writeStdin

Fix

The following fixes the problem: http://websvn.kde.org/?view=rev&revision=906635. The fix made it into KDE 4.2 and is also in the latest branch of 4.1 and 3.5.

Why does this fix solve the problem? The system writes into the fd:

#STOR blah blah

and then some newlines. As long as the fix is applied, the newlines will be written first. If the fix is not applied, it might happen that the response to #STOR is read. Then, newlines are sent over and the system waits eternally for an answer. But an answer to newlines is never sent.

Instead of this fix, it is also possible to replace the first if by a while.

Ubuntu

Now on 4.2 on Ubuntu 8.10 x32 it works. But not on 4.2 on kubuntu 8.10 x64. How to get kde 4.2 on Ubuntu 8.10:

deb http://ppa.launchpad.net/kubuntu-experimental/ubuntu intrepid main

Use the gpg key according to http://www.kubuntu.org/news/kde-4.2 Analyzing: May the source be with you:

deb-src http://ppa.launchpad.net/kubuntu-experimental/ppa/ubuntu intrepid main