Merge "Merge remote-tracking branch 'origin/5.3' into 5.4.0" into refs/staging/5.4.0

This commit is contained in:
Jani Heikkinen 2014-11-10 16:03:28 +01:00 committed by The Qt Project
commit 6dd3f0800f
8 changed files with 61 additions and 80 deletions

View File

@ -7,6 +7,9 @@ QMAKE_COMPILER = gcc clang llvm # clang pretends to be gcc
QMAKE_CC = clang QMAKE_CC = clang
QMAKE_CXX = clang++ QMAKE_CXX = clang++
QMAKE_LINK_C = $$QMAKE_CC
QMAKE_LINK_C_SHLIB = $$QMAKE_CC
QMAKE_LINK = $$QMAKE_CXX QMAKE_LINK = $$QMAKE_CXX
QMAKE_LINK_SHLIB = $$QMAKE_CXX QMAKE_LINK_SHLIB = $$QMAKE_CXX

View File

@ -13,6 +13,7 @@ QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
QMAKE_INCDIR = /usr/local/include QMAKE_INCDIR = /usr/local/include
QMAKE_LIBDIR = /usr/local/lib QMAKE_LIBDIR = /usr/local/lib
QMAKE_LFLAGS_NOUNDEF = -Wl,--no-undefined
QMAKE_LFLAGS_THREAD = -pthread QMAKE_LFLAGS_THREAD = -pthread
QMAKE_LIBS = QMAKE_LIBS =
@ -28,6 +29,5 @@ QMAKE_RANLIB =
include(../../common/unix.conf) include(../../common/unix.conf)
include(../../common/gcc-base-unix.conf) include(../../common/gcc-base-unix.conf)
include(../../common/g++-unix.conf)
include(../../common/clang.conf) include(../../common/clang.conf)
load(qt_config) load(qt_config)

View File

@ -760,14 +760,6 @@ void Widget::splitCaseSensitiveFunction()
void Widget::sprintfFunction() void Widget::sprintfFunction()
{ {
//! [63]
size_t BufSize;
char buf[BufSize];
::snprintf(buf, BufSize, "%lld", 123456789LL);
QString str = QString::fromUtf8(buf);
//! [63]
//! [64] //! [64]
QString result; QString result;
QTextStream(&result) << "pi = " << 3.14; QTextStream(&result) << "pi = " << 3.14;

View File

@ -5705,21 +5705,18 @@ QString QString::toUpper() const
Safely builds a formatted string from the format string \a cformat Safely builds a formatted string from the format string \a cformat
and an arbitrary list of arguments. and an arbitrary list of arguments.
The %lc escape sequence expects a unicode character of type ushort The format string supports the conversion specifiers, length modifiers,
(as returned by QChar::unicode()). The %ls escape sequence expects and flags provided by printf() in the standard C++ library. The \a cformat
a pointer to a zero-terminated array of unicode characters of type string and \c{%s} arguments must be UTF-8 encoded.
ushort (as returned by QString::utf16()).
\note This function expects a UTF-8 string for %s and Latin-1 for \note The \c{%lc} escape sequence expects a unicode character of type
the format string. \c char16_t, or \c ushort (as returned by QChar::unicode()).
The \c{%ls} escape sequence expects a pointer to a zero-terminated array
The format string supports most of the conversion specifiers of unicode characters of type \c char16_t, or ushort (as returned by
provided by printf() in the standard C++ library. It doesn't QString::utf16()). This is at odds with the printf() in the standard C++
honor the length modifiers (e.g. \c h for \c short, \c ll for library, which defines \c {%lc} to print a wchar_t and \c{%ls} to print
\c{long long}). If you need those, use the standard snprintf() a \c{wchar_t*}, and might also produce compiler warnings on platforms
function instead: where the size of \c {wchar_t} is not 16 bits.
\snippet qstring/main.cpp 63
\warning We do not recommend using QString::sprintf() in new Qt \warning We do not recommend using QString::sprintf() in new Qt
code. Instead, consider using QTextStream or arg(), both of code. Instead, consider using QTextStream or arg(), both of

View File

@ -282,24 +282,18 @@ public:
QStringList serverConnectionNames; QStringList serverConnectionNames;
ConnectionMode mode; ConnectionMode mode;
// members accessed in unlocked mode (except for deletion)
// connection and server provide their own locking mechanisms
// busService doesn't have state to be changed
DBusConnection *connection;
DBusServer *server;
QDBusConnectionInterface *busService; QDBusConnectionInterface *busService;
// watchers and timeouts are accessed from any thread // the dispatch lock protects everything related to the DBusConnection or DBusServer
// but the corresponding timer and QSocketNotifier must be handled // including the timeouts and watches
// only in the object's thread QMutex dispatchLock;
QMutex watchAndTimeoutLock; DBusConnection *connection;
DBusServer *server;
WatcherHash watchers; WatcherHash watchers;
TimeoutHash timeouts; TimeoutHash timeouts;
PendingTimeoutList timeoutsPendingAdd; PendingTimeoutList timeoutsPendingAdd;
// members accessed through a lock // the master lock protects our own internal state
QMutex dispatchLock;
QReadWriteLock lock; QReadWriteLock lock;
QDBusError lastError; QDBusError lastError;

View File

@ -154,7 +154,7 @@ static dbus_bool_t qDBusAddTimeout(DBusTimeout *timeout, void *data)
if (!q_dbus_timeout_get_enabled(timeout)) if (!q_dbus_timeout_get_enabled(timeout))
return true; return true;
QDBusWatchAndTimeoutLocker locker(AddTimeoutAction, d); QDBusDispatchLocker locker(AddTimeoutAction, d);
if (QCoreApplication::instance() && QThread::currentThread() == d->thread()) { if (QCoreApplication::instance() && QThread::currentThread() == d->thread()) {
// correct thread // correct thread
return qDBusRealAddTimeout(d, timeout, q_dbus_timeout_get_interval(timeout)); 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); QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data);
QDBusWatchAndTimeoutLocker locker(RemoveTimeoutAction, d); QDBusDispatchLocker locker(RemoveTimeoutAction, d);
// is it pending addition? // is it pending addition?
QDBusConnectionPrivate::PendingTimeoutList::iterator pit = d->timeoutsPendingAdd.begin(); QDBusConnectionPrivate::PendingTimeoutList::iterator pit = d->timeoutsPendingAdd.begin();
@ -262,7 +262,7 @@ static bool qDBusRealAddWatch(QDBusConnectionPrivate *d, DBusWatch *watch, int f
{ {
QDBusConnectionPrivate::Watcher watcher; QDBusConnectionPrivate::Watcher watcher;
QDBusWatchAndTimeoutLocker locker(AddWatchAction, d); QDBusDispatchLocker locker(AddWatchAction, d);
if (flags & DBUS_WATCH_READABLE) { if (flags & DBUS_WATCH_READABLE) {
//qDebug("addReadWatch %d", fd); //qDebug("addReadWatch %d", fd);
watcher.watch = watch; watcher.watch = watch;
@ -296,7 +296,7 @@ static void qDBusRemoveWatch(DBusWatch *watch, void *data)
QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data); QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data);
int fd = q_dbus_watch_get_unix_fd(watch); 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); QDBusConnectionPrivate::WatcherHash::iterator i = d->watchers.find(fd);
while (i != d->watchers.end() && i.key() == fd) { while (i != d->watchers.end() && i.key() == fd) {
if (i.value().watch == watch) { 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) 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); QDBusConnectionPrivate::WatcherHash::iterator i = d->watchers.find(fd);
while (i != d->watchers.end() && i.key() == 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(); extern bool qDBusInitThreads();
QDBusConnectionPrivate::QDBusConnectionPrivate(QObject *p) QDBusConnectionPrivate::QDBusConnectionPrivate(QObject *p)
: QObject(p), ref(1), capabilities(0), mode(InvalidMode), connection(0), server(0), busService(0), : QObject(p), ref(1), capabilities(0), mode(InvalidMode), busService(0),
watchAndTimeoutLock(QMutex::Recursive), dispatchLock(QMutex::Recursive), connection(0), server(0),
rootNode(QString(QLatin1Char('/'))), rootNode(QString(QLatin1Char('/'))),
anonymousAuthenticationAllowed(false) anonymousAuthenticationAllowed(false)
{ {
@ -1126,7 +1126,7 @@ bool QDBusConnectionPrivate::handleError(const QDBusErrorInternal &error)
void QDBusConnectionPrivate::timerEvent(QTimerEvent *e) void QDBusConnectionPrivate::timerEvent(QTimerEvent *e)
{ {
{ {
QDBusWatchAndTimeoutLocker locker(TimerEventAction, this); QDBusDispatchLocker locker(TimerEventAction, this);
DBusTimeout *timeout = timeouts.value(e->timerId(), 0); DBusTimeout *timeout = timeouts.value(e->timerId(), 0);
if (timeout) if (timeout)
q_dbus_timeout_handle(timeout); q_dbus_timeout_handle(timeout);
@ -1145,7 +1145,7 @@ void QDBusConnectionPrivate::customEvent(QEvent *e)
switch (ev->subtype) switch (ev->subtype)
{ {
case QDBusConnectionCallbackEvent::AddTimeout: { case QDBusConnectionCallbackEvent::AddTimeout: {
QDBusWatchAndTimeoutLocker locker(RealAddTimeoutAction, this); QDBusDispatchLocker locker(RealAddTimeoutAction, this);
while (!timeoutsPendingAdd.isEmpty()) { while (!timeoutsPendingAdd.isEmpty()) {
QPair<DBusTimeout *, int> entry = timeoutsPendingAdd.takeFirst(); QPair<DBusTimeout *, int> entry = timeoutsPendingAdd.takeFirst();
qDBusRealAddTimeout(this, entry.first, entry.second); qDBusRealAddTimeout(this, entry.first, entry.second);
@ -1178,43 +1178,31 @@ void QDBusConnectionPrivate::doDispatch()
void QDBusConnectionPrivate::socketRead(int fd) void QDBusConnectionPrivate::socketRead(int fd)
{ {
QVarLengthArray<DBusWatch *, 2> pendingWatches; QDBusDispatchLocker locker(SocketReadAction, this);
{
QDBusWatchAndTimeoutLocker locker(SocketReadAction, this);
WatcherHash::ConstIterator it = watchers.constFind(fd); WatcherHash::ConstIterator it = watchers.constFind(fd);
while (it != watchers.constEnd() && it.key() == fd) { while (it != watchers.constEnd() && it.key() == fd) {
if (it->watch && it->read && it->read->isEnabled()) if (it->watch && it->read && it->read->isEnabled()) {
pendingWatches.append(it.value().watch); if (!q_dbus_watch_handle(it.value().watch, DBUS_WATCH_READABLE))
qDebug("OUT OF MEM");
}
++it; ++it;
} }
}
for (int i = 0; i < pendingWatches.size(); ++i)
if (!q_dbus_watch_handle(pendingWatches[i], DBUS_WATCH_READABLE))
qDebug("OUT OF MEM");
doDispatch(); doDispatch();
} }
void QDBusConnectionPrivate::socketWrite(int fd) void QDBusConnectionPrivate::socketWrite(int fd)
{ {
QVarLengthArray<DBusWatch *, 2> pendingWatches; QDBusDispatchLocker locker(SocketWriteAction, this);
{
QDBusWatchAndTimeoutLocker locker(SocketWriteAction, this);
WatcherHash::ConstIterator it = watchers.constFind(fd); WatcherHash::ConstIterator it = watchers.constFind(fd);
while (it != watchers.constEnd() && it.key() == fd) { while (it != watchers.constEnd() && it.key() == fd) {
if (it->watch && it->write && it->write->isEnabled()) if (it->watch && it->write && it->write->isEnabled()) {
pendingWatches.append(it.value().watch); if (!q_dbus_watch_handle(it.value().watch, DBUS_WATCH_WRITABLE))
qDebug("OUT OF MEM");
}
++it; ++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) void QDBusConnectionPrivate::objectDestroyed(QObject *obj)
{ {
QDBusWriteLocker locker(ObjectDestroyedAction, this); QDBusWriteLocker locker(ObjectDestroyedAction, this);
@ -1265,7 +1253,10 @@ void QDBusConnectionPrivate::relaySignal(QObject *obj, const QMetaObject *mo, in
//qDBusDebug() << "Emitting signal" << message; //qDBusDebug() << "Emitting signal" << message;
//qDBusDebug() << "for paths:"; //qDBusDebug() << "for paths:";
q_dbus_message_set_no_reply(msg, true); // the reply would not be delivered to anything q_dbus_message_set_no_reply(msg, true); // the reply would not be delivered to anything
{
QDBusDispatchLocker locker(HuntAndEmitAction, this);
huntAndEmit(connection, msg, obj, rootNode, isScriptable, isAdaptor); huntAndEmit(connection, msg, obj, rootNode, isScriptable, isAdaptor);
}
q_dbus_message_unref(msg); q_dbus_message_unref(msg);
} }
@ -1922,7 +1913,11 @@ int QDBusConnectionPrivate::send(const QDBusMessage& message)
qDBusDebug() << this << "sending message (no reply):" << message; qDBusDebug() << this << "sending message (no reply):" << message;
checkThread(); 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; int serial = 0;
if (isOk) if (isOk)
serial = q_dbus_message_get_serial(msg); serial = q_dbus_message_get_serial(msg);
@ -2040,7 +2035,11 @@ QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message,
qDBusDebug() << this << "sending message (blocking):" << message; qDBusDebug() << this << "sending message (blocking):" << message;
QDBusErrorInternal error; 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); q_dbus_message_unref(msg);

View File

@ -86,6 +86,9 @@ enum ThreadAction {
MessageResultReceivedAction = 26, MessageResultReceivedAction = 26,
ActivateSignalAction = 27, ActivateSignalAction = 27,
PendingCallBlockAction = 28, PendingCallBlockAction = 28,
SendMessageAction = 29,
SendWithReplyAndBlockAction = 30,
HuntAndEmitAction = 31,
AddTimeoutAction = 50, AddTimeoutAction = 50,
RealAddTimeoutAction = 51, 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 #if QDBUS_THREAD_DEBUG
# define SEM_ACQUIRE(action, sem) \ # define SEM_ACQUIRE(action, sem) \
do { \ do { \

View File