Merge remote-tracking branch 'origin/5.12' into 5.13

Conflicts:
	src/corelib/io/qresource.cpp

Change-Id: I54917f72444a621bd08aeaa15f5d17415993144d
This commit is contained in:
Qt Forward Merge Bot 2019-07-29 01:00:11 +02:00 committed by Edward Welbourne
commit 154155f588
8 changed files with 112 additions and 26 deletions

View File

@ -940,8 +940,10 @@ bool QResourceRoot::mappingRootSubdir(const QString &path, QString *match) const
Q_CORE_EXPORT bool qRegisterResourceData(int version, const unsigned char *tree,
const unsigned char *name, const unsigned char *data)
{
if (resourceGlobalData.isDestroyed())
return false;
QMutexLocker lock(resourceMutex());
if (version >= 0x01 && version <= 0x3 && resourceList()) {
if (version >= 0x01 && version <= 0x3) {
bool found = false;
QResourceRoot res(version, tree, name, data);
for(int i = 0; i < resourceList()->size(); ++i) {
@ -967,7 +969,7 @@ Q_CORE_EXPORT bool qUnregisterResourceData(int version, const unsigned char *tre
return false;
QMutexLocker lock(resourceMutex());
if (version >= 0x01 && version <= 0x3 && resourceList()) {
if (version >= 0x01 && version <= 0x3) {
QResourceRoot res(version, tree, name, data);
for(int i = 0; i < resourceList()->size(); ) {
if(*resourceList()->at(i) == res) {

View File

@ -106,11 +106,39 @@ int get_signal_index()
return signal_index + QMetaObjectPrivate::signalOffset(senderMetaObject);
}
void emit_results_ready(const QHostInfo &hostInfo, const QObject *receiver,
QtPrivate::QSlotObjectBase *slotObj)
}
/*
The calling thread is likely the one that executes the lookup via
QHostInfoRunnable. Unless we operate with a queued connection already,
posts the QHostInfo to a dedicated QHostInfoResult object that lives in
the same thread as the user-provided receiver, or (if there is none) in
the thread that made the call to lookupHost. That QHostInfoResult object
then calls the user code in the correct thread.
The 'result' object deletes itself (via deleteLater) when the metacall
event is received.
*/
void QHostInfoResult::postResultsReady(const QHostInfo &info)
{
// queued connection will take care of dispatching to right thread
if (!slotObj) {
emitResultsReady(info);
return;
}
static const int signal_index = get_signal_index();
// we used to have a context object, but it's already destroyed
if (withContextObject && !receiver)
return;
/* QHostInfoResult c'tor moves the result object to the thread of receiver.
If we don't have a receiver, then the result object will not live in a
thread that runs an event loop - so move it to this' thread, which is the thread
that initiated the lookup, and required to have a running event loop. */
auto result = new QHostInfoResult(receiver, slotObj);
if (!receiver)
result->moveToThread(thread());
Q_CHECK_PTR(result);
const int nargs = 2;
auto types = reinterpret_cast<int *>(malloc(nargs * sizeof(int)));
@ -120,15 +148,13 @@ void emit_results_ready(const QHostInfo &hostInfo, const QObject *receiver,
auto args = reinterpret_cast<void **>(malloc(nargs * sizeof(void *)));
Q_CHECK_PTR(args);
args[0] = 0;
args[1] = QMetaType::create(types[1], &hostInfo);
args[1] = QMetaType::create(types[1], &info);
Q_CHECK_PTR(args[1]);
auto metaCallEvent = new QMetaCallEvent(slotObj, nullptr, signal_index, nargs, types, args);
Q_CHECK_PTR(metaCallEvent);
qApp->postEvent(result, metaCallEvent);
}
}
/*!
\class QHostInfo
\brief The QHostInfo class provides static functions for host name lookups.
@ -316,6 +342,10 @@ int QHostInfo::lookupHost(const QString &name, QObject *receiver,
ready, the \a functor is called with a QHostInfo argument. The
QHostInfo object can then be inspected to get the results of the
lookup.
The \a functor will be run in the thread that makes the call to lookupHost;
that thread must have a running Qt event loop.
\note There is no guarantee on the order the signals will be emitted
if you start multiple requests with lookupHost().
@ -623,7 +653,8 @@ int QHostInfo::lookupHostImpl(const QString &name,
QHostInfo hostInfo(id);
hostInfo.setError(QHostInfo::HostNotFound);
hostInfo.setErrorString(QCoreApplication::translate("QHostInfo", "No host name given"));
emit_results_ready(hostInfo, receiver, slotObj);
QHostInfoResult result(receiver, slotObj);
result.postResultsReady(hostInfo);
return id;
}
@ -637,7 +668,8 @@ int QHostInfo::lookupHostImpl(const QString &name,
QHostInfo info = manager->cache.get(name, &valid);
if (valid) {
info.setLookupId(id);
emit_results_ready(info, receiver, slotObj);
QHostInfoResult result(receiver, slotObj);
result.postResultsReady(info);
return id;
}
}
@ -698,7 +730,7 @@ void QHostInfoRunnable::run()
// signal emission
hostInfo.setLookupId(id);
resultEmitter.emitResultsReady(hostInfo);
resultEmitter.postResultsReady(hostInfo);
#if QT_CONFIG(thread)
// now also iterate through the postponed ones
@ -711,7 +743,7 @@ void QHostInfoRunnable::run()
QHostInfoRunnable* postponed = *it;
// we can now emit
hostInfo.setLookupId(postponed->id);
postponed->resultEmitter.emitResultsReady(hostInfo);
postponed->resultEmitter.postResultsReady(hostInfo);
delete postponed;
}
manager->postponedLookups.erase(partitionBegin, partitionEnd);

View File

@ -84,12 +84,14 @@ class QHostInfoResult : public QObject
QPointer<const QObject> receiver = nullptr;
QtPrivate::QSlotObjectBase *slotObj = nullptr;
const bool withContextObject = false;
public:
QHostInfoResult() = default;
QHostInfoResult(const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj) :
receiver(receiver),
slotObj(slotObj)
slotObj(slotObj),
withContextObject(slotObj && receiver)
{
connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this,
&QObject::deleteLater);
@ -97,10 +99,15 @@ public:
moveToThread(receiver->thread());
}
void postResultsReady(const QHostInfo &info);
public Q_SLOTS:
inline void emitResultsReady(const QHostInfo &info)
{
if (slotObj) {
// we used to have a context object, but it's already destroyed
if (withContextObject && !receiver)
return;
QHostInfo copy = info;
void *args[2] = { 0, reinterpret_cast<void *>(&copy) };
slotObj->call(const_cast<QObject*>(receiver.data()), args);

View File

@ -878,8 +878,25 @@ static QPair<QLibrary*, QLibrary*> loadOpenSsl()
// macOS's /usr/lib/libssl.dylib, /usr/lib/libcrypto.dylib will be picked up in the third
// attempt, _after_ <bundle>/Contents/Frameworks has been searched.
// iOS does not ship a system libssl.dylib, libcrypto.dylib in the first place.
# if defined(Q_OS_ANDROID)
// OpenSSL 1.1.x must be suffixed otherwise it will use the system libcrypto.so libssl.so which on API-21 are OpenSSL 1.0 not 1.1
auto openSSLSuffix = [](const QByteArray &defaultSuffix = {}) {
auto suffix = qgetenv("ANDROID_OPENSSL_SUFFIX");
if (suffix.isEmpty())
return defaultSuffix;
return suffix;
};
# if QT_CONFIG(opensslv11)
static QString suffix = QString::fromLatin1(openSSLSuffix("_1_1"));
# else
static QString suffix = QString::fromLatin1(openSSLSuffix());
# endif
libssl->setFileNameAndVersion(QLatin1String("ssl") + suffix, -1);
libcrypto->setFileNameAndVersion(QLatin1String("crypto") + suffix, -1);
# else
libssl->setFileNameAndVersion(QLatin1String("ssl"), -1);
libcrypto->setFileNameAndVersion(QLatin1String("crypto"), -1);
# endif
if (libcrypto->load() && libssl->load()) {
// libssl.so.0 and libcrypto.so.0 found
return pair;

View File

@ -49,7 +49,14 @@
QT_BEGIN_NAMESPACE
class QNSWindowBackingStore : public QRasterBackingStore
class QCocoaBackingStore : public QRasterBackingStore
{
protected:
QCocoaBackingStore(QWindow *window);
QCFType<CGColorSpaceRef> colorSpace() const;
};
class QNSWindowBackingStore : public QCocoaBackingStore
{
public:
QNSWindowBackingStore(QWindow *window);
@ -64,7 +71,7 @@ private:
void redrawRoundedBottomCorners(CGRect) const;
};
class QCALayerBackingStore : public QPlatformBackingStore
class QCALayerBackingStore : public QCocoaBackingStore
{
public:
QCALayerBackingStore(QWindow *window);

View File

@ -48,11 +48,24 @@
QT_BEGIN_NAMESPACE
QNSWindowBackingStore::QNSWindowBackingStore(QWindow *window)
QCocoaBackingStore::QCocoaBackingStore(QWindow *window)
: QRasterBackingStore(window)
{
}
QCFType<CGColorSpaceRef> QCocoaBackingStore::colorSpace() const
{
NSView *view = static_cast<QCocoaWindow *>(window()->handle())->view();
return QCFType<CGColorSpaceRef>::constructFromGet(view.window.colorSpace.CGColorSpace);
}
// ----------------------------------------------------------------------------
QNSWindowBackingStore::QNSWindowBackingStore(QWindow *window)
: QCocoaBackingStore(window)
{
}
QNSWindowBackingStore::~QNSWindowBackingStore()
{
}
@ -175,11 +188,10 @@ void QNSWindowBackingStore::flush(QWindow *window, const QRegion &region, const
Q_ASSERT_X(graphicsContext, "QCocoaBackingStore",
"Focusing the view should give us a current graphics context");
// Prevent potentially costly color conversion by assigning the display color space
// to the backingstore image. This does not copy the underlying image data.
CGColorSpaceRef displayColorSpace = view.window.screen.colorSpace.CGColorSpace;
// Tag backingstore image with color space based on the window.
// Note: This does not copy the underlying image data.
QCFType<CGImageRef> cgImage = CGImageCreateCopyWithColorSpace(
QCFType<CGImageRef>(m_image.toCGImage()), displayColorSpace);
QCFType<CGImageRef>(m_image.toCGImage()), colorSpace());
// Create temporary image to use for blitting, without copying image data
NSImage *backingStoreImage = [[[NSImage alloc] initWithCGImage:cgImage size:NSZeroSize] autorelease];
@ -293,7 +305,7 @@ void QNSWindowBackingStore::redrawRoundedBottomCorners(CGRect windowRect) const
// ----------------------------------------------------------------------------
QCALayerBackingStore::QCALayerBackingStore(QWindow *window)
: QPlatformBackingStore(window)
: QCocoaBackingStore(window)
{
qCDebug(lcQpaBackingStore) << "Creating QCALayerBackingStore for" << window;
m_buffers.resize(1);
@ -432,11 +444,7 @@ bool QCALayerBackingStore::recreateBackBufferIfNeeded()
<< "based on requested" << m_requestedSize << "and dpr =" << devicePixelRatio;
static auto pixelFormat = QImage::toPixelFormat(QImage::Format_ARGB32_Premultiplied);
NSView *view = static_cast<QCocoaWindow *>(window()->handle())->view();
auto colorSpace = QCFType<CGColorSpaceRef>::constructFromGet(view.window.screen.colorSpace.CGColorSpace);
m_buffers.back().reset(new GraphicsBuffer(requestedBufferSize, devicePixelRatio, pixelFormat, colorSpace));
m_buffers.back().reset(new GraphicsBuffer(requestedBufferSize, devicePixelRatio, pixelFormat, colorSpace()));
return true;
}

View File

@ -5362,10 +5362,10 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
const CGRect barRect = [cell barRectFlipped:hasTicks];
if (drawBar) {
[cell drawBarInside:barRect flipped:!verticalFlip];
// This ain't HIG kosher: force unfilled bar look.
if (hasDoubleTicks)
slider.numberOfTickMarks = numberOfTickMarks;
[cell drawBarInside:barRect flipped:!verticalFlip];
}
if (hasTicks && drawTicks) {

View File

@ -92,6 +92,7 @@ private slots:
void lookupIPv6();
void lookupConnectToFunctionPointer_data();
void lookupConnectToFunctionPointer();
void lookupConnectToFunctionPointerDeleted();
void lookupConnectToLambda_data();
void lookupConnectToLambda();
void reverseLookup_data();
@ -361,6 +362,17 @@ void tst_QHostInfo::lookupConnectToFunctionPointer()
QCOMPARE(tmp.join(' '), expected.join(' '));
}
void tst_QHostInfo::lookupConnectToFunctionPointerDeleted()
{
{
QObject contextObject;
QHostInfo::lookupHost("localhost", &contextObject, [](const QHostInfo){
QFAIL("This should never be called!");
});
}
QTestEventLoop::instance().enterLoop(3);
}
void tst_QHostInfo::lookupConnectToLambda_data()
{
lookupIPv4_data();
@ -708,6 +720,7 @@ void tst_QHostInfo::cache()
void tst_QHostInfo::resultsReady(const QHostInfo &hi)
{
QVERIFY(QThread::currentThread() == thread());
lookupDone = true;
lookupResults = hi;
lookupsDoneCounter++;