diff options
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_win.cpp | 44 | ||||
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_win_p.h | 2 | ||||
-rw-r--r-- | src/corelib/kernel/qsignalmapper.cpp | 3 | ||||
-rw-r--r-- | src/corelib/kernel/qvariant.cpp | 9 | ||||
-rw-r--r-- | src/corelib/kernel/qvariant_p.h | 86 |
5 files changed, 81 insertions, 63 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 12296a3bec..d3242b6e67 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -84,6 +84,7 @@ extern uint qGlobalPostedEventsCount(); enum { WM_QT_SOCKETNOTIFIER = WM_USER, WM_QT_SENDPOSTEDEVENTS = WM_USER + 1, + WM_QT_ACTIVATENOTIFIERS = WM_USER + 2, SendPostedEventsWindowsTimerId = ~1u }; @@ -314,7 +315,7 @@ static void resolveTimerAPI() QEventDispatcherWin32Private::QEventDispatcherWin32Private() : threadId(GetCurrentThreadId()), interrupt(false), closingDown(false), internalHwnd(0), getMessageHook(0), serialNumber(0), lastSerialNumber(0), sendPostedEventsWindowsTimerId(0), - wakeUps(0) + wakeUps(0), activateNotifiersPosted(false) { resolveTimerAPI(); } @@ -398,6 +399,7 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA if (sn) { d->doWsaAsyncSelect(sn->fd, 0); d->active_fd[sn->fd].selected = false; + d->postActivateSocketNotifiers(); if (type < 3) { QEvent event(QEvent::SockAct); QCoreApplication::sendEvent(sn->obj, &event); @@ -408,6 +410,20 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA } } return 0; + } else if (message == WM_QT_ACTIVATENOTIFIERS) { + Q_ASSERT(d != 0); + + // register all socket notifiers + for (QSFDict::iterator it = d->active_fd.begin(), end = d->active_fd.end(); + it != end; ++it) { + QSockFd &sd = it.value(); + if (!sd.selected) { + d->doWsaAsyncSelect(it.key(), sd.event); + sd.selected = true; + } + } + d->activateNotifiersPosted = false; + return 0; } else if (message == WM_QT_SENDPOSTEDEVENTS // we also use a Windows timer to send posted events when the message queue is full || (message == WM_TIMER @@ -648,6 +664,12 @@ void QEventDispatcherWin32Private::doWsaAsyncSelect(int socket, long event) WSAAsyncSelect(socket, internalHwnd, event ? int(WM_QT_SOCKETNOTIFIER) : 0, event); } +void QEventDispatcherWin32Private::postActivateSocketNotifiers() +{ + if (!activateNotifiersPosted) + activateNotifiersPosted = PostMessage(internalHwnd, WM_QT_ACTIVATENOTIFIERS, 0, 0); +} + void QEventDispatcherWin32::createInternalHwnd() { Q_D(QEventDispatcherWin32); @@ -766,16 +788,6 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) d->queuedSocketEvents.append(msg); continue; } - } else if (!(flags & QEventLoop::ExcludeSocketNotifiers)) { - // register all socket notifiers - for (QSFDict::iterator it = d->active_fd.begin(), end = d->active_fd.end(); - it != end; ++it) { - QSockFd &sd = it.value(); - if (!sd.selected) { - d->doWsaAsyncSelect(it.key(), sd.event); - sd.selected = true; - } - } } } if (!haveMessage) { @@ -896,6 +908,8 @@ void QEventDispatcherWin32::registerSocketNotifier(QSocketNotifier *notifier) "same socket %d and type %s", sockfd, t[type]); } + createInternalHwnd(); + QSockNot *sn = new QSockNot; sn->obj = notifier; sn->fd = sockfd; @@ -920,6 +934,8 @@ void QEventDispatcherWin32::registerSocketNotifier(QSocketNotifier *notifier) } else { d->active_fd.insert(sockfd, QSockFd(event)); } + + d->postActivateSocketNotifiers(); } void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier) @@ -945,10 +961,12 @@ void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier) d->doWsaAsyncSelect(sockfd, 0); const long event[3] = { FD_READ | FD_CLOSE | FD_ACCEPT, FD_WRITE | FD_CONNECT, FD_OOB }; sd.event ^= event[type]; - if (sd.event == 0) + if (sd.event == 0) { d->active_fd.erase(it); - else + } else if (sd.selected) { sd.selected = false; + d->postActivateSocketNotifiers(); + } } QSNDict *sn_vec[3] = { &d->sn_read, &d->sn_write, &d->sn_except }; diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h index 6efa81fe79..848dbaf475 100644 --- a/src/corelib/kernel/qeventdispatcher_win_p.h +++ b/src/corelib/kernel/qeventdispatcher_win_p.h @@ -184,7 +184,9 @@ public: QSNDict sn_write; QSNDict sn_except; QSFDict active_fd; + bool activateNotifiersPosted; void doWsaAsyncSelect(int socket, long event); + void postActivateSocketNotifiers(); QList<QWinEventNotifier *> winEventNotifierList; void activateEventNotifier(QWinEventNotifier * wen); diff --git a/src/corelib/kernel/qsignalmapper.cpp b/src/corelib/kernel/qsignalmapper.cpp index c738866d61..a483717da5 100644 --- a/src/corelib/kernel/qsignalmapper.cpp +++ b/src/corelib/kernel/qsignalmapper.cpp @@ -226,6 +226,9 @@ QObject *QSignalMapper::mapping(QObject *object) const Removes all mappings for \a sender. This is done automatically when mapped objects are destroyed. + + \note This does not disconnect any signals. If \a sender is not destroyed + then this will need to be done explicitly if required. */ void QSignalMapper::removeMappings(QObject *sender) { diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 143da62b63..01351f97ff 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -2886,6 +2886,7 @@ static const quint32 qCanConvertMatrix[QVariant::LastCoreType + 1] = /*QUuid*/ 1 << QVariant::String }; +static const size_t qCanConvertMatrixMaximumTargetType = 8 * sizeof(*qCanConvertMatrix); #ifndef QT_BOOTSTRAPPED /*! @@ -3135,8 +3136,9 @@ bool QVariant::canConvert(int targetTypeId) const case QMetaType::ULong: case QMetaType::Short: case QMetaType::UShort: - return qCanConvertMatrix[QVariant::Int] & (1 << currentType) - || currentType == QVariant::Int + return currentType == QVariant::Int + || (currentType < qCanConvertMatrixMaximumTargetType + && qCanConvertMatrix[QVariant::Int] & (1U << currentType)) || QMetaType::typeFlags(currentType) & QMetaType::IsEnumeration; case QMetaType::QObjectStar: return canConvertMetaObject(currentType, targetTypeId, d.data.o); @@ -3147,7 +3149,8 @@ bool QVariant::canConvert(int targetTypeId) const if (targetTypeId == String && currentType == StringList) return v_cast<QStringList>(&d)->count() == 1; - return qCanConvertMatrix[targetTypeId] & (1 << currentType); + return currentType < qCanConvertMatrixMaximumTargetType + && qCanConvertMatrix[targetTypeId] & (1U << currentType); } /*! diff --git a/src/corelib/kernel/qvariant_p.h b/src/corelib/kernel/qvariant_p.h index 4d1f883651..d01f386032 100644 --- a/src/corelib/kernel/qvariant_p.h +++ b/src/corelib/kernel/qvariant_p.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -65,6 +66,7 @@ struct QVariantIntegrator { static const bool CanUseInternalSpace = sizeof(T) <= sizeof(QVariant::Private::Data) && ((QTypeInfoQuery<T>::isRelocatable) || Q_IS_ENUM(T)); + typedef QtPrivate::integral_constant<bool, CanUseInternalSpace> CanUseInternalSpace_t; }; Q_STATIC_ASSERT(QVariantIntegrator<double>::CanUseInternalSpace); Q_STATIC_ASSERT(QVariantIntegrator<long int>::CanUseInternalSpace); @@ -115,31 +117,49 @@ private: T m_t; }; -// constructs a new variant if copy is 0, otherwise copy-constructs template <class T> -inline void v_construct(QVariant::Private *x, const void *copy, T * = 0) +inline void v_construct_helper(QVariant::Private *x, const T &t, QtPrivate::true_type) { - if (!QVariantIntegrator<T>::CanUseInternalSpace) { - x->data.shared = copy ? new QVariantPrivateSharedEx<T>(*static_cast<const T *>(copy)) - : new QVariantPrivateSharedEx<T>; - x->is_shared = true; - } else { - if (copy) - new (&x->data.ptr) T(*static_cast<const T *>(copy)); - else - new (&x->data.ptr) T; - } + new (&x->data) T(t); + x->is_shared = false; +} + +template <class T> +inline void v_construct_helper(QVariant::Private *x, const T &t, QtPrivate::false_type) +{ + x->data.shared = new QVariantPrivateSharedEx<T>(t); + x->is_shared = true; +} + +template <class T> +inline void v_construct_helper(QVariant::Private *x, QtPrivate::true_type) +{ + new (&x->data) T(); + x->is_shared = false; +} + +template <class T> +inline void v_construct_helper(QVariant::Private *x, QtPrivate::false_type) +{ + x->data.shared = new QVariantPrivateSharedEx<T>; + x->is_shared = true; } template <class T> inline void v_construct(QVariant::Private *x, const T &t) { - if (!QVariantIntegrator<T>::CanUseInternalSpace) { - x->data.shared = new QVariantPrivateSharedEx<T>(t); - x->is_shared = true; - } else { - new (&x->data.ptr) T(t); - } + // dispatch + v_construct_helper(x, t, typename QVariantIntegrator<T>::CanUseInternalSpace_t()); +} + +// constructs a new variant if copy is 0, otherwise copy-constructs +template <class T> +inline void v_construct(QVariant::Private *x, const void *copy, T * = 0) +{ + if (copy) + v_construct<T>(x, *static_cast<const T *>(copy)); + else + v_construct_helper<T>(x, typename QVariantIntegrator<T>::CanUseInternalSpace_t()); } // deletes the internal structures @@ -294,39 +314,11 @@ protected: template<class Filter> class QVariantConstructor { - template<typename T, bool CanUseInternalSpace = QVariantIntegrator<T>::CanUseInternalSpace> - struct CallConstructor {}; - - template<typename T> - struct CallConstructor<T, /* CanUseInternalSpace = */ true> - { - CallConstructor(const QVariantConstructor &tc) - { - if (tc.m_copy) - new (&tc.m_x->data.ptr) T(*static_cast<const T*>(tc.m_copy)); - else - new (&tc.m_x->data.ptr) T(); - tc.m_x->is_shared = false; - } - }; - - template<typename T> - struct CallConstructor<T, /* CanUseInternalSpace = */ false> - { - CallConstructor(const QVariantConstructor &tc) - { - Q_STATIC_ASSERT(QTypeInfo<T>::isComplex || sizeof(T) > sizeof(QVariant::Private::Data)); - tc.m_x->data.shared = tc.m_copy ? new QVariantPrivateSharedEx<T>(*static_cast<const T*>(tc.m_copy)) - : new QVariantPrivateSharedEx<T>; - tc.m_x->is_shared = true; - } - }; - template<typename T, bool IsAcceptedType = Filter::template Acceptor<T>::IsAccepted> struct FilteredConstructor { FilteredConstructor(const QVariantConstructor &tc) { - CallConstructor<T> tmp(tc); + v_construct<T>(tc.m_x, tc.m_copy); tc.m_x->is_null = !tc.m_copy; } }; |