diff --git a/mkspecs/common/clang.conf b/mkspecs/common/clang.conf index 6235296ef3312c999b8a8f35a6e760d2480fba21..2c29bb88fb1ba22324293d8dcfb1bc5c25a08084 100644 --- a/mkspecs/common/clang.conf +++ b/mkspecs/common/clang.conf @@ -7,6 +7,9 @@ QMAKE_COMPILER = gcc clang llvm # clang pretends to be gcc QMAKE_CC = clang QMAKE_CXX = clang++ +QMAKE_LINK_C = $$QMAKE_CC +QMAKE_LINK_C_SHLIB = $$QMAKE_CC + QMAKE_LINK = $$QMAKE_CXX QMAKE_LINK_SHLIB = $$QMAKE_CXX diff --git a/mkspecs/unsupported/freebsd-clang/qmake.conf b/mkspecs/unsupported/freebsd-clang/qmake.conf index ad4fa3487ed3b5c867a3572e0b8f47704e8e46a4..2cfd763688e5cf3b7322652844c45baac2205247 100644 --- a/mkspecs/unsupported/freebsd-clang/qmake.conf +++ b/mkspecs/unsupported/freebsd-clang/qmake.conf @@ -13,6 +13,7 @@ QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD QMAKE_INCDIR = /usr/local/include QMAKE_LIBDIR = /usr/local/lib +QMAKE_LFLAGS_NOUNDEF = -Wl,--no-undefined QMAKE_LFLAGS_THREAD = -pthread QMAKE_LIBS = @@ -28,6 +29,5 @@ QMAKE_RANLIB = include(../../common/unix.conf) include(../../common/gcc-base-unix.conf) -include(../../common/g++-unix.conf) include(../../common/clang.conf) load(qt_config) diff --git a/src/corelib/doc/snippets/qstring/main.cpp b/src/corelib/doc/snippets/qstring/main.cpp index bf45a31c294a02fda561ff28bb1a2928084c8272..f49c4dd35970b4254b6ffe7ecc52e2f298bd624c 100644 --- a/src/corelib/doc/snippets/qstring/main.cpp +++ b/src/corelib/doc/snippets/qstring/main.cpp @@ -760,14 +760,6 @@ void Widget::splitCaseSensitiveFunction() void Widget::sprintfFunction() { - //! [63] - size_t BufSize; - char buf[BufSize]; - - ::snprintf(buf, BufSize, "%lld", 123456789LL); - QString str = QString::fromUtf8(buf); - //! [63] - //! [64] QString result; QTextStream(&result) << "pi = " << 3.14; diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 48f251e3f4292e7a6e207dbe0895f7a1f18f508b..71ca4239d058016895e2f820a27bb9437f52a1b9 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -5705,21 +5705,18 @@ QString QString::toUpper() const Safely builds a formatted string from the format string \a cformat and an arbitrary list of arguments. - The %lc escape sequence expects a unicode character of type ushort - (as returned by QChar::unicode()). The %ls escape sequence expects - a pointer to a zero-terminated array of unicode characters of type - ushort (as returned by QString::utf16()). - - \note This function expects a UTF-8 string for %s and Latin-1 for - the format string. - - The format string supports most of the conversion specifiers - provided by printf() in the standard C++ library. It doesn't - honor the length modifiers (e.g. \c h for \c short, \c ll for - \c{long long}). If you need those, use the standard snprintf() - function instead: - - \snippet qstring/main.cpp 63 + The format string supports the conversion specifiers, length modifiers, + and flags provided by printf() in the standard C++ library. The \a cformat + string and \c{%s} arguments must be UTF-8 encoded. + + \note The \c{%lc} escape sequence expects a unicode character of type + \c char16_t, or \c ushort (as returned by QChar::unicode()). + The \c{%ls} escape sequence expects a pointer to a zero-terminated array + of unicode characters of type \c char16_t, or ushort (as returned by + QString::utf16()). This is at odds with the printf() in the standard C++ + library, which defines \c {%lc} to print a wchar_t and \c{%ls} to print + a \c{wchar_t*}, and might also produce compiler warnings on platforms + where the size of \c {wchar_t} is not 16 bits. \warning We do not recommend using QString::sprintf() in new Qt code. Instead, consider using QTextStream or arg(), both of diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index b1ec11dc71f6c25f5217dafe3dcb88843a0dc48d..00c3aced0e3108c102a73272355311cfe33e39b9 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -282,24 +282,18 @@ public: QStringList serverConnectionNames; ConnectionMode mode; + QDBusConnectionInterface *busService; - // members accessed in unlocked mode (except for deletion) - // connection and server provide their own locking mechanisms - // busService doesn't have state to be changed + // the dispatch lock protects everything related to the DBusConnection or DBusServer + // including the timeouts and watches + QMutex dispatchLock; DBusConnection *connection; DBusServer *server; - QDBusConnectionInterface *busService; - - // watchers and timeouts are accessed from any thread - // but the corresponding timer and QSocketNotifier must be handled - // only in the object's thread - QMutex watchAndTimeoutLock; WatcherHash watchers; TimeoutHash timeouts; PendingTimeoutList timeoutsPendingAdd; - // members accessed through a lock - QMutex dispatchLock; + // the master lock protects our own internal state QReadWriteLock lock; QDBusError lastError; diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 0dc8477ff4bfddb8f68b3840867685241a30848d..f27d45b1429291120acf2e77332d364c136d28c3 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -154,7 +154,7 @@ static dbus_bool_t qDBusAddTimeout(DBusTimeout *timeout, void *data) if (!q_dbus_timeout_get_enabled(timeout)) return true; - QDBusWatchAndTimeoutLocker locker(AddTimeoutAction, d); + QDBusDispatchLocker locker(AddTimeoutAction, d); if (QCoreApplication::instance() && QThread::currentThread() == d->thread()) { // correct thread return qDBusRealAddTimeout(d, timeout, q_dbus_timeout_get_interval(timeout)); @@ -189,7 +189,7 @@ static void qDBusRemoveTimeout(DBusTimeout *timeout, void *data) QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data); - QDBusWatchAndTimeoutLocker locker(RemoveTimeoutAction, d); + QDBusDispatchLocker locker(RemoveTimeoutAction, d); // is it pending addition? QDBusConnectionPrivate::PendingTimeoutList::iterator pit = d->timeoutsPendingAdd.begin(); @@ -262,7 +262,7 @@ static bool qDBusRealAddWatch(QDBusConnectionPrivate *d, DBusWatch *watch, int f { QDBusConnectionPrivate::Watcher watcher; - QDBusWatchAndTimeoutLocker locker(AddWatchAction, d); + QDBusDispatchLocker locker(AddWatchAction, d); if (flags & DBUS_WATCH_READABLE) { //qDebug("addReadWatch %d", fd); watcher.watch = watch; @@ -296,7 +296,7 @@ static void qDBusRemoveWatch(DBusWatch *watch, void *data) QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data); int fd = q_dbus_watch_get_unix_fd(watch); - QDBusWatchAndTimeoutLocker locker(RemoveWatchAction, d); + QDBusDispatchLocker locker(RemoveWatchAction, d); QDBusConnectionPrivate::WatcherHash::iterator i = d->watchers.find(fd); while (i != d->watchers.end() && i.key() == fd) { if (i.value().watch == watch) { @@ -340,7 +340,7 @@ static void qDBusToggleWatch(DBusWatch *watch, void *data) static void qDBusRealToggleWatch(QDBusConnectionPrivate *d, DBusWatch *watch, int fd) { - QDBusWatchAndTimeoutLocker locker(ToggleWatchAction, d); + QDBusDispatchLocker locker(ToggleWatchAction, d); QDBusConnectionPrivate::WatcherHash::iterator i = d->watchers.find(fd); while (i != d->watchers.end() && i.key() == fd) { @@ -1015,8 +1015,8 @@ void QDBusConnectionPrivate::deliverCall(QObject *object, int /*flags*/, const Q extern bool qDBusInitThreads(); QDBusConnectionPrivate::QDBusConnectionPrivate(QObject *p) - : QObject(p), ref(1), capabilities(0), mode(InvalidMode), connection(0), server(0), busService(0), - watchAndTimeoutLock(QMutex::Recursive), + : QObject(p), ref(1), capabilities(0), mode(InvalidMode), busService(0), + dispatchLock(QMutex::Recursive), connection(0), server(0), rootNode(QString(QLatin1Char('/'))), anonymousAuthenticationAllowed(false) { @@ -1126,7 +1126,7 @@ bool QDBusConnectionPrivate::handleError(const QDBusErrorInternal &error) void QDBusConnectionPrivate::timerEvent(QTimerEvent *e) { { - QDBusWatchAndTimeoutLocker locker(TimerEventAction, this); + QDBusDispatchLocker locker(TimerEventAction, this); DBusTimeout *timeout = timeouts.value(e->timerId(), 0); if (timeout) q_dbus_timeout_handle(timeout); @@ -1145,7 +1145,7 @@ void QDBusConnectionPrivate::customEvent(QEvent *e) switch (ev->subtype) { case QDBusConnectionCallbackEvent::AddTimeout: { - QDBusWatchAndTimeoutLocker locker(RealAddTimeoutAction, this); + QDBusDispatchLocker locker(RealAddTimeoutAction, this); while (!timeoutsPendingAdd.isEmpty()) { QPair<DBusTimeout *, int> entry = timeoutsPendingAdd.takeFirst(); qDBusRealAddTimeout(this, entry.first, entry.second); @@ -1178,41 +1178,29 @@ void QDBusConnectionPrivate::doDispatch() void QDBusConnectionPrivate::socketRead(int fd) { - QVarLengthArray<DBusWatch *, 2> pendingWatches; - - { - QDBusWatchAndTimeoutLocker locker(SocketReadAction, this); - WatcherHash::ConstIterator it = watchers.constFind(fd); - while (it != watchers.constEnd() && it.key() == fd) { - if (it->watch && it->read && it->read->isEnabled()) - pendingWatches.append(it.value().watch); - ++it; + QDBusDispatchLocker locker(SocketReadAction, this); + WatcherHash::ConstIterator it = watchers.constFind(fd); + while (it != watchers.constEnd() && it.key() == fd) { + if (it->watch && it->read && it->read->isEnabled()) { + if (!q_dbus_watch_handle(it.value().watch, DBUS_WATCH_READABLE)) + qDebug("OUT OF MEM"); } + ++it; } - - for (int i = 0; i < pendingWatches.size(); ++i) - if (!q_dbus_watch_handle(pendingWatches[i], DBUS_WATCH_READABLE)) - qDebug("OUT OF MEM"); doDispatch(); } void QDBusConnectionPrivate::socketWrite(int fd) { - QVarLengthArray<DBusWatch *, 2> pendingWatches; - - { - QDBusWatchAndTimeoutLocker locker(SocketWriteAction, this); - WatcherHash::ConstIterator it = watchers.constFind(fd); - while (it != watchers.constEnd() && it.key() == fd) { - if (it->watch && it->write && it->write->isEnabled()) - pendingWatches.append(it.value().watch); - ++it; + QDBusDispatchLocker locker(SocketWriteAction, this); + WatcherHash::ConstIterator it = watchers.constFind(fd); + while (it != watchers.constEnd() && it.key() == fd) { + if (it->watch && it->write && it->write->isEnabled()) { + if (!q_dbus_watch_handle(it.value().watch, DBUS_WATCH_WRITABLE)) + qDebug("OUT OF MEM"); } + ++it; } - - for (int i = 0; i < pendingWatches.size(); ++i) - if (!q_dbus_watch_handle(pendingWatches[i], DBUS_WATCH_WRITABLE)) - qDebug("OUT OF MEM"); } void QDBusConnectionPrivate::objectDestroyed(QObject *obj) @@ -1265,7 +1253,10 @@ void QDBusConnectionPrivate::relaySignal(QObject *obj, const QMetaObject *mo, in //qDBusDebug() << "Emitting signal" << message; //qDBusDebug() << "for paths:"; q_dbus_message_set_no_reply(msg, true); // the reply would not be delivered to anything - huntAndEmit(connection, msg, obj, rootNode, isScriptable, isAdaptor); + { + QDBusDispatchLocker locker(HuntAndEmitAction, this); + huntAndEmit(connection, msg, obj, rootNode, isScriptable, isAdaptor); + } q_dbus_message_unref(msg); } @@ -1922,7 +1913,11 @@ int QDBusConnectionPrivate::send(const QDBusMessage& message) qDBusDebug() << this << "sending message (no reply):" << message; checkThread(); - bool isOk = q_dbus_connection_send(connection, msg, 0); + bool isOk; + { + QDBusDispatchLocker locker(SendMessageAction, this); + isOk = q_dbus_connection_send(connection, msg, 0); + } int serial = 0; if (isOk) serial = q_dbus_message_get_serial(msg); @@ -2040,7 +2035,11 @@ QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message, qDBusDebug() << this << "sending message (blocking):" << message; QDBusErrorInternal error; - DBusMessage *reply = q_dbus_connection_send_with_reply_and_block(connection, msg, timeout, error); + DBusMessage *reply; + { + QDBusDispatchLocker locker(SendWithReplyAndBlockAction, this); + reply = q_dbus_connection_send_with_reply_and_block(connection, msg, timeout, error); + } q_dbus_message_unref(msg); diff --git a/src/dbus/qdbusthreaddebug_p.h b/src/dbus/qdbusthreaddebug_p.h index 78db18f5c766bf35a3267f6b3e853bf4eb4645dd..804106813400aa3a758dc6c971876add39a305e7 100644 --- a/src/dbus/qdbusthreaddebug_p.h +++ b/src/dbus/qdbusthreaddebug_p.h @@ -86,6 +86,9 @@ enum ThreadAction { MessageResultReceivedAction = 26, ActivateSignalAction = 27, PendingCallBlockAction = 28, + SendMessageAction = 29, + SendWithReplyAndBlockAction = 30, + HuntAndEmitAction = 31, AddTimeoutAction = 50, RealAddTimeoutAction = 51, @@ -196,13 +199,6 @@ struct QDBusDispatchLocker: QDBusMutexLocker { } }; -struct QDBusWatchAndTimeoutLocker: QDBusMutexLocker -{ - inline QDBusWatchAndTimeoutLocker(ThreadAction a, QDBusConnectionPrivate *s) - : QDBusMutexLocker(a, s, &s->watchAndTimeoutLock) - { } -}; - #if QDBUS_THREAD_DEBUG # define SEM_ACQUIRE(action, sem) \ do { \ diff --git a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp old mode 100755 new mode 100644