From 9fc7e0ee3ff00c04f9301cbb45de09851cb55fa4 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 24 Jun 2011 15:08:28 +0100 Subject: QSocketNotifier autotest - fix compile with MSVC Reviewed-By: Sergio Ahumada --- tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp b/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp index eb9a260..46bdb81 100644 --- a/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp +++ b/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp @@ -55,9 +55,9 @@ #endif #ifdef Q_OS_UNIX #include +#include #endif #include -#include class tst_QSocketNotifier : public QObject { -- cgit v0.12 From 2ff9617cd6093a758dddea5ce50d1efd6e98ded8 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 24 Jun 2011 17:26:20 +0200 Subject: Fix event delevery order Some functions (such as QObject::moveToThread) did not keep the event ordered by priority. And because qUpperBound is used to add events, that mean new events would not be inserted in order. Task-number: QTBUG19637 Change-Id: I38eb9addb1cdd45b8566e000361ac6e5f1f2c2b8 Reviewed-on: http://codereview.qt.nokia.com/733 Reviewed-by: Qt Sanity Bot Reviewed-by: Bradley T. Hughes Reviewed-by: Olivier Goffart (cherry picked from commit 7eeabcf70db658bca847498f618a94a375c95f5f) --- src/corelib/kernel/qcoreapplication.cpp | 17 +------- src/corelib/kernel/qobject.cpp | 2 +- src/corelib/thread/qthread_p.h | 21 +++++++++ src/gui/kernel/qapplication.cpp | 4 +- tests/auto/qeventloop/tst_qeventloop.cpp | 75 ++++++++++++++++++++++++++++++++ 5 files changed, 101 insertions(+), 18 deletions(-) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index dd46bc5..18a5eae 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -1288,20 +1288,7 @@ void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority) // delete the event on exceptions to protect against memory leaks till the event is // properly owned in the postEventList QScopedPointer eventDeleter(event); - if (data->postEventList.isEmpty() || data->postEventList.last().priority >= priority) { - // optimization: we can simply append if the last event in - // the queue has higher or equal priority - data->postEventList.append(QPostEvent(receiver, event, priority)); - } else { - // insert event in descending priority order, using upper - // bound for a given priority (to ensure proper ordering - // of events with the same priority) - QPostEventList::iterator begin = data->postEventList.begin() - + data->postEventList.insertionOffset, - end = data->postEventList.end(); - QPostEventList::iterator at = qUpperBound(begin, end, priority); - data->postEventList.insert(at, QPostEvent(receiver, event, priority)); - } + data->postEventList.addEvent(QPostEvent(receiver, event, priority)); eventDeleter.take(); event->posted = true; ++receiver->d_func()->postedEvents; @@ -1461,7 +1448,7 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type // cannot send deferred delete if (!event_type && !receiver) { // don't lose the event - data->postEventList.append(pe); + data->postEventList.addEvent(pe); const_cast(pe).event = 0; } continue; diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index b88643d..88618c3 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -1482,7 +1482,7 @@ void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData continue; if (pe.receiver == q) { // move this post event to the targetList - targetData->postEventList.append(pe); + targetData->postEventList.addEvent(pe); const_cast(pe).event = 0; ++eventsMoved; } diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index 13df3e6..461d93d 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -93,6 +93,8 @@ inline bool operator<(const QPostEvent &pe, int priority) return priority < pe.priority; } +// This class holds the list of posted events. +// The list has to be kept sorted by priority class QPostEventList : public QList { public: @@ -109,6 +111,25 @@ public: inline QPostEventList() : QList(), recursion(0), startOffset(0), insertionOffset(0) { } + + void addEvent(const QPostEvent &ev) { + int priority = ev.priority; + if (isEmpty() || last().priority >= priority) { + // optimization: we can simply append if the last event in + // the queue has higher or equal priority + append(ev); + } else { + // insert event in descending priority order, using upper + // bound for a given priority (to ensure proper ordering + // of events with the same priority) + QPostEventList::iterator at = qUpperBound(begin() + insertionOffset, end(), priority); + insert(at, ev); + } + } +private: + //hides because they do not keep that list sorted. addEvent must be used + using QList::append; + using QList::insert; }; #ifndef QT_NO_THREAD diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 3803599..361ec6d 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -1288,8 +1288,8 @@ bool QApplication::compressEvent(QEvent *event, QObject *receiver, QPostEventLis || event->type() == QEvent::LanguageChange || event->type() == QEvent::UpdateSoftKeys || event->type() == QEvent::InputMethod)) { - for (int i = 0; i < postedEvents->size(); ++i) { - const QPostEvent &cur = postedEvents->at(i); + for (QPostEventList::const_iterator it = postedEvents->constBegin(); it != postedEvents->constEnd(); ++it) { + const QPostEvent &cur = *it; if (cur.receiver != receiver || cur.event == 0 || cur.event->type() != event->type()) continue; if (cur.event->type() == QEvent::LayoutRequest diff --git a/tests/auto/qeventloop/tst_qeventloop.cpp b/tests/auto/qeventloop/tst_qeventloop.cpp index 7a8c441..bcc205e 100644 --- a/tests/auto/qeventloop/tst_qeventloop.cpp +++ b/tests/auto/qeventloop/tst_qeventloop.cpp @@ -59,6 +59,8 @@ #include #endif +#include "../../shared/util.h" + //TESTED_CLASS= //TESTED_FILES= @@ -208,6 +210,7 @@ private slots: void quit(); void processEventsExcludeSocket(); void processEventsExcludeTimers(); + void deliverInDefinedOrder_QTBUG19637(); // keep this test last: void nestedLoops(); @@ -842,5 +845,77 @@ void tst_QEventLoop::symbianNestedActiveSchedulerLoop() #endif } +Q_DECLARE_METATYPE(QThread*) + +namespace DeliverInDefinedOrder_QTBUG19637 { + enum { NbThread = 3, NbObject = 500, NbEventQueue = 5, NbEvent = 50 }; + + struct CustomEvent : public QEvent { + CustomEvent(int q, int v) : QEvent(Type(User + q)), value(v) {} + int value; + }; + + struct Object : public QObject { + Q_OBJECT + public: + Object() : count(0) { + for (int i = 0; i < NbEventQueue; i++) + lastReceived[i] = -1; + } + int lastReceived[NbEventQueue]; + int count; + virtual void customEvent(QEvent* e) { + QVERIFY(e->type() >= QEvent::User); + QVERIFY(e->type() < QEvent::User + 5); + uint idx = e->type() - QEvent::User; + int value = static_cast(e)->value; + QVERIFY(lastReceived[idx] < value); + lastReceived[idx] = value; + count++; + } + + public slots: + void moveToThread(QThread *t) { + QObject::moveToThread(t); + } + }; + +} + +void tst_QEventLoop::deliverInDefinedOrder_QTBUG19637() +{ + using namespace DeliverInDefinedOrder_QTBUG19637; + qMetaTypeId(); + QThread threads[NbThread]; + Object objects[NbObject]; + for (int t = 0; t < NbThread; t++) { + threads[t].start(); + } + + int event = 0; + + for (int o = 0; o < NbObject; o++) { + objects[o].moveToThread(&threads[o % NbThread]); + for (int e = 0; e < NbEvent; e++) { + int q = e % NbEventQueue; + QCoreApplication::postEvent(&objects[o], new CustomEvent(q, ++event) , q); + if (e % 7) + QMetaObject::invokeMethod(&objects[o], "moveToThread", Qt::QueuedConnection, Q_ARG(QThread*, &threads[(e+o)%NbThread])); + } + } + + QTest::qWait(30); + for (int o = 0; o < NbObject; o++) { + QTRY_COMPARE(objects[o].count, int(NbEvent)); + } + + for (int t = 0; t < NbThread; t++) { + threads[t].quit(); + threads[t].wait(); + } + +} + + QTEST_MAIN(tst_QEventLoop) #include "tst_qeventloop.moc" -- cgit v0.12 From b2e678bfd4f190ab27cb380201207d8f227f0739 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 27 Jun 2011 13:09:23 +0200 Subject: QStringBuilder: do not crash with null char* This is supported by the others operator+ Change-Id: I9a1d1a0afb63acf32935948111d43ca6da370363 Reviewed-on: http://codereview.qt.nokia.com/764 Reviewed-by: hjk (cherry picked from commit 53a16752c257d2f4f99ecef2cde1580b817fc12a) --- src/corelib/tools/qstringbuilder.cpp | 2 ++ src/corelib/tools/qstringbuilder.h | 2 ++ tests/auto/qstringbuilder1/stringbuilder.cpp | 12 ++++++++++++ 3 files changed, 16 insertions(+) diff --git a/src/corelib/tools/qstringbuilder.cpp b/src/corelib/tools/qstringbuilder.cpp index 45de6bc..1cc7e5d 100644 --- a/src/corelib/tools/qstringbuilder.cpp +++ b/src/corelib/tools/qstringbuilder.cpp @@ -162,6 +162,8 @@ void QAbstractConcatenable::convertFromAscii(const char *a, int len, QChar *&out } #endif if (len == -1) { + if (!a) + return; while (*a) *out++ = QLatin1Char(*a++); } else { diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h index 709d84a..594ab2f 100644 --- a/src/corelib/tools/qstringbuilder.h +++ b/src/corelib/tools/qstringbuilder.h @@ -352,6 +352,8 @@ template <> struct QConcatenable : private QAbstractConcatenable #endif static inline void appendTo(const char *a, char *&out) { + if (!a) + return; while (*a) *out++ = *a++; } diff --git a/tests/auto/qstringbuilder1/stringbuilder.cpp b/tests/auto/qstringbuilder1/stringbuilder.cpp index 2327ef5..de7ad65 100644 --- a/tests/auto/qstringbuilder1/stringbuilder.cpp +++ b/tests/auto/qstringbuilder1/stringbuilder.cpp @@ -133,6 +133,12 @@ void runScenario() QCOMPARE(r, string); r = string P ba; QCOMPARE(r, string); + + const char *zero = 0; + r = string P zero; + QCOMPARE(r, string); + r = zero P string; + QCOMPARE(r, string); #endif string = QString::fromLatin1(LITERAL); @@ -161,6 +167,12 @@ void runScenario() QCOMPARE(r, r2); r2 = QByteArray("hello\0") P UTF8_LITERAL; QCOMPARE(r, r2); + + const char *zero = 0; + r = ba P zero; + QCOMPARE(r, ba); + r = zero P ba; + QCOMPARE(r, ba); } //operator QString += -- cgit v0.12 From 007f01a7e801d5409708e4b8de8b3ead1481cf7d Mon Sep 17 00:00:00 2001 From: Bernhard Rosenkraenzer Date: Mon, 27 Jun 2011 18:12:46 +0200 Subject: Make it compile with openssl 1.0.0d, gcc 4.6 SSL_ctrl's prototype has changed slightly in openssl 1.0.0x - the 4th argument is now a void* as opposed to a const void*. gcc 4.6 doesn't allow this as an implicit cast. Merge-request: 1239 Reviewed-by: Peter Hartmann --- src/network/ssl/qsslsocket_openssl.cpp | 4 ++++ src/network/ssl/qsslsocket_openssl_symbols.cpp | 4 ++++ src/network/ssl/qsslsocket_openssl_symbols_p.h | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 9a137a6..5a606af 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -420,7 +420,11 @@ init_context: QByteArray ace = QUrl::toAce(tlsHostName); // only send the SNI header if the URL is valid and not an IP if (!ace.isEmpty() && !QHostAddress().setAddress(tlsHostName)) { +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + if (!q_SSL_ctrl(ssl, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, ace.data())) +#else if (!q_SSL_ctrl(ssl, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, ace.constData())) +#endif qWarning("could not set SSL_CTRL_SET_TLSEXT_HOSTNAME, Server Name Indication disabled"); } } diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index a4cc3c4..90a840f 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -210,8 +210,12 @@ DEFINEFUNC(int, SSL_library_init, void, DUMMYARG, return -1, return) DEFINEFUNC(void, SSL_load_error_strings, void, DUMMYARG, return, DUMMYARG) DEFINEFUNC(SSL *, SSL_new, SSL_CTX *a, a, return 0, return) #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT) +#if OPENSSL_VERSION_NUMBER >= 0x10000000L +DEFINEFUNC4(long, SSL_ctrl, SSL *a, a, int cmd, cmd, long larg, larg, void *parg, parg, return -1, return) +#else DEFINEFUNC4(long, SSL_ctrl, SSL *a, a, int cmd, cmd, long larg, larg, const void *parg, parg, return -1, return) #endif +#endif DEFINEFUNC3(int, SSL_read, SSL *a, a, void *b, b, int c, c, return -1, return) DEFINEFUNC3(void, SSL_set_bio, SSL *a, a, BIO *b, b, BIO *c, c, return, DUMMYARG) DEFINEFUNC(void, SSL_set_accept_state, SSL *a, a, return, DUMMYARG) diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h index c0a3b4d..0381c4f 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h @@ -318,8 +318,12 @@ int q_SSL_library_init(); void q_SSL_load_error_strings(); SSL *q_SSL_new(SSL_CTX *a); #if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT) +#if OPENSSL_VERSION_NUMBER >= 0x10000000L +long q_SSL_ctrl(SSL *ssl,int cmd, long larg, void *parg); +#else long q_SSL_ctrl(SSL *ssl,int cmd, long larg, const void *parg); #endif +#endif int q_SSL_read(SSL *a, void *b, int c); void q_SSL_set_bio(SSL *a, BIO *b, BIO *c); void q_SSL_set_accept_state(SSL *a); -- cgit v0.12