Difference between revisions of "147948"
(→Fix) |
(→Fix) |
||
Line 179: | Line 179: | ||
#STOR blah blah | #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. | 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 = | = Ubuntu = |
Latest revision as of 14:25, 29 March 2009
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
- oPenConnectIOn
- put
- stat
- mimetype
- listDir
- mkdir
- oPenConnectIOn
- ConnectionStArt
- oPenConnectIOn
- rename
- oPenConnectIOn
- ConnectionStArt
- oPenConnectIOn
- symlink
- oPenConnectIOn
- ConnectionStArt
- oPenConnectIOn
- chmod
- oPenConnectIOn
- ConnectionStArt
- oPenConnectIOn
- copy
- oPenConnectIOn
- ConnectionStArt
- oPenConnectIOn
- del
- oPenConnectIOn
- ConnectionStArt
- oPenConnectIOn
- special
- oPenConnectIOn
- ConnectionStArt
- run
- received
- manageConnection
- handleResponse
- finished
- writeStdin
- manageConnection
- received
- oPenConnectIOn
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