From 904089839b164dff3eb3230e6345b0a6d456dabf Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 10 Jun 2010 10:15:09 +0200 Subject: Updated WebKit from /home/shausman/src/webkit/trunk to qtwebkit/qtwebkit-4.6 ( d8a9d09376a47b92ea49f1a078c392cbfdbc0ed6 ) Changes in WebKit/qt since the last update: * https://bugs.webkit.org/show_bug.cgi?id=39958 -- [Qt] TextBreakIterator Qt performance --- src/3rdparty/webkit/VERSION | 2 +- src/3rdparty/webkit/WebCore/ChangeLog | 31 +++++++++++ .../platform/text/qt/TextBreakIteratorQt.cpp | 64 ++++++++++++---------- 3 files changed, 68 insertions(+), 29 deletions(-) diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 51d663b..b92486d 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -8,4 +8,4 @@ The commit imported was from the and has the sha1 checksum - d6d6c3821ed111b214a753f1ce8fa969c1a94dc3 + d8a9d09376a47b92ea49f1a078c392cbfdbc0ed6 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index c3df1bf..bf8b745 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,34 @@ +2010-06-08 Kenneth Rohde Christiansen + + Unreviewed Buildbot fix. + + Reset the Qt TextBreakIterator when reusing it. + + * platform/text/qt/TextBreakIteratorQt.cpp: + (WebCore::setUpIterator): + +2010-06-08 Kenneth Rohde Christiansen + + Reviewed by Antti Koivisto. + + [Qt] TextBreakIterator Qt performance + https://bugs.webkit.org/show_bug.cgi?id=39958 + + Rework TextBreakIteratorQt to be more in line with the ICU version. + + We now reuse iterators where ever possible. The string data is compared + with memcmp, which should be faster than using a hash, as you need + to traverse the full buffer in the case the strings don't match, + where as the compare would fail quickly. + + * platform/text/qt/TextBreakIteratorQt.cpp: + (WebCore::TextBreakIterator::TextBreakIterator): + (WebCore::setUpIterator): + (WebCore::wordBreakIterator): + (WebCore::characterBreakIterator): + (WebCore::lineBreakIterator): + (WebCore::sentenceBreakIterator): + 2010-04-19 Balazs Kelemen Reviewed by Kenneth Rohde Christiansen. diff --git a/src/3rdparty/webkit/WebCore/platform/text/qt/TextBreakIteratorQt.cpp b/src/3rdparty/webkit/WebCore/platform/text/qt/TextBreakIteratorQt.cpp index d80e270..0302db8 100644 --- a/src/3rdparty/webkit/WebCore/platform/text/qt/TextBreakIteratorQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/text/qt/TextBreakIteratorQt.cpp @@ -36,31 +36,49 @@ namespace WebCore { + static unsigned char buffer[1024]; + class TextBreakIterator : public QTextBoundaryFinder { + public: + TextBreakIterator(QTextBoundaryFinder::BoundaryType type, const UChar* string, int length) + : QTextBoundaryFinder(type, (const QChar*)string, length, buffer, sizeof(buffer)) + , length(length) + , string(string) {} + TextBreakIterator() + : QTextBoundaryFinder() + , length(0) + , string(0) {} + + int length; + const UChar* string; }; - static QTextBoundaryFinder* iterator = 0; - static unsigned char buffer[1024]; - TextBreakIterator* wordBreakIterator(const UChar* string, int length) + TextBreakIterator* setUpIterator(TextBreakIterator& iterator, QTextBoundaryFinder::BoundaryType type, const UChar* string, int length) { if (!string) return 0; - if (!iterator) - iterator = new QTextBoundaryFinder; - *iterator = QTextBoundaryFinder(QTextBoundaryFinder::Word, (const QChar *)string, length, buffer, sizeof(buffer)); - return static_cast(iterator); + if (iterator.isValid() && type == iterator.type() && length == iterator.length + && memcmp(string, iterator.string, length) == 0) { + iterator.toStart(); + return &iterator; + } + + iterator = TextBreakIterator(type, string, length); + + return &iterator; } - TextBreakIterator* characterBreakIterator(const UChar* string, int length) + TextBreakIterator* wordBreakIterator(const UChar* string, int length) { - if (!string) - return 0; - if (!iterator) - iterator = new QTextBoundaryFinder; + static TextBreakIterator staticWordBreakIterator; + return setUpIterator(staticWordBreakIterator, QTextBoundaryFinder::Word, string, length); + } - *iterator = QTextBoundaryFinder(QTextBoundaryFinder::Grapheme, (const QChar *)string, length, buffer, sizeof(buffer)); - return static_cast(iterator); + TextBreakIterator* characterBreakIterator(const UChar* string, int length) + { + static TextBreakIterator staticCharacterBreakIterator; + return setUpIterator(staticCharacterBreakIterator, QTextBoundaryFinder::Grapheme, string, length); } TextBreakIterator* cursorMovementIterator(const UChar* string, int length) @@ -70,25 +88,15 @@ namespace WebCore { TextBreakIterator* lineBreakIterator(const UChar* string, int length) { - static QTextBoundaryFinder *iterator = 0; - if (!string) - return 0; - if (!iterator) - iterator = new QTextBoundaryFinder; - - *iterator = QTextBoundaryFinder(QTextBoundaryFinder::Line, (const QChar *)string, length, buffer, sizeof(buffer)); - return static_cast(iterator); + static TextBreakIterator staticLineBreakIterator; + return setUpIterator(staticLineBreakIterator, QTextBoundaryFinder::Line, string, length); } TextBreakIterator* sentenceBreakIterator(const UChar* string, int length) { - if (!string) - return 0; - if (!iterator) - iterator = new QTextBoundaryFinder; + static TextBreakIterator staticSentenceBreakIterator; + return setUpIterator(staticSentenceBreakIterator, QTextBoundaryFinder::Sentence, string, length); - *iterator = QTextBoundaryFinder(QTextBoundaryFinder::Sentence, (const QChar *)string, length, buffer, sizeof(buffer)); - return static_cast(iterator); } int textBreakFirst(TextBreakIterator* bi) -- cgit v0.12 From 90518a59df46312d56e4c6bc7080415b44b928f4 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 10 Jun 2010 12:36:15 +0200 Subject: tst_qlocalsocket: pro files of client / server examples fixed Reviewed-by: ossi --- tests/auto/qlocalsocket/example/client/client.pro | 6 ------ tests/auto/qlocalsocket/example/server/server.pro | 6 ------ 2 files changed, 12 deletions(-) diff --git a/tests/auto/qlocalsocket/example/client/client.pro b/tests/auto/qlocalsocket/example/client/client.pro index eb7e6e6..84f20d6 100644 --- a/tests/auto/qlocalsocket/example/client/client.pro +++ b/tests/auto/qlocalsocket/example/client/client.pro @@ -1,14 +1,8 @@ -###################################################################### -# Automatically generated by qmake (2.01a) Wed Jun 6 17:07:12 2007 -###################################################################### - TEMPLATE = app TARGET = DEPENDPATH += . INCLUDEPATH += . CONFIG += console -include(../../src/src.pri) -# Input QT = core network SOURCES += main.cpp diff --git a/tests/auto/qlocalsocket/example/server/server.pro b/tests/auto/qlocalsocket/example/server/server.pro index 438462d..bfd14d2 100644 --- a/tests/auto/qlocalsocket/example/server/server.pro +++ b/tests/auto/qlocalsocket/example/server/server.pro @@ -1,7 +1,3 @@ -###################################################################### -# Automatically generated by qmake (2.01a) Wed Jun 6 15:16:48 2007 -###################################################################### - TEMPLATE = app TARGET = DEPENDPATH += . @@ -11,8 +7,6 @@ CONFIG += console QT = core network -include(../../src/src.pri) - # Input SOURCES += main.cpp -- cgit v0.12 From 6c8b980a8ea8009a7b80fcce419e331df778a989 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 10 Jun 2010 12:37:47 +0200 Subject: tst_QLocalSocket::threadedConnection autotest stabilized Fixed race condition on connection. Done-with: ossi Reviewed-by: ossi --- tests/auto/qlocalsocket/tst_qlocalsocket.cpp | 38 +++++++++------------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp index 44f3c12..dbb58c1 100644 --- a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp @@ -683,25 +683,11 @@ public: QString testLine = "test"; LocalSocket socket; QSignalSpy spyReadyRead(&socket, SIGNAL(readyRead())); - int tries = 0; - do { - socket.connectToServer("qlocalsocket_threadtest"); - if (socket.error() != QLocalSocket::ServerNotFoundError - && socket.error() != QLocalSocket::ConnectionRefusedError) - break; - QTest::qWait(100); - ++tries; - } while ((socket.error() == QLocalSocket::ServerNotFoundError - || socket.error() == QLocalSocket::ConnectionRefusedError) - && tries < 1000); - if (tries == 0 && socket.state() != QLocalSocket::ConnectedState) { - QVERIFY(socket.waitForConnected(7000)); - QVERIFY(socket.state() == QLocalSocket::ConnectedState); - } + socket.connectToServer("qlocalsocket_threadtest"); + QVERIFY(socket.waitForConnected(1000)); // We should *not* have this signal yet! - if (tries == 0) - QCOMPARE(spyReadyRead.count(), 0); + QCOMPARE(spyReadyRead.count(), 0); socket.waitForReadyRead(); QCOMPARE(spyReadyRead.count(), 1); QTextStream in(&socket); @@ -715,6 +701,8 @@ class Server : public QThread public: int clients; + QMutex mutex; + QWaitCondition wc; void run() { QString testLine = "test"; @@ -722,6 +710,9 @@ public: server.setMaxPendingConnections(10); QVERIFY2(server.listen("qlocalsocket_threadtest"), server.errorString().toLatin1().constData()); + mutex.lock(); + wc.wakeAll(); + mutex.unlock(); int done = clients; while (done > 0) { bool timedOut = true; @@ -746,14 +737,9 @@ void tst_QLocalSocket::threadedConnection_data() QTest::addColumn("threads"); QTest::newRow("1 client") << 1; QTest::newRow("2 clients") << 2; -#ifdef Q_OS_WINCE - QTest::newRow("4 clients") << 4; -#endif -#ifndef Q_OS_WIN QTest::newRow("5 clients") << 5; - QTest::newRow("10 clients") << 10; -#endif #ifndef Q_OS_WINCE + QTest::newRow("10 clients") << 10; QTest::newRow("20 clients") << 20; #endif } @@ -770,7 +756,9 @@ void tst_QLocalSocket::threadedConnection() server.setStackSize(0x14000); #endif server.clients = threads; + server.mutex.lock(); server.start(); + server.wc.wait(&server.mutex); QList clients; for (int i = 0; i < threads; ++i) { @@ -784,9 +772,7 @@ void tst_QLocalSocket::threadedConnection() server.wait(); while (!clients.isEmpty()) { QVERIFY(clients.first()->wait(3000)); - Client *client =clients.takeFirst(); - client->terminate(); - delete client; + delete clients.takeFirst(); } } -- cgit v0.12 From cbe3425a3bd226c61c94f92c521dc5c9b090ef96 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 10 Jun 2010 12:42:13 +0200 Subject: QLocalServer: make many simultaneous connection attempts work on Windows Don't call GetOverlappedResult if ConnectNamedPipe connects instantly. Autotest: tst_qlocalsocket::threadedConnection Task-number: QTBUG-8477 Done-with: ossi Reviewed-by: ossi --- src/network/socket/qlocalserver_p.h | 1 + src/network/socket/qlocalserver_win.cpp | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/network/socket/qlocalserver_p.h b/src/network/socket/qlocalserver_p.h index feaaae0..4f92b64 100644 --- a/src/network/socket/qlocalserver_p.h +++ b/src/network/socket/qlocalserver_p.h @@ -99,6 +99,7 @@ public: struct Listener { HANDLE handle; OVERLAPPED overlapped; + bool connected; }; void setError(const QString &function); diff --git a/src/network/socket/qlocalserver_win.cpp b/src/network/socket/qlocalserver_win.cpp index 50d6ca4..940455c 100644 --- a/src/network/socket/qlocalserver_win.cpp +++ b/src/network/socket/qlocalserver_win.cpp @@ -85,8 +85,10 @@ bool QLocalServerPrivate::addListener() if (!ConnectNamedPipe(listener.handle, &listener.overlapped)) { switch (GetLastError()) { case ERROR_IO_PENDING: + listener.connected = false; break; case ERROR_PIPE_CONNECTED: + listener.connected = true; SetEvent(eventHandle); break; default: @@ -155,7 +157,9 @@ void QLocalServerPrivate::_q_onNewConnection() // a client connection first, so there is no way around polling all of them. for (int i = 0; i < listeners.size(); ) { HANDLE handle = listeners[i].handle; - if (GetOverlappedResult(handle, &listeners[i].overlapped, &dummy, FALSE)) { + if (listeners[i].connected + || GetOverlappedResult(handle, &listeners[i].overlapped, &dummy, FALSE)) + { listeners.removeAt(i); addListener(); -- cgit v0.12 From 12614b2c5aaaed44ef9b3d1b3f6dbf50fd2d405f Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 10 Jun 2010 13:10:27 +0200 Subject: QLocalSocket: fix reading from a socket after broken connection Reading from a socket with a broken connection didn't work, even if there were still bytes to read in the internal read buffer. Autotest: tst_QLocalSocket::writeToClientAndDisconnect Task-number: QTBUG-10921 Reviewed-by: ossi --- src/network/socket/qlocalsocket_win.cpp | 10 ++++++---- tests/auto/qlocalsocket/tst_qlocalsocket.cpp | 16 +++++++++++++--- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index 5f46ecb..dc87ade 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -192,6 +192,9 @@ qint64 QLocalSocket::readData(char *data, qint64 maxSize) { Q_D(QLocalSocket); + if (d->pipeClosed && d->actualReadBufferSize == 0) + return -1; // signal EOF + qint64 readSoFar; // If startAsyncRead() read data, copy it to its destination. if (maxSize == 1 && d->actualReadBufferSize > 0) { @@ -213,10 +216,8 @@ qint64 QLocalSocket::readData(char *data, qint64 maxSize) } if (d->pipeClosed) { - if (readSoFar == 0) { + if (d->actualReadBufferSize == 0) QTimer::singleShot(0, this, SLOT(_q_pipeClosed())); - return -1; // signal EOF - } } else { if (!d->readSequenceStarted) d->startAsyncRead(); @@ -345,7 +346,8 @@ DWORD QLocalSocketPrivate::bytesAvailable() if (!pipeClosed) { pipeClosed = true; emit q->readChannelFinished(); - QTimer::singleShot(0, q, SLOT(_q_pipeClosed())); + if (actualReadBufferSize == 0) + QTimer::singleShot(0, q, SLOT(_q_pipeClosed())); } } return 0; diff --git a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp index dbb58c1..87a30c2 100644 --- a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp @@ -980,6 +980,7 @@ void tst_QLocalSocket::writeToClientAndDisconnect() QLocalServer server; QLocalSocket client; + QSignalSpy readChannelFinishedSpy(&client, SIGNAL(readChannelFinished())); QVERIFY(server.listen("writeAndDisconnectServer")); client.connectToServer("writeAndDisconnectServer"); @@ -992,10 +993,19 @@ void tst_QLocalSocket::writeToClientAndDisconnect() memset(buffer, 0, sizeof(buffer)); QCOMPARE(clientSocket->write(buffer, sizeof(buffer)), (qint64)sizeof(buffer)); clientSocket->waitForBytesWritten(); - clientSocket->disconnectFromServer(); - QVERIFY(client.waitForReadyRead()); + clientSocket->close(); + server.close(); + + // Wait for the client to notice the broken connection. + int timeout = 5000; + do { + const int timestep = 100; + QTest::qWait(timestep); + timeout -= timestep; + } while (!readChannelFinishedSpy.count() && timeout > 0); + + QVERIFY(!readChannelFinishedSpy.isEmpty()); QCOMPARE(client.read(buffer, sizeof(buffer)), (qint64)sizeof(buffer)); - QVERIFY(client.waitForDisconnected()); QCOMPARE(client.state(), QLocalSocket::UnconnectedState); } -- cgit v0.12 From 98da12415aa8bb7497120cd841e7a798e3e5206e Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 10 Jun 2010 14:14:18 +0200 Subject: QLocalSocket/Win: QLocalSocketPrivate::bytesAvailable renamed QLocalSocketPrivate::bytesAvailable has been renamed to QLocalSocketPrivate::checkPipeState to match the purpose of this method. Reviewed-by: ossi --- src/network/socket/qlocalsocket_p.h | 2 +- src/network/socket/qlocalsocket_win.cpp | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/network/socket/qlocalsocket_p.h b/src/network/socket/qlocalsocket_p.h index 0f1c23c..57ca3c2 100644 --- a/src/network/socket/qlocalsocket_p.h +++ b/src/network/socket/qlocalsocket_p.h @@ -135,7 +135,7 @@ public: void _q_canWrite(); void _q_pipeClosed(); void _q_emitReadyRead(); - DWORD bytesAvailable(); + DWORD checkPipeState(); void startAsyncRead(); bool completeAsyncRead(); void checkReadyRead(); diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index dc87ade..aa597da 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -251,7 +251,7 @@ void QLocalSocketPrivate::checkReadyRead() void QLocalSocketPrivate::startAsyncRead() { do { - DWORD bytesToRead = bytesAvailable(); + DWORD bytesToRead = checkPipeState(); if (bytesToRead == 0) { // There are no bytes in the pipe but we need to // start the overlapped read with some buffer size. @@ -334,9 +334,11 @@ void QLocalSocket::abort() } /*! - The number of bytes available from the pipe - */ -DWORD QLocalSocketPrivate::bytesAvailable() + \internal + Returns the number of available bytes in the pipe. + Sets QLocalSocketPrivate::pipeClosed to true if the connection is broken. + */ +DWORD QLocalSocketPrivate::checkPipeState() { Q_Q(QLocalSocket); DWORD bytes; @@ -531,7 +533,7 @@ bool QLocalSocket::waitForDisconnected(int msecs) } QIncrementalSleepTimer timer(msecs); forever { - d->bytesAvailable(); // to check if PeekNamedPipe fails + d->checkPipeState(); if (d->pipeClosed) close(); if (state() == UnconnectedState) -- cgit v0.12 From 073d04f1c2c5dc7020469bfc92708dce634f4779 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 10 Jun 2010 14:16:24 +0200 Subject: QLocalSocket: don't emit readChannelFinished() twice on Windows Reviewed-by: ossi --- src/network/socket/qlocalsocket_win.cpp | 3 +++ tests/auto/qlocalsocket/tst_qlocalsocket.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index aa597da..2223ebe 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -252,6 +252,9 @@ void QLocalSocketPrivate::startAsyncRead() { do { DWORD bytesToRead = checkPipeState(); + if (pipeClosed) + return; + if (bytesToRead == 0) { // There are no bytes in the pipe but we need to // start the overlapped read with some buffer size. diff --git a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp index 87a30c2..d2cba6e 100644 --- a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp @@ -1004,7 +1004,7 @@ void tst_QLocalSocket::writeToClientAndDisconnect() timeout -= timestep; } while (!readChannelFinishedSpy.count() && timeout > 0); - QVERIFY(!readChannelFinishedSpy.isEmpty()); + QCOMPARE(readChannelFinishedSpy.count(), 1); QCOMPARE(client.read(buffer, sizeof(buffer)), (qint64)sizeof(buffer)); QCOMPARE(client.state(), QLocalSocket::UnconnectedState); } -- cgit v0.12