Merge remote-tracking branch 'origin/5.15' into dev
Change-Id: I6ad865b2c26003f4508da9b3f8e075a951ff8ef7
This commit is contained in:
commit
721a0e8078
@ -195,8 +195,11 @@ void QAnimationGroup::insertAnimation(int index, QAbstractAnimation *animation)
|
||||
return;
|
||||
}
|
||||
|
||||
if (QAnimationGroup *oldGroup = animation->group())
|
||||
if (QAnimationGroup *oldGroup = animation->group()) {
|
||||
oldGroup->removeAnimation(animation);
|
||||
// ensure we don't insert out of bounds if oldGroup == this
|
||||
index = qMin(index, d->animations.size());
|
||||
}
|
||||
|
||||
d->animations.insert(index, animation);
|
||||
QAbstractAnimationPrivate::get(animation)->group = this;
|
||||
|
@ -901,30 +901,8 @@ static bool check_parent_thread(QObject *parent,
|
||||
*/
|
||||
|
||||
QObject::QObject(QObject *parent)
|
||||
: d_ptr(new QObjectPrivate)
|
||||
: QObject(*new QObjectPrivate, parent)
|
||||
{
|
||||
Q_ASSERT_X(this != parent, Q_FUNC_INFO, "Cannot parent a QObject to itself");
|
||||
|
||||
Q_D(QObject);
|
||||
d_ptr->q_ptr = this;
|
||||
d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
|
||||
d->threadData->ref();
|
||||
if (parent) {
|
||||
QT_TRY {
|
||||
if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData))
|
||||
parent = 0;
|
||||
setParent(parent);
|
||||
} QT_CATCH(...) {
|
||||
d->threadData->deref();
|
||||
QT_RETHROW;
|
||||
}
|
||||
}
|
||||
#if QT_VERSION < 0x60000
|
||||
qt_addObject(this);
|
||||
#endif
|
||||
if (Q_UNLIKELY(qtHookData[QHooks::AddQObject]))
|
||||
reinterpret_cast<QHooks::AddQObjectCallback>(qtHookData[QHooks::AddQObject])(this);
|
||||
Q_TRACE(QObject_ctor, this);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2145,7 +2123,9 @@ void QObjectPrivate::setParent_helper(QObject *o)
|
||||
// cleared our entry in parentD->children.
|
||||
} else {
|
||||
const int index = parentD->children.indexOf(q);
|
||||
if (parentD->isDeletingChildren) {
|
||||
if (index < 0) {
|
||||
// we're probably recursing into setParent() from a ChildRemoved event, don't do anything
|
||||
} else if (parentD->isDeletingChildren) {
|
||||
parentD->children[index] = 0;
|
||||
} else {
|
||||
parentD->children.removeAt(index);
|
||||
|
@ -847,9 +847,10 @@ void **QListData::erase(void **xi)
|
||||
|
||||
/*! \fn template <class T> void QList<T>::insert(int i, const T &value)
|
||||
|
||||
Inserts \a value at index position \a i in the list. If \a i <= 0,
|
||||
the value is prepended to the list. If \a i >= size(), the
|
||||
value is appended to the list.
|
||||
Inserts \a value at index position \a i in the list.
|
||||
|
||||
If \a i == 0, the value is prepended to the list. If \a i == size(),
|
||||
the value is appended to the list.
|
||||
|
||||
Example:
|
||||
\snippet code/src_corelib_tools_qlistdata.cpp 8
|
||||
|
@ -580,8 +580,16 @@ inline T &QList<T>::operator[](int i)
|
||||
detach(); return reinterpret_cast<Node *>(p.at(i))->t(); }
|
||||
template <typename T>
|
||||
inline void QList<T>::removeAt(int i)
|
||||
{ if(i >= 0 && i < p.size()) { detach();
|
||||
node_destruct(reinterpret_cast<Node *>(p.at(i))); p.remove(i); } }
|
||||
{
|
||||
#if !QT_DEPRECATED_SINCE(5, 15)
|
||||
Q_ASSERT_X(i >= 0 && i < p.size(), "QList<T>::removeAt", "index out of range");
|
||||
#elif !defined(QT_NO_DEBUG)
|
||||
if (i < 0 || i >= p.size())
|
||||
qWarning("QList::removeAt(): Index out of range.");
|
||||
#endif
|
||||
detach();
|
||||
node_destruct(reinterpret_cast<Node *>(p.at(i))); p.remove(i);
|
||||
}
|
||||
template <typename T>
|
||||
inline T QList<T>::takeAt(int i)
|
||||
{ Q_ASSERT_X(i >= 0 && i < p.size(), "QList<T>::take", "index out of range");
|
||||
@ -676,6 +684,12 @@ inline void QList<T>::prepend(const T &t)
|
||||
template <typename T>
|
||||
inline void QList<T>::insert(int i, const T &t)
|
||||
{
|
||||
#if !QT_DEPRECATED_SINCE(5, 15)
|
||||
Q_ASSERT_X(i >= 0 && i <= p.size(), "QList<T>::insert", "index out of range");
|
||||
#elif !defined(QT_NO_DEBUG)
|
||||
if (i < 0 || i > p.size())
|
||||
qWarning("QList::insert(): Index out of range.");
|
||||
#endif
|
||||
if (d->ref.isShared()) {
|
||||
Node *n = detach_helper_grow(i, 1);
|
||||
QT_TRY {
|
||||
|
@ -108,7 +108,11 @@ public:
|
||||
friend class QSet<T>;
|
||||
|
||||
public:
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
#else
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
#endif
|
||||
typedef qptrdiff difference_type;
|
||||
typedef T value_type;
|
||||
typedef const T *pointer;
|
||||
@ -128,13 +132,15 @@ public:
|
||||
{ return i != o.i; }
|
||||
inline iterator &operator++() { ++i; return *this; }
|
||||
inline iterator operator++(int) { iterator r = *this; ++i; return r; }
|
||||
inline iterator &operator--() { --i; return *this; }
|
||||
inline iterator operator--(int) { iterator r = *this; --i; return r; }
|
||||
inline iterator operator+(int j) const { return i + j; }
|
||||
inline iterator operator-(int j) const { return i - j; }
|
||||
friend inline iterator operator+(int j, iterator k) { return k + j; }
|
||||
inline iterator &operator+=(int j) { i += j; return *this; }
|
||||
inline iterator &operator-=(int j) { i -= j; return *this; }
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
inline QT_DEPRECATED iterator &operator--() { --i; return *this; }
|
||||
inline QT_DEPRECATED iterator operator--(int) { iterator r = *this; --i; return r; }
|
||||
inline QT_DEPRECATED iterator operator+(int j) const { return i + j; }
|
||||
inline QT_DEPRECATED iterator operator-(int j) const { return i - j; }
|
||||
friend inline QT_DEPRECATED iterator operator+(int j, iterator k) { return k + j; }
|
||||
inline QT_DEPRECATED iterator &operator+=(int j) { i += j; return *this; }
|
||||
inline QT_DEPRECATED iterator &operator-=(int j) { i -= j; return *this; }
|
||||
#endif
|
||||
};
|
||||
|
||||
class const_iterator
|
||||
@ -145,7 +151,11 @@ public:
|
||||
friend class QSet<T>;
|
||||
|
||||
public:
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
#else
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
#endif
|
||||
typedef qptrdiff difference_type;
|
||||
typedef T value_type;
|
||||
typedef const T *pointer;
|
||||
@ -163,19 +173,18 @@ public:
|
||||
inline bool operator!=(const const_iterator &o) const { return i != o.i; }
|
||||
inline const_iterator &operator++() { ++i; return *this; }
|
||||
inline const_iterator operator++(int) { const_iterator r = *this; ++i; return r; }
|
||||
inline const_iterator &operator--() { --i; return *this; }
|
||||
inline const_iterator operator--(int) { const_iterator r = *this; --i; return r; }
|
||||
inline const_iterator operator+(int j) const { return i + j; }
|
||||
inline const_iterator operator-(int j) const { return i - j; }
|
||||
friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
|
||||
inline const_iterator &operator+=(int j) { i += j; return *this; }
|
||||
inline const_iterator &operator-=(int j) { i -= j; return *this; }
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
inline QT_DEPRECATED const_iterator &operator--() { --i; return *this; }
|
||||
inline QT_DEPRECATED const_iterator operator--(int) { const_iterator r = *this; --i; return r; }
|
||||
inline QT_DEPRECATED const_iterator operator+(int j) const { return i + j; }
|
||||
inline QT_DEPRECATED const_iterator operator-(int j) const { return i - j; }
|
||||
friend inline QT_DEPRECATED const_iterator operator+(int j, const_iterator k) { return k + j; }
|
||||
inline QT_DEPRECATED const_iterator &operator+=(int j) { i += j; return *this; }
|
||||
inline QT_DEPRECATED const_iterator &operator-=(int j) { i -= j; return *this; }
|
||||
#endif
|
||||
};
|
||||
|
||||
// STL style
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
inline iterator begin() { return q_hash.begin(); }
|
||||
inline const_iterator begin() const noexcept { return q_hash.begin(); }
|
||||
inline const_iterator cbegin() const noexcept { return q_hash.begin(); }
|
||||
@ -185,12 +194,17 @@ public:
|
||||
inline const_iterator cend() const noexcept { return q_hash.end(); }
|
||||
inline const_iterator constEnd() const noexcept { return q_hash.constEnd(); }
|
||||
|
||||
reverse_iterator rbegin() { return reverse_iterator(end()); }
|
||||
reverse_iterator rend() { return reverse_iterator(begin()); }
|
||||
const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
|
||||
const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
|
||||
const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); }
|
||||
const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); }
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
reverse_iterator QT_DEPRECATED rbegin() { return reverse_iterator(end()); }
|
||||
reverse_iterator QT_DEPRECATED rend() { return reverse_iterator(begin()); }
|
||||
const_reverse_iterator QT_DEPRECATED rbegin() const noexcept { return const_reverse_iterator(end()); }
|
||||
const_reverse_iterator QT_DEPRECATED rend() const noexcept { return const_reverse_iterator(begin()); }
|
||||
const_reverse_iterator QT_DEPRECATED crbegin() const noexcept { return const_reverse_iterator(end()); }
|
||||
const_reverse_iterator QT_DEPRECATED crend() const noexcept { return const_reverse_iterator(begin()); }
|
||||
#endif
|
||||
|
||||
iterator erase(iterator i)
|
||||
{ return erase(m2c(i)); }
|
||||
@ -399,17 +413,19 @@ public:
|
||||
inline bool hasNext() const { return c->constEnd() != i; }
|
||||
inline const T &next() { n = i++; return *n; }
|
||||
inline const T &peekNext() const { return *i; }
|
||||
inline bool hasPrevious() const { return c->constBegin() != i; }
|
||||
inline const T &previous() { n = --i; return *n; }
|
||||
inline const T &peekPrevious() const { iterator p = i; return *--p; }
|
||||
inline void remove()
|
||||
{ if (c->constEnd() != n) { i = c->erase(n); n = c->end(); } }
|
||||
inline const T &value() const { Q_ASSERT(item_exists()); return *n; }
|
||||
inline bool findNext(const T &t)
|
||||
{ while (c->constEnd() != (n = i)) if (*i++ == t) return true; return false; }
|
||||
inline bool findPrevious(const T &t)
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
inline QT_DEPRECATED bool hasPrevious() const { return c->constBegin() != i; }
|
||||
inline QT_DEPRECATED const T &previous() { n = --i; return *n; }
|
||||
inline QT_DEPRECATED const T &peekPrevious() const { iterator p = i; return *--p; }
|
||||
inline QT_DEPRECATED bool findPrevious(const T &t)
|
||||
{ while (c->constBegin() != i) if (*(n = --i) == t) return true;
|
||||
n = c->end(); return false; }
|
||||
#endif
|
||||
};
|
||||
#endif // QT_NO_JAVA_STYLE_ITERATORS
|
||||
|
||||
|
@ -906,8 +906,6 @@
|
||||
|
||||
Calling this function on QSet<T>::constEnd() leads to
|
||||
undefined results.
|
||||
|
||||
\sa operator--()
|
||||
*/
|
||||
|
||||
/*!
|
||||
@ -924,6 +922,7 @@
|
||||
/*!
|
||||
\fn template <class T> QSet<T>::iterator &QSet<T>::iterator::operator--()
|
||||
\fn template <class T> QSet<T>::const_iterator &QSet<T>::const_iterator::operator--()
|
||||
\obsolete
|
||||
|
||||
The prefix -- operator (\c{--it}) makes the preceding item
|
||||
current and returns an iterator to the new current item.
|
||||
@ -937,6 +936,7 @@
|
||||
/*!
|
||||
\fn template <class T> QSet<T>::iterator QSet<T>::iterator::operator--(int)
|
||||
\fn template <class T> QSet<T>::const_iterator QSet<T>::const_iterator::operator--(int)
|
||||
\obsolete
|
||||
|
||||
\overload
|
||||
|
||||
@ -947,6 +947,7 @@
|
||||
/*!
|
||||
\fn template <class T> QSet<T>::iterator QSet<T>::iterator::operator+(int j) const
|
||||
\fn template <class T> QSet<T>::const_iterator QSet<T>::const_iterator::operator+(int j) const
|
||||
\obsolete
|
||||
|
||||
Returns an iterator to the item at \a j positions forward from
|
||||
this iterator. (If \a j is negative, the iterator goes backward.)
|
||||
@ -959,6 +960,7 @@
|
||||
/*!
|
||||
\fn template <class T> QSet<T>::iterator QSet<T>::iterator::operator-(int j) const
|
||||
\fn template <class T> QSet<T>::const_iterator QSet<T>::const_iterator::operator-(int j) const
|
||||
\obsolete
|
||||
|
||||
Returns an iterator to the item at \a j positions backward from
|
||||
this iterator. (If \a j is negative, the iterator goes forward.)
|
||||
@ -971,6 +973,7 @@
|
||||
/*!
|
||||
\fn template <class T> QSet<T>::iterator &QSet<T>::iterator::operator+=(int j)
|
||||
\fn template <class T> QSet<T>::const_iterator &QSet<T>::const_iterator::operator+=(int j)
|
||||
\obsolete
|
||||
|
||||
Advances the iterator by \a j items. (If \a j is negative, the
|
||||
iterator goes backward.)
|
||||
@ -983,6 +986,7 @@
|
||||
/*!
|
||||
\fn template <class T> QSet<T>::iterator &QSet<T>::iterator::operator-=(int j)
|
||||
\fn template <class T> QSet<T>::const_iterator &QSet<T>::const_iterator::operator-=(int j)
|
||||
\obsolete
|
||||
|
||||
Makes the iterator go back by \a j items. (If \a j is negative,
|
||||
the iterator goes forward.)
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Copyright (C) 2018 Intel Corporation.
|
||||
** Copyright (C) 2019 Intel Corporation.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
@ -188,6 +188,8 @@ static inline quint64 detectProcessorFeatures()
|
||||
# define PICreg "%%rbx"
|
||||
#endif
|
||||
|
||||
static bool checkRdrndWorks() noexcept;
|
||||
|
||||
static int maxBasicCpuidSupported()
|
||||
{
|
||||
#if defined(Q_CC_EMSCRIPTEN)
|
||||
@ -376,37 +378,8 @@ static quint64 detectProcessorFeatures()
|
||||
features &= ~AllAVX512;
|
||||
}
|
||||
|
||||
#if defined(Q_PROCESSOR_X86) && QT_COMPILER_SUPPORTS_HERE(RDRND)
|
||||
/**
|
||||
* Some AMD CPUs (e.g. AMD A4-6250J and AMD Ryzen 3000-series) have a
|
||||
* failing random generation instruction, which always returns
|
||||
* 0xffffffff, even when generation was "successful".
|
||||
*
|
||||
* This code checks if hardware random generator generates four consecutive
|
||||
* equal numbers. If it does, then we probably have a failing one and
|
||||
* should disable it completely.
|
||||
*
|
||||
* https://bugreports.qt.io/browse/QTBUG-69423
|
||||
*/
|
||||
if (features & CpuFeatureRDRND) {
|
||||
const qsizetype testBufferSize = 4;
|
||||
unsigned testBuffer[4] = {};
|
||||
|
||||
const qsizetype generated = qRandomCpu(testBuffer, testBufferSize);
|
||||
|
||||
if (Q_UNLIKELY(generated == testBufferSize &&
|
||||
testBuffer[0] == testBuffer[1] &&
|
||||
testBuffer[1] == testBuffer[2] &&
|
||||
testBuffer[2] == testBuffer[3])) {
|
||||
|
||||
fprintf(stderr, "WARNING: CPU random generator seem to be failing, disable hardware random number generation\n");
|
||||
fprintf(stderr, "WARNING: RDRND generated: 0x%x 0x%x 0x%x 0x%x\n",
|
||||
testBuffer[0], testBuffer[1], testBuffer[2], testBuffer[3]);
|
||||
|
||||
features &= ~CpuFeatureRDRND;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (features & CpuFeatureRDRND && !checkRdrndWorks())
|
||||
features &= ~(CpuFeatureRDRND | CpuFeatureRDSEED);
|
||||
|
||||
return features;
|
||||
}
|
||||
@ -662,15 +635,9 @@ static unsigned *qt_random_rdseed(unsigned *ptr, unsigned *)
|
||||
}
|
||||
# endif
|
||||
|
||||
QT_FUNCTION_TARGET(RDRND) qsizetype qRandomCpu(void *buffer, qsizetype count) noexcept
|
||||
static QT_FUNCTION_TARGET(RDRND) unsigned *qt_random_rdrnd(unsigned *ptr, unsigned *end) noexcept
|
||||
{
|
||||
unsigned *ptr = reinterpret_cast<unsigned *>(buffer);
|
||||
unsigned *end = ptr + count;
|
||||
int retries = 10;
|
||||
|
||||
if (qCpuHasFeature(RDSEED))
|
||||
ptr = qt_random_rdseed(ptr, end);
|
||||
|
||||
while (ptr + sizeof(qregisteruint)/sizeof(*ptr) <= end) {
|
||||
if (_rdrandXX_step(reinterpret_cast<qregisteruint *>(ptr)))
|
||||
ptr += sizeof(qregisteruint)/sizeof(*ptr);
|
||||
@ -688,8 +655,64 @@ QT_FUNCTION_TARGET(RDRND) qsizetype qRandomCpu(void *buffer, qsizetype count) no
|
||||
}
|
||||
|
||||
out:
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static QT_FUNCTION_TARGET(RDRND) Q_DECL_COLD_FUNCTION bool checkRdrndWorks() noexcept
|
||||
{
|
||||
/*
|
||||
* Some AMD CPUs (e.g. AMD A4-6250J and AMD Ryzen 3000-series) have a
|
||||
* failing random generation instruction, which always returns
|
||||
* 0xffffffff, even when generation was "successful".
|
||||
*
|
||||
* This code checks if hardware random generator generates four consecutive
|
||||
* equal numbers. If it does, then we probably have a failing one and
|
||||
* should disable it completely.
|
||||
*
|
||||
* https://bugreports.qt.io/browse/QTBUG-69423
|
||||
*/
|
||||
constexpr qsizetype TestBufferSize = 4;
|
||||
unsigned testBuffer[TestBufferSize] = {};
|
||||
|
||||
unsigned *end = qt_random_rdrnd(testBuffer, testBuffer + TestBufferSize);
|
||||
if (end < testBuffer + 3) {
|
||||
// Random generation didn't produce enough data for us to make a
|
||||
// determination whether it's working or not. Assume it isn't, but
|
||||
// don't print a warning.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the results for equality
|
||||
if (testBuffer[0] == testBuffer[1]
|
||||
&& testBuffer[0] == testBuffer[2]
|
||||
&& end == testBuffer + TestBufferSize && testBuffer[0] == testBuffer[3]) {
|
||||
fprintf(stderr, "WARNING: CPU random generator seem to be failing, "
|
||||
"disabling hardware random number generation\n"
|
||||
"WARNING: RDRND generated:");
|
||||
for (unsigned *ptr = testBuffer; ptr < end; ++ptr)
|
||||
fprintf(stderr, " 0x%x", *ptr);
|
||||
fprintf(stderr, "\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// We're good
|
||||
return true;
|
||||
}
|
||||
|
||||
QT_FUNCTION_TARGET(RDRND) qsizetype qRandomCpu(void *buffer, qsizetype count) noexcept
|
||||
{
|
||||
unsigned *ptr = reinterpret_cast<unsigned *>(buffer);
|
||||
unsigned *end = ptr + count;
|
||||
|
||||
if (qCpuHasFeature(RDSEED))
|
||||
ptr = qt_random_rdseed(ptr, end);
|
||||
|
||||
// fill the buffer with RDRND if RDSEED didn't
|
||||
ptr = qt_random_rdrnd(ptr, end);
|
||||
return ptr - reinterpret_cast<unsigned *>(buffer);
|
||||
}
|
||||
#endif
|
||||
#elif defined(Q_PROCESSOR_X86) && !defined(Q_OS_NACL) && !defined(Q_PROCESSOR_ARM)
|
||||
static bool checkRdrndWorks() noexcept { return false; }
|
||||
#endif // Q_PROCESSOR_X86 && RDRND
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -53,6 +53,8 @@
|
||||
#include <qnetworkinterface.h>
|
||||
#include <qoperatingsystemversion.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
//#define QNATIVESOCKETENGINE_DEBUG
|
||||
#if defined(QNATIVESOCKETENGINE_DEBUG)
|
||||
# include <qstring.h>
|
||||
@ -1141,13 +1143,14 @@ qint64 QNativeSocketEnginePrivate::nativePendingDatagramSize() const
|
||||
qint64 ret = -1;
|
||||
int recvResult = 0;
|
||||
DWORD flags;
|
||||
// We start at 1500 bytes (the MTU for Ethernet V2), which should catch
|
||||
// almost all uses (effective MTU for UDP under IPv4 is 1468), except
|
||||
// for localhost datagrams and those reassembled by the IP layer.
|
||||
char udpMessagePeekBuffer[1500];
|
||||
std::vector<WSABUF> buf;
|
||||
// We increase the amount we peek by 2048 * 5 on each iteration
|
||||
// Grabs most cases fast and early.
|
||||
char udpMessagePeekBuffer[2048];
|
||||
const int increments = 5;
|
||||
QVarLengthArray<WSABUF, 10> buf;
|
||||
for (;;) {
|
||||
buf.resize(buf.size() + 5, {sizeof(udpMessagePeekBuffer), udpMessagePeekBuffer});
|
||||
buf.reserve(buf.size() + increments);
|
||||
std::fill_n(std::back_inserter(buf), increments, WSABUF{sizeof(udpMessagePeekBuffer), udpMessagePeekBuffer});
|
||||
|
||||
flags = MSG_PEEK;
|
||||
DWORD bytesRead = 0;
|
||||
|
@ -248,13 +248,12 @@ static bool ensureValidImage(QImage *dest, struct jpeg_decompress_struct *info,
|
||||
|
||||
static bool read_jpeg_image(QImage *outImage,
|
||||
QSize scaledSize, QRect scaledClipRect,
|
||||
QRect clipRect, volatile int inQuality,
|
||||
QRect clipRect, int quality,
|
||||
Rgb888ToRgb32Converter converter,
|
||||
j_decompress_ptr info, struct my_error_mgr* err )
|
||||
{
|
||||
if (!setjmp(err->setjmp_buffer)) {
|
||||
// -1 means default quality.
|
||||
int quality = inQuality;
|
||||
if (quality < 0)
|
||||
quality = 75;
|
||||
|
||||
@ -529,7 +528,14 @@ static inline void write_icc_profile(const QImage &image, j_compress_ptr cinfo)
|
||||
}
|
||||
}
|
||||
|
||||
static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile int sourceQuality, const QString &description, bool optimize, bool progressive)
|
||||
static bool do_write_jpeg_image(struct jpeg_compress_struct &cinfo,
|
||||
JSAMPROW *row_pointer,
|
||||
const QImage &image,
|
||||
QIODevice *device,
|
||||
int sourceQuality,
|
||||
const QString &description,
|
||||
bool optimize,
|
||||
bool progressive)
|
||||
{
|
||||
bool success = false;
|
||||
const QVector<QRgb> cmap = image.colorTable();
|
||||
@ -537,10 +543,6 @@ static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile in
|
||||
if (image.format() == QImage::Format_Invalid || image.format() == QImage::Format_Alpha8)
|
||||
return false;
|
||||
|
||||
struct jpeg_compress_struct cinfo;
|
||||
JSAMPROW row_pointer[1];
|
||||
row_pointer[0] = 0;
|
||||
|
||||
struct my_jpeg_destination_mgr *iod_dest = new my_jpeg_destination_mgr(device);
|
||||
struct my_error_mgr jerr;
|
||||
|
||||
@ -713,6 +715,27 @@ static bool write_jpeg_image(const QImage &image, QIODevice *device, volatile in
|
||||
}
|
||||
|
||||
delete iod_dest;
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool write_jpeg_image(const QImage &image,
|
||||
QIODevice *device,
|
||||
int sourceQuality,
|
||||
const QString &description,
|
||||
bool optimize,
|
||||
bool progressive)
|
||||
{
|
||||
// protect these objects from the setjmp/longjmp pair inside
|
||||
// do_write_jpeg_image (by making them non-local).
|
||||
struct jpeg_compress_struct cinfo;
|
||||
JSAMPROW row_pointer[1];
|
||||
row_pointer[0] = 0;
|
||||
|
||||
const bool success = do_write_jpeg_image(cinfo, row_pointer,
|
||||
image, device,
|
||||
sourceQuality, description,
|
||||
optimize, progressive);
|
||||
|
||||
delete [] row_pointer[0];
|
||||
return success;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,8 @@
|
||||
TEMPLATE = app
|
||||
TARGET = tst_bench_qudpsocket
|
||||
|
||||
QT = network testlib
|
||||
|
||||
CONFIG += release
|
||||
|
||||
SOURCES += tst_qudpsocket.cpp
|
@ -0,0 +1,80 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/qcoreapplication.h>
|
||||
#include <QtNetwork/qudpsocket.h>
|
||||
#include <QtNetwork/qnetworkdatagram.h>
|
||||
|
||||
class tst_QUdpSocket : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
tst_QUdpSocket();
|
||||
|
||||
private slots:
|
||||
void pendingDatagramSize_data();
|
||||
void pendingDatagramSize();
|
||||
};
|
||||
|
||||
tst_QUdpSocket::tst_QUdpSocket()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QUdpSocket::pendingDatagramSize_data()
|
||||
{
|
||||
QTest::addColumn<int>("size");
|
||||
for (int value : {52, 1024, 2049, 4500, 4098, 8192, 12000, 25000, 32 * 1024, 63 * 1024})
|
||||
QTest::addRow("%d", value) << value;
|
||||
}
|
||||
|
||||
void tst_QUdpSocket::pendingDatagramSize()
|
||||
{
|
||||
QFETCH(int, size);
|
||||
QUdpSocket socket;
|
||||
socket.bind();
|
||||
|
||||
QNetworkDatagram datagram;
|
||||
datagram.setData(QByteArray(size, 'a'));
|
||||
datagram.setDestination(QHostAddress::SpecialAddress::LocalHost, socket.localPort());
|
||||
|
||||
auto sent = socket.writeDatagram(datagram);
|
||||
QCOMPARE(sent, size);
|
||||
|
||||
auto res = QTest::qWaitFor([&socket]() { return socket.hasPendingDatagrams(); }, 5000);
|
||||
QVERIFY(res);
|
||||
|
||||
QBENCHMARK {
|
||||
auto pendingSize = socket.pendingDatagramSize();
|
||||
Q_UNUSED(pendingSize);
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QUdpSocket)
|
||||
#include "tst_qudpsocket.moc"
|
@ -1,3 +1,4 @@
|
||||
TEMPLATE = subdirs
|
||||
SUBDIRS = \
|
||||
qtcpserver
|
||||
qtcpserver \
|
||||
qudpsocket
|
||||
|
Loading…
Reference in New Issue
Block a user