Merge remote-tracking branch 'origin/5.9' into 5.10
Change-Id: Iede384644c3df5ee01b701806dfdb586dd6bb138
This commit is contained in:
commit
1139be7b30
144
dist/changes-5.9.3
vendored
Normal file
144
dist/changes-5.9.3
vendored
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
Qt 5.9.3 is a bug-fix release. It maintains both forward and backward
|
||||||
|
compatibility (source and binary) with Qt 5.9.0 through 5.9.2.
|
||||||
|
|
||||||
|
For more details, refer to the online documentation included in this
|
||||||
|
distribution. The documentation is also available online:
|
||||||
|
|
||||||
|
http://doc.qt.io/qt-5/index.html
|
||||||
|
|
||||||
|
The Qt version 5.9 series is binary compatible with the 5.8.x series.
|
||||||
|
Applications compiled for 5.8 will continue to run with 5.9.
|
||||||
|
|
||||||
|
Some of the changes listed in this file include issue tracking numbers
|
||||||
|
corresponding to tasks in the Qt Bug Tracker:
|
||||||
|
|
||||||
|
https://bugreports.qt.io/
|
||||||
|
|
||||||
|
Each of these identifiers can be entered in the bug tracker to obtain more
|
||||||
|
information about a particular change.
|
||||||
|
|
||||||
|
****************************************************************************
|
||||||
|
* Qt 5.9.3 Changes *
|
||||||
|
****************************************************************************
|
||||||
|
|
||||||
|
QtCore
|
||||||
|
------
|
||||||
|
|
||||||
|
- QFileSystemWatcher:
|
||||||
|
* [QTBUG-64171] Fixed a bug that would cause the application to crash if
|
||||||
|
QFileSystemWatcher was created in an auxiliary thread on Windows.
|
||||||
|
|
||||||
|
- QStorageInfo:
|
||||||
|
* [QTBUG-61420] Fixed decoding of volume labels containing certain
|
||||||
|
uncommon characters on Linux.
|
||||||
|
|
||||||
|
- QThreadPool:
|
||||||
|
* Improved performance with large amount of QRunnable items.
|
||||||
|
|
||||||
|
QtGui
|
||||||
|
------
|
||||||
|
|
||||||
|
- [QTBUG-64239] Fixed memory corruption on scaled emojis.
|
||||||
|
- [QTBUG-63846] Fixed dragging inside a modal window when a
|
||||||
|
QShapedPixmapWindow is used.
|
||||||
|
- [QTBUG-61777] Fixed painting of zero-length lines with scaling.
|
||||||
|
- [QTBUG-61244] Fixed centering of some items in layouts.
|
||||||
|
- [QTBUG-63168] Fixed a crash when reparenting QWindowContainer.
|
||||||
|
|
||||||
|
|
||||||
|
QtNetwork
|
||||||
|
---------
|
||||||
|
|
||||||
|
- QHostAddress:
|
||||||
|
* [QTBUG-63764] Fixed a problem in QHostAddress not detaching in its
|
||||||
|
setters and thus spoiling shared data.
|
||||||
|
|
||||||
|
- QNetworkAccessManager:
|
||||||
|
* [QTBUG-63075] Added support for HTTP status 308.
|
||||||
|
* [QTBUG-61300] Fixed a problem with mixing headers from different
|
||||||
|
responses.
|
||||||
|
* [QTBUG-63471] Fixed redirects support in HTTP/2 protocol handler.
|
||||||
|
* [QTBUG-63313] Fixed cookies received during a redirect not being
|
||||||
|
applied in the redirect.
|
||||||
|
* [QTBUG-63142] Fixed HTTP method always being changed to GET when
|
||||||
|
redirected with 307 and 308.
|
||||||
|
|
||||||
|
- QNetworkCookieJar:
|
||||||
|
* Fixed cookies with a root path ("/") not matching an empty path ("").
|
||||||
|
|
||||||
|
QtSql
|
||||||
|
------
|
||||||
|
|
||||||
|
- PostgreSQL:
|
||||||
|
* Fixed handling of binary data for PostgreSQL 9.x and later
|
||||||
|
* Fixed detection of PostgreSQL 9.x and later
|
||||||
|
|
||||||
|
- OCI:
|
||||||
|
* [QTBUG-57765] Fixed a bug that would see some cached results returned
|
||||||
|
when issuing a forward only query
|
||||||
|
|
||||||
|
QtWidgets
|
||||||
|
---------
|
||||||
|
|
||||||
|
- QAction:
|
||||||
|
* [QTBUG-62006] Ensured setData() does not emit changed() if no change
|
||||||
|
happened.
|
||||||
|
|
||||||
|
- QDockWidget:
|
||||||
|
* [QTBUG-63526] Fixed an issue in QDockWidgets where the widget would
|
||||||
|
not resize despite showing a resize cursor.
|
||||||
|
|
||||||
|
- QHeaderView:
|
||||||
|
* [QTBUG-54601] Fixed resizing when hidden sections were involved.
|
||||||
|
* [QTBUG-64036] Ensured maximumSectionSize property is honored during
|
||||||
|
resizeSections().
|
||||||
|
|
||||||
|
- QListView:
|
||||||
|
* [QTBUG-45427] Fixed the laying out of a QListView in a grid layout
|
||||||
|
after the dataChanged() signal is emitted.
|
||||||
|
|
||||||
|
- QMenuBar
|
||||||
|
* [QTBUG-34160] Fixed a problem with adding the same QAction to more than
|
||||||
|
one menu.
|
||||||
|
|
||||||
|
- QWidget
|
||||||
|
* [QTBUG-56860] Fixed widget losing focus after showing menu second time.
|
||||||
|
|
||||||
|
- QWizard:
|
||||||
|
* [QTBUG-46894] Fixed the shortcut for the Next button on Windows.
|
||||||
|
|
||||||
|
|
||||||
|
Platform-specific changes
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
- Cocoa:
|
||||||
|
* optimize backingstore flush on 10-bit displays
|
||||||
|
* [QTBUG-57076] [QTBUG-63712] Attach menu items when updating the menubar
|
||||||
|
* [QTBUG-63444] Toggle titlebar transparency to support unified toolbar
|
||||||
|
|
||||||
|
- iOS:
|
||||||
|
* [QTBUG-57428][QTBUG-63660] add support for adding mimetypes other than text
|
||||||
|
on the clipboard
|
||||||
|
|
||||||
|
- Windows:
|
||||||
|
* [QTBUG-63654] Windows font database: Remove clamping of default font size
|
||||||
|
|
||||||
|
- X11:
|
||||||
|
* [QTBUG-48034] Don't misdetect certain trackballs as tablets
|
||||||
|
* [QTBUG-62840] Fix crash on X servers with BGR888 display
|
||||||
|
|
||||||
|
Third-Party Code
|
||||||
|
----------------
|
||||||
|
|
||||||
|
- Improved documentation about Freetype 2 licenses.
|
||||||
|
- Updated Sqlite to fix CVE-2017-10989.
|
||||||
|
- Updated bundled libpng to version 1.6.34.
|
||||||
|
|
||||||
|
Tools
|
||||||
|
-----
|
||||||
|
|
||||||
|
* qmake:
|
||||||
|
- [QTBUG-63409] Fixed a build error with MSVC when concrt.h was included
|
||||||
|
while exceptions are disabled.
|
||||||
|
- [QTBUG-62985] Fixed a bug that caused the accidental creation of files
|
||||||
|
called "NUL" when using MinGW.
|
@ -723,184 +723,189 @@ public class QtActivityDelegate
|
|||||||
|
|
||||||
Bundle extras = m_activity.getIntent().getExtras();
|
Bundle extras = m_activity.getIntent().getExtras();
|
||||||
if (extras != null) {
|
if (extras != null) {
|
||||||
if ( /*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0
|
try {
|
||||||
&&*/ extras.containsKey("debug_ping")
|
final String dc = "--Added-by-androiddeployqt--/debugger.command";
|
||||||
&& extras.getString("debug_ping").equals("true")) {
|
String debuggerCommand =
|
||||||
try {
|
new BufferedReader(new InputStreamReader(m_activity.getAssets().open(dc))).readLine();
|
||||||
final String dc = "--Added-by-androiddeployqt--/debugger.command";
|
if ( /*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0
|
||||||
String debuggerCommand =
|
&&*/ extras.containsKey("debug_ping")
|
||||||
new BufferedReader(new InputStreamReader(m_activity.getAssets().open(dc))).readLine();
|
&& extras.getString("debug_ping").equals("true")) {
|
||||||
String packagePath =
|
try {
|
||||||
m_activity.getPackageManager().getApplicationInfo(m_activity.getPackageName(),
|
String packagePath =
|
||||||
PackageManager.GET_CONFIGURATIONS).dataDir + "/";
|
m_activity.getPackageManager().getApplicationInfo(m_activity.getPackageName(),
|
||||||
|
PackageManager.GET_CONFIGURATIONS).dataDir + "/";
|
||||||
|
|
||||||
debugLog("extra parameters: " + extras);
|
debugLog("extra parameters: " + extras);
|
||||||
String packageName = m_activity.getPackageName();
|
String packageName = m_activity.getPackageName();
|
||||||
String pingFile = extras.getString("ping_file");
|
String pingFile = extras.getString("ping_file");
|
||||||
String pongFile = extras.getString("pong_file");
|
String pongFile = extras.getString("pong_file");
|
||||||
String gdbserverSocket = extras.getString("gdbserver_socket");
|
String gdbserverSocket = extras.getString("gdbserver_socket");
|
||||||
String gdbserverCommand = packagePath + debuggerCommand + gdbserverSocket;
|
String gdbserverCommand = packagePath + debuggerCommand + gdbserverSocket;
|
||||||
String pingSocket = extras.getString("ping_socket");
|
String pingSocket = extras.getString("ping_socket");
|
||||||
boolean usePing = pingFile != null;
|
boolean usePing = pingFile != null;
|
||||||
boolean usePong = pongFile != null;
|
boolean usePong = pongFile != null;
|
||||||
boolean useSocket = gdbserverSocket != null;
|
boolean useSocket = gdbserverSocket != null;
|
||||||
boolean usePingSocket = pingSocket != null;
|
boolean usePingSocket = pingSocket != null;
|
||||||
int napTime = 200; // milliseconds between file accesses
|
int napTime = 200; // milliseconds between file accesses
|
||||||
int timeOut = 30000; // ms until we give up on ping and pong
|
int timeOut = 30000; // ms until we give up on ping and pong
|
||||||
int maxAttempts = timeOut / napTime;
|
int maxAttempts = timeOut / napTime;
|
||||||
|
|
||||||
if (gdbserverSocket != null) {
|
if (gdbserverSocket != null) {
|
||||||
debugLog("removing gdb socket " + gdbserverSocket);
|
debugLog("removing gdb socket " + gdbserverSocket);
|
||||||
new File(gdbserverSocket).delete();
|
new File(gdbserverSocket).delete();
|
||||||
}
|
|
||||||
|
|
||||||
if (usePing) {
|
|
||||||
debugLog("removing ping file " + pingFile);
|
|
||||||
File ping = new File(pingFile);
|
|
||||||
if (ping.exists()) {
|
|
||||||
if (!ping.delete())
|
|
||||||
debugLog("ping file cannot be deleted");
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (usePong) {
|
if (usePing) {
|
||||||
debugLog("removing pong file " + pongFile);
|
debugLog("removing ping file " + pingFile);
|
||||||
File pong = new File(pongFile);
|
File ping = new File(pingFile);
|
||||||
if (pong.exists()) {
|
if (ping.exists()) {
|
||||||
if (!pong.delete())
|
if (!ping.delete())
|
||||||
debugLog("pong file cannot be deleted");
|
debugLog("ping file cannot be deleted");
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
debugLog("starting " + gdbserverCommand);
|
|
||||||
m_debuggerProcess = Runtime.getRuntime().exec(gdbserverCommand);
|
|
||||||
debugLog("gdbserver started");
|
|
||||||
|
|
||||||
if (useSocket) {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < maxAttempts; ++i) {
|
|
||||||
debugLog("waiting for socket at " + gdbserverSocket + ", attempt " + i);
|
|
||||||
File file = new File(gdbserverSocket);
|
|
||||||
if (file.exists()) {
|
|
||||||
file.setReadable(true, false);
|
|
||||||
file.setWritable(true, false);
|
|
||||||
file.setExecutable(true, false);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
Thread.sleep(napTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == maxAttempts) {
|
if (usePong) {
|
||||||
debugLog("time out when waiting for debug socket");
|
debugLog("removing pong file " + pongFile);
|
||||||
return false;
|
File pong = new File(pongFile);
|
||||||
|
if (pong.exists()) {
|
||||||
|
if (!pong.delete())
|
||||||
|
debugLog("pong file cannot be deleted");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debugLog("socket ok");
|
debugLog("starting " + gdbserverCommand);
|
||||||
} else {
|
m_debuggerProcess = Runtime.getRuntime().exec(gdbserverCommand);
|
||||||
debugLog("socket not used");
|
debugLog("gdbserver started");
|
||||||
}
|
|
||||||
|
|
||||||
if (usePingSocket) {
|
if (useSocket) {
|
||||||
DebugWaitRunnable runnable = new DebugWaitRunnable(pingSocket);
|
int i;
|
||||||
Thread waitThread = new Thread(runnable);
|
for (i = 0; i < maxAttempts; ++i) {
|
||||||
waitThread.start();
|
debugLog("waiting for socket at " + gdbserverSocket + ", attempt " + i);
|
||||||
|
File file = new File(gdbserverSocket);
|
||||||
|
if (file.exists()) {
|
||||||
|
file.setReadable(true, false);
|
||||||
|
file.setWritable(true, false);
|
||||||
|
file.setExecutable(true, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Thread.sleep(napTime);
|
||||||
|
}
|
||||||
|
|
||||||
int i;
|
if (i == maxAttempts) {
|
||||||
for (i = 0; i < maxAttempts && waitThread.isAlive(); ++i) {
|
debugLog("time out when waiting for debug socket");
|
||||||
debugLog("Waiting for debug socket connect");
|
return false;
|
||||||
debugLog("go to sleep");
|
}
|
||||||
Thread.sleep(napTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == maxAttempts) {
|
debugLog("socket ok");
|
||||||
debugLog("time out when waiting for ping socket");
|
|
||||||
runnable.shutdown();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (runnable.wasFailure) {
|
|
||||||
debugLog("Could not connect to debug client");
|
|
||||||
return false;
|
|
||||||
} else {
|
} else {
|
||||||
debugLog("Got pid acknowledgment");
|
debugLog("socket not used");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (usePing) {
|
if (usePingSocket) {
|
||||||
// Tell we are ready.
|
DebugWaitRunnable runnable = new DebugWaitRunnable(pingSocket);
|
||||||
debugLog("writing ping at " + pingFile);
|
Thread waitThread = new Thread(runnable);
|
||||||
FileWriter writer = new FileWriter(pingFile);
|
waitThread.start();
|
||||||
writer.write("" + android.os.Process.myPid());
|
|
||||||
writer.close();
|
|
||||||
File file = new File(pingFile);
|
|
||||||
file.setReadable(true, false);
|
|
||||||
file.setWritable(true, false);
|
|
||||||
file.setExecutable(true, false);
|
|
||||||
debugLog("wrote ping");
|
|
||||||
} else {
|
|
||||||
debugLog("ping not requested");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait until other side is ready.
|
int i;
|
||||||
if (usePong) {
|
for (i = 0; i < maxAttempts && waitThread.isAlive(); ++i) {
|
||||||
int i;
|
debugLog("Waiting for debug socket connect");
|
||||||
for (i = 0; i < maxAttempts; ++i) {
|
debugLog("go to sleep");
|
||||||
debugLog("waiting for pong at " + pongFile + ", attempt " + i);
|
Thread.sleep(napTime);
|
||||||
File file = new File(pongFile);
|
|
||||||
if (file.exists()) {
|
|
||||||
file.delete();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
debugLog("go to sleep");
|
|
||||||
Thread.sleep(napTime);
|
|
||||||
}
|
|
||||||
debugLog("Removing pingFile " + pingFile);
|
|
||||||
new File(pingFile).delete();
|
|
||||||
|
|
||||||
if (i == maxAttempts) {
|
if (i == maxAttempts) {
|
||||||
debugLog("time out when waiting for pong file");
|
debugLog("time out when waiting for ping socket");
|
||||||
return false;
|
runnable.shutdown();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runnable.wasFailure) {
|
||||||
|
debugLog("Could not connect to debug client");
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
debugLog("Got pid acknowledgment");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debugLog("got pong " + pongFile);
|
if (usePing) {
|
||||||
} else {
|
// Tell we are ready.
|
||||||
debugLog("pong not requested");
|
debugLog("writing ping at " + pingFile);
|
||||||
|
FileWriter writer = new FileWriter(pingFile);
|
||||||
|
writer.write("" + android.os.Process.myPid());
|
||||||
|
writer.close();
|
||||||
|
File file = new File(pingFile);
|
||||||
|
file.setReadable(true, false);
|
||||||
|
file.setWritable(true, false);
|
||||||
|
file.setExecutable(true, false);
|
||||||
|
debugLog("wrote ping");
|
||||||
|
} else {
|
||||||
|
debugLog("ping not requested");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait until other side is ready.
|
||||||
|
if (usePong) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < maxAttempts; ++i) {
|
||||||
|
debugLog("waiting for pong at " + pongFile + ", attempt " + i);
|
||||||
|
File file = new File(pongFile);
|
||||||
|
if (file.exists()) {
|
||||||
|
file.delete();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
debugLog("go to sleep");
|
||||||
|
Thread.sleep(napTime);
|
||||||
|
}
|
||||||
|
debugLog("Removing pingFile " + pingFile);
|
||||||
|
new File(pingFile).delete();
|
||||||
|
|
||||||
|
if (i == maxAttempts) {
|
||||||
|
debugLog("time out when waiting for pong file");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
debugLog("got pong " + pongFile);
|
||||||
|
} else {
|
||||||
|
debugLog("pong not requested");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
ioe.printStackTrace();
|
||||||
|
} catch (SecurityException se) {
|
||||||
|
se.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
ioe.printStackTrace();
|
|
||||||
} catch (SecurityException se) {
|
|
||||||
se.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (/*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0
|
if (/*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0
|
||||||
&&*/ extras.containsKey("qml_debug")
|
&&*/ extras.containsKey("qml_debug")
|
||||||
&& extras.getString("qml_debug").equals("true")) {
|
&& extras.getString("qml_debug").equals("true")) {
|
||||||
String qmljsdebugger;
|
String qmljsdebugger;
|
||||||
if (extras.containsKey("qmljsdebugger")) {
|
if (extras.containsKey("qmljsdebugger")) {
|
||||||
qmljsdebugger = extras.getString("qmljsdebugger");
|
qmljsdebugger = extras.getString("qmljsdebugger");
|
||||||
qmljsdebugger.replaceAll("\\s", ""); // remove whitespace for security
|
qmljsdebugger.replaceAll("\\s", ""); // remove whitespace for security
|
||||||
} else {
|
} else {
|
||||||
qmljsdebugger = "port:3768";
|
qmljsdebugger = "port:3768";
|
||||||
|
}
|
||||||
|
m_applicationParameters += "\t-qmljsdebugger=" + qmljsdebugger;
|
||||||
}
|
}
|
||||||
m_applicationParameters += "\t-qmljsdebugger=" + qmljsdebugger;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (extras.containsKey("extraenvvars")) {
|
if (extras.containsKey("extraenvvars")) {
|
||||||
try {
|
try {
|
||||||
m_environmentVariables += "\t" + new String(Base64.decode(extras.getString("extraenvvars"), Base64.DEFAULT), "UTF-8");
|
m_environmentVariables += "\t" + new String(Base64.decode(extras.getString("extraenvvars"), Base64.DEFAULT), "UTF-8");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (extras.containsKey("extraappparams")) {
|
if (extras.containsKey("extraappparams")) {
|
||||||
try {
|
try {
|
||||||
m_applicationParameters += "\t" + new String(Base64.decode(extras.getString("extraappparams"), Base64.DEFAULT), "UTF-8");
|
m_applicationParameters += "\t" + new String(Base64.decode(extras.getString("extraappparams"), Base64.DEFAULT), "UTF-8");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// This is not an error, so keep it silent
|
||||||
|
// e.printStackTrace();
|
||||||
}
|
}
|
||||||
} // extras != null
|
} // extras != null
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ public:
|
|||||||
Q_DECL_CONSTEXPR inline bool testFlag(Enum f) const Q_DECL_NOTHROW { return (i & Int(f)) == Int(f) && (Int(f) != 0 || i == Int(f) ); }
|
Q_DECL_CONSTEXPR inline bool testFlag(Enum f) const Q_DECL_NOTHROW { return (i & Int(f)) == Int(f) && (Int(f) != 0 || i == Int(f) ); }
|
||||||
Q_DECL_RELAXED_CONSTEXPR inline QFlags &setFlag(Enum f, bool on = true) Q_DECL_NOTHROW
|
Q_DECL_RELAXED_CONSTEXPR inline QFlags &setFlag(Enum f, bool on = true) Q_DECL_NOTHROW
|
||||||
{
|
{
|
||||||
return on ? (*this |= f) : (*this &= ~f);
|
return on ? (*this |= f) : (*this &= ~Int(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -255,6 +255,7 @@ void QLoggingSettingsParser::parseNextLine(QStringRef line)
|
|||||||
QLoggingRegistry::QLoggingRegistry()
|
QLoggingRegistry::QLoggingRegistry()
|
||||||
: categoryFilter(defaultCategoryFilter)
|
: categoryFilter(defaultCategoryFilter)
|
||||||
{
|
{
|
||||||
|
initalizeRules(); // Init on first use
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool qtLoggingDebug()
|
static bool qtLoggingDebug()
|
||||||
@ -283,7 +284,7 @@ static QVector<QLoggingRule> loadRulesFromFile(const QString &filePath)
|
|||||||
Initializes the rules database by loading
|
Initializes the rules database by loading
|
||||||
$QT_LOGGING_CONF, $QT_LOGGING_RULES, and .config/QtProject/qtlogging.ini.
|
$QT_LOGGING_CONF, $QT_LOGGING_RULES, and .config/QtProject/qtlogging.ini.
|
||||||
*/
|
*/
|
||||||
void QLoggingRegistry::init()
|
void QLoggingRegistry::initalizeRules()
|
||||||
{
|
{
|
||||||
QVector<QLoggingRule> er, qr, cr;
|
QVector<QLoggingRule> er, qr, cr;
|
||||||
// get rules from environment
|
// get rules from environment
|
||||||
|
@ -113,7 +113,7 @@ class Q_AUTOTEST_EXPORT QLoggingRegistry
|
|||||||
public:
|
public:
|
||||||
QLoggingRegistry();
|
QLoggingRegistry();
|
||||||
|
|
||||||
void init();
|
void initalizeRules();
|
||||||
|
|
||||||
void registerCategory(QLoggingCategory *category, QtMsgType enableForLevel);
|
void registerCategory(QLoggingCategory *category, QtMsgType enableForLevel);
|
||||||
void unregisterCategory(QLoggingCategory *category);
|
void unregisterCategory(QLoggingCategory *category);
|
||||||
|
@ -802,8 +802,6 @@ void QCoreApplicationPrivate::init()
|
|||||||
if (!coreappdata()->applicationVersionSet)
|
if (!coreappdata()->applicationVersionSet)
|
||||||
coreappdata()->applicationVersion = appVersion();
|
coreappdata()->applicationVersion = appVersion();
|
||||||
|
|
||||||
QLoggingRegistry::instance()->init();
|
|
||||||
|
|
||||||
#if QT_CONFIG(library)
|
#if QT_CONFIG(library)
|
||||||
// Reset the lib paths, so that they will be recomputed, taking the availability of argv[0]
|
// Reset the lib paths, so that they will be recomputed, taking the availability of argv[0]
|
||||||
// into account. If necessary, recompute right away and replay the manual changes on top of the
|
// into account. If necessary, recompute right away and replay the manual changes on top of the
|
||||||
|
@ -217,13 +217,15 @@ bool QSemaphore::tryAcquire(int n)
|
|||||||
bool QSemaphore::tryAcquire(int n, int timeout)
|
bool QSemaphore::tryAcquire(int n, int timeout)
|
||||||
{
|
{
|
||||||
Q_ASSERT_X(n >= 0, "QSemaphore::tryAcquire", "parameter 'n' must be non-negative");
|
Q_ASSERT_X(n >= 0, "QSemaphore::tryAcquire", "parameter 'n' must be non-negative");
|
||||||
if (timeout < 0)
|
|
||||||
return tryAcquire(n);
|
// We're documented to accept any negative value as "forever"
|
||||||
|
// but QDeadlineTimer only accepts -1.
|
||||||
|
timeout = qMax(timeout, -1);
|
||||||
|
|
||||||
QDeadlineTimer timer(timeout);
|
QDeadlineTimer timer(timeout);
|
||||||
QMutexLocker locker(&d->mutex);
|
QMutexLocker locker(&d->mutex);
|
||||||
qint64 remainingTime = timer.remainingTime();
|
qint64 remainingTime = timer.remainingTime();
|
||||||
while (n > d->avail && remainingTime > 0) {
|
while (n > d->avail && remainingTime != 0) {
|
||||||
if (!d->cond.wait(locker.mutex(), remainingTime))
|
if (!d->cond.wait(locker.mutex(), remainingTime))
|
||||||
return false;
|
return false;
|
||||||
remainingTime = timer.remainingTime();
|
remainingTime = timer.remainingTime();
|
||||||
|
@ -1231,20 +1231,20 @@ void QHttpNetworkConnectionPrivate::_q_hostLookupFinished(const QHostInfo &info)
|
|||||||
if (dequeueRequest(channels[0].socket)) {
|
if (dequeueRequest(channels[0].socket)) {
|
||||||
emitReplyError(channels[0].socket, channels[0].reply, QNetworkReply::HostNotFoundError);
|
emitReplyError(channels[0].socket, channels[0].reply, QNetworkReply::HostNotFoundError);
|
||||||
networkLayerState = QHttpNetworkConnectionPrivate::Unknown;
|
networkLayerState = QHttpNetworkConnectionPrivate::Unknown;
|
||||||
}
|
} else if (connectionType == QHttpNetworkConnection::ConnectionTypeSPDY
|
||||||
#ifndef QT_NO_SSL
|
|| connectionType == QHttpNetworkConnection::ConnectionTypeHTTP2) {
|
||||||
else if (connectionType == QHttpNetworkConnection::ConnectionTypeSPDY) {
|
|
||||||
for (const HttpMessagePair &spdyPair : qAsConst(channels[0].spdyRequestsToSend)) {
|
for (const HttpMessagePair &spdyPair : qAsConst(channels[0].spdyRequestsToSend)) {
|
||||||
// emit error for all replies
|
// emit error for all replies
|
||||||
QHttpNetworkReply *currentReply = spdyPair.second;
|
QHttpNetworkReply *currentReply = spdyPair.second;
|
||||||
Q_ASSERT(currentReply);
|
Q_ASSERT(currentReply);
|
||||||
emitReplyError(channels[0].socket, currentReply, QNetworkReply::HostNotFoundError);
|
emitReplyError(channels[0].socket, currentReply, QNetworkReply::HostNotFoundError);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
#endif // QT_NO_SSL
|
// Should not happen: we start a host lookup before sending a request,
|
||||||
else {
|
// so it's natural to have requests either in SPDY/HTTP/2 queue,
|
||||||
// Should not happen
|
// or in low/high priority queues.
|
||||||
qWarning("QHttpNetworkConnectionPrivate::_q_hostLookupFinished could not de-queue request");
|
qWarning("QHttpNetworkConnectionPrivate::_q_hostLookupFinished"
|
||||||
|
" could not de-queue request, failed to report HostNotFoundError");
|
||||||
networkLayerState = QHttpNetworkConnectionPrivate::Unknown;
|
networkLayerState = QHttpNetworkConnectionPrivate::Unknown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1213,10 +1213,8 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxL
|
|||||||
msg.dwBufferCount = 1;
|
msg.dwBufferCount = 1;
|
||||||
msg.name = reinterpret_cast<LPSOCKADDR>(&aa);
|
msg.name = reinterpret_cast<LPSOCKADDR>(&aa);
|
||||||
msg.namelen = sizeof(aa);
|
msg.namelen = sizeof(aa);
|
||||||
if (options & (QAbstractSocketEngine::WantDatagramHopLimit | QAbstractSocketEngine::WantDatagramDestination)) {
|
msg.Control.buf = cbuf;
|
||||||
msg.Control.buf = cbuf;
|
msg.Control.len = sizeof(cbuf);
|
||||||
msg.Control.len = sizeof(cbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD flags = 0;
|
DWORD flags = 0;
|
||||||
DWORD bytesRead = 0;
|
DWORD bytesRead = 0;
|
||||||
|
@ -290,6 +290,18 @@ void tst_QFlags::testSetFlags()
|
|||||||
btn.setFlag(Qt::LeftButton, false);
|
btn.setFlag(Qt::LeftButton, false);
|
||||||
QVERIFY(!btn.testFlag(Qt::LeftButton));
|
QVERIFY(!btn.testFlag(Qt::LeftButton));
|
||||||
QVERIFY(!btn.testFlag(Qt::MidButton));
|
QVERIFY(!btn.testFlag(Qt::MidButton));
|
||||||
|
|
||||||
|
MyStrictFlags flags;
|
||||||
|
flags.setFlag(MyStrictEnum::StrictOne);
|
||||||
|
flags.setFlag(MyStrictEnum::StrictTwo, true);
|
||||||
|
QVERIFY(flags.testFlag(MyStrictEnum::StrictOne));
|
||||||
|
QVERIFY(flags.testFlag(MyStrictEnum::StrictTwo));
|
||||||
|
QVERIFY(!flags.testFlag(MyStrictEnum::StrictFour));
|
||||||
|
|
||||||
|
flags.setFlag(MyStrictEnum::StrictTwo, false);
|
||||||
|
QVERIFY(flags.testFlag(MyStrictEnum::StrictOne));
|
||||||
|
QVERIFY(!flags.testFlag(MyStrictEnum::StrictTwo));
|
||||||
|
QVERIFY(!flags.testFlag(MyStrictEnum::StrictFour));
|
||||||
}
|
}
|
||||||
|
|
||||||
// (statically) check QTypeInfo for QFlags instantiations:
|
// (statically) check QTypeInfo for QFlags instantiations:
|
||||||
|
@ -197,10 +197,22 @@ private slots:
|
|||||||
// Check whether QT_LOGGING_CONF is picked up from environment
|
// Check whether QT_LOGGING_CONF is picked up from environment
|
||||||
//
|
//
|
||||||
|
|
||||||
qputenv("QT_LOGGING_CONF", QFINDTESTDATA("qtlogging.ini").toLocal8Bit());
|
Q_ASSERT(!qApp); // Rules should not require an app to resolve
|
||||||
|
|
||||||
QLoggingRegistry registry;
|
qputenv("QT_LOGGING_RULES", "qt.foo.bar=true");
|
||||||
registry.init();
|
QLoggingCategory qtEnabledByLoggingRule("qt.foo.bar");
|
||||||
|
QCOMPARE(qtEnabledByLoggingRule.isDebugEnabled(), true);
|
||||||
|
QLoggingCategory qtDisabledByDefault("qt.foo.baz");
|
||||||
|
QCOMPARE(qtDisabledByDefault.isDebugEnabled(), false);
|
||||||
|
|
||||||
|
QLoggingRegistry ®istry = *QLoggingRegistry::instance();
|
||||||
|
QCOMPARE(registry.ruleSets[QLoggingRegistry::ApiRules].size(), 0);
|
||||||
|
QCOMPARE(registry.ruleSets[QLoggingRegistry::ConfigRules].size(), 0);
|
||||||
|
QCOMPARE(registry.ruleSets[QLoggingRegistry::EnvironmentRules].size(), 1);
|
||||||
|
|
||||||
|
qunsetenv("QT_LOGGING_RULES");
|
||||||
|
qputenv("QT_LOGGING_CONF", QFINDTESTDATA("qtlogging.ini").toLocal8Bit());
|
||||||
|
registry.initalizeRules();
|
||||||
|
|
||||||
QCOMPARE(registry.ruleSets[QLoggingRegistry::ApiRules].size(), 0);
|
QCOMPARE(registry.ruleSets[QLoggingRegistry::ApiRules].size(), 0);
|
||||||
QCOMPARE(registry.ruleSets[QLoggingRegistry::ConfigRules].size(), 0);
|
QCOMPARE(registry.ruleSets[QLoggingRegistry::ConfigRules].size(), 0);
|
||||||
@ -208,7 +220,7 @@ private slots:
|
|||||||
|
|
||||||
// check that QT_LOGGING_RULES take precedence
|
// check that QT_LOGGING_RULES take precedence
|
||||||
qputenv("QT_LOGGING_RULES", "Digia.*=true");
|
qputenv("QT_LOGGING_RULES", "Digia.*=true");
|
||||||
registry.init();
|
registry.initalizeRules();
|
||||||
QCOMPARE(registry.ruleSets[QLoggingRegistry::EnvironmentRules].size(), 2);
|
QCOMPARE(registry.ruleSets[QLoggingRegistry::EnvironmentRules].size(), 2);
|
||||||
QCOMPARE(registry.ruleSets[QLoggingRegistry::EnvironmentRules].at(1).enabled, true);
|
QCOMPARE(registry.ruleSets[QLoggingRegistry::EnvironmentRules].at(1).enabled, true);
|
||||||
}
|
}
|
||||||
@ -234,7 +246,7 @@ private slots:
|
|||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
QLoggingRegistry registry;
|
QLoggingRegistry registry;
|
||||||
registry.init();
|
registry.initalizeRules();
|
||||||
QCOMPARE(registry.ruleSets[QLoggingRegistry::ConfigRules].size(), 1);
|
QCOMPARE(registry.ruleSets[QLoggingRegistry::ConfigRules].size(), 1);
|
||||||
|
|
||||||
// remove file again
|
// remove file again
|
||||||
@ -300,6 +312,6 @@ private slots:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
QTEST_MAIN(tst_QLoggingRegistry)
|
QTEST_APPLESS_MAIN(tst_QLoggingRegistry)
|
||||||
|
|
||||||
#include "tst_qloggingregistry.moc"
|
#include "tst_qloggingregistry.moc"
|
||||||
|
@ -41,6 +41,8 @@ private slots:
|
|||||||
void tryAcquireWithTimeout_data();
|
void tryAcquireWithTimeout_data();
|
||||||
void tryAcquireWithTimeout();
|
void tryAcquireWithTimeout();
|
||||||
void tryAcquireWithTimeoutStarvation();
|
void tryAcquireWithTimeoutStarvation();
|
||||||
|
void tryAcquireWithTimeoutForever_data();
|
||||||
|
void tryAcquireWithTimeoutForever();
|
||||||
void producerConsumer();
|
void producerConsumer();
|
||||||
void raii();
|
void raii();
|
||||||
};
|
};
|
||||||
@ -156,21 +158,25 @@ void tst_QSemaphore::tryAcquire()
|
|||||||
semaphore.release();
|
semaphore.release();
|
||||||
QCOMPARE(semaphore.available(), 1);
|
QCOMPARE(semaphore.available(), 1);
|
||||||
QVERIFY(!semaphore.tryAcquire(2));
|
QVERIFY(!semaphore.tryAcquire(2));
|
||||||
|
QVERIFY(!semaphore.tryAcquire(2, 0));
|
||||||
QCOMPARE(semaphore.available(), 1);
|
QCOMPARE(semaphore.available(), 1);
|
||||||
|
|
||||||
semaphore.release();
|
semaphore.release();
|
||||||
QCOMPARE(semaphore.available(), 2);
|
QCOMPARE(semaphore.available(), 2);
|
||||||
QVERIFY(!semaphore.tryAcquire(3));
|
QVERIFY(!semaphore.tryAcquire(3));
|
||||||
|
QVERIFY(!semaphore.tryAcquire(3, 0));
|
||||||
QCOMPARE(semaphore.available(), 2);
|
QCOMPARE(semaphore.available(), 2);
|
||||||
|
|
||||||
semaphore.release(10);
|
semaphore.release(10);
|
||||||
QCOMPARE(semaphore.available(), 12);
|
QCOMPARE(semaphore.available(), 12);
|
||||||
QVERIFY(!semaphore.tryAcquire(100));
|
QVERIFY(!semaphore.tryAcquire(100));
|
||||||
|
QVERIFY(!semaphore.tryAcquire(100, 0));
|
||||||
QCOMPARE(semaphore.available(), 12);
|
QCOMPARE(semaphore.available(), 12);
|
||||||
|
|
||||||
semaphore.release(10);
|
semaphore.release(10);
|
||||||
QCOMPARE(semaphore.available(), 22);
|
QCOMPARE(semaphore.available(), 22);
|
||||||
QVERIFY(!semaphore.tryAcquire(100));
|
QVERIFY(!semaphore.tryAcquire(100));
|
||||||
|
QVERIFY(!semaphore.tryAcquire(100, 0));
|
||||||
QCOMPARE(semaphore.available(), 22);
|
QCOMPARE(semaphore.available(), 22);
|
||||||
|
|
||||||
QVERIFY(semaphore.tryAcquire());
|
QVERIFY(semaphore.tryAcquire());
|
||||||
@ -179,23 +185,38 @@ void tst_QSemaphore::tryAcquire()
|
|||||||
QVERIFY(semaphore.tryAcquire());
|
QVERIFY(semaphore.tryAcquire());
|
||||||
QCOMPARE(semaphore.available(), 20);
|
QCOMPARE(semaphore.available(), 20);
|
||||||
|
|
||||||
|
semaphore.release(2);
|
||||||
|
QVERIFY(semaphore.tryAcquire(1, 0));
|
||||||
|
QCOMPARE(semaphore.available(), 21);
|
||||||
|
|
||||||
|
QVERIFY(semaphore.tryAcquire(1, 0));
|
||||||
|
QCOMPARE(semaphore.available(), 20);
|
||||||
|
|
||||||
QVERIFY(semaphore.tryAcquire(10));
|
QVERIFY(semaphore.tryAcquire(10));
|
||||||
QCOMPARE(semaphore.available(), 10);
|
QCOMPARE(semaphore.available(), 10);
|
||||||
|
|
||||||
|
semaphore.release(10);
|
||||||
|
QVERIFY(semaphore.tryAcquire(10, 0));
|
||||||
|
QCOMPARE(semaphore.available(), 10);
|
||||||
|
|
||||||
QVERIFY(semaphore.tryAcquire(10));
|
QVERIFY(semaphore.tryAcquire(10));
|
||||||
QCOMPARE(semaphore.available(), 0);
|
QCOMPARE(semaphore.available(), 0);
|
||||||
|
|
||||||
// should not be able to acquire more
|
// should not be able to acquire more
|
||||||
QVERIFY(!semaphore.tryAcquire());
|
QVERIFY(!semaphore.tryAcquire());
|
||||||
|
QVERIFY(!semaphore.tryAcquire(1, 0));
|
||||||
QCOMPARE(semaphore.available(), 0);
|
QCOMPARE(semaphore.available(), 0);
|
||||||
|
|
||||||
QVERIFY(!semaphore.tryAcquire());
|
QVERIFY(!semaphore.tryAcquire());
|
||||||
|
QVERIFY(!semaphore.tryAcquire(1, 0));
|
||||||
QCOMPARE(semaphore.available(), 0);
|
QCOMPARE(semaphore.available(), 0);
|
||||||
|
|
||||||
QVERIFY(!semaphore.tryAcquire(10));
|
QVERIFY(!semaphore.tryAcquire(10));
|
||||||
|
QVERIFY(!semaphore.tryAcquire(10, 0));
|
||||||
QCOMPARE(semaphore.available(), 0);
|
QCOMPARE(semaphore.available(), 0);
|
||||||
|
|
||||||
QVERIFY(!semaphore.tryAcquire(10));
|
QVERIFY(!semaphore.tryAcquire(10));
|
||||||
|
QVERIFY(!semaphore.tryAcquire(10, 0));
|
||||||
QCOMPARE(semaphore.available(), 0);
|
QCOMPARE(semaphore.available(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,6 +366,48 @@ void tst_QSemaphore::tryAcquireWithTimeoutStarvation()
|
|||||||
QVERIFY(consumer.wait());
|
QVERIFY(consumer.wait());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QSemaphore::tryAcquireWithTimeoutForever_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<int>("timeout");
|
||||||
|
QTest::newRow("-1") << -1;
|
||||||
|
|
||||||
|
// tryAcquire is documented to take any negative value as "forever"
|
||||||
|
QTest::newRow("INT_MIN") << INT_MIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QSemaphore::tryAcquireWithTimeoutForever()
|
||||||
|
{
|
||||||
|
enum { WaitTime = 1000 };
|
||||||
|
struct Thread : public QThread {
|
||||||
|
QSemaphore sem;
|
||||||
|
|
||||||
|
void run() override
|
||||||
|
{
|
||||||
|
QTest::qWait(WaitTime);
|
||||||
|
sem.release(2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
QFETCH(int, timeout);
|
||||||
|
Thread t;
|
||||||
|
|
||||||
|
// sanity check it works if we can immediately acquire
|
||||||
|
t.sem.release(11);
|
||||||
|
QVERIFY(t.sem.tryAcquire(1, timeout));
|
||||||
|
QVERIFY(t.sem.tryAcquire(10, timeout));
|
||||||
|
|
||||||
|
// verify that we do wait for at least WaitTime if we can't acquire immediately
|
||||||
|
QElapsedTimer timer;
|
||||||
|
timer.start();
|
||||||
|
t.start();
|
||||||
|
QVERIFY(t.sem.tryAcquire(1, timeout));
|
||||||
|
QVERIFY(timer.elapsed() >= WaitTime);
|
||||||
|
|
||||||
|
QVERIFY(t.wait());
|
||||||
|
|
||||||
|
QCOMPARE(t.sem.available(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
const char alphabet[] = "ACGTH";
|
const char alphabet[] = "ACGTH";
|
||||||
const int AlphabetSize = sizeof(alphabet) - 1;
|
const int AlphabetSize = sizeof(alphabet) - 1;
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ private slots:
|
|||||||
void tst_QDnsLookup_Appless::noApplication()
|
void tst_QDnsLookup_Appless::noApplication()
|
||||||
{
|
{
|
||||||
QTest::ignoreMessage(QtWarningMsg, "QDnsLookup requires a QCoreApplication");
|
QTest::ignoreMessage(QtWarningMsg, "QDnsLookup requires a QCoreApplication");
|
||||||
QDnsLookup dns(QDnsLookup::A, "a-single.test.macieira.org");
|
QDnsLookup dns(QDnsLookup::A, "a-single.test.qt-project.org");
|
||||||
dns.lookup();
|
dns.lookup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ void tst_QDnsLookup_Appless::recreateApplication()
|
|||||||
char **argv = 0;
|
char **argv = 0;
|
||||||
for (int i = 0; i < 10; ++i) {
|
for (int i = 0; i < 10; ++i) {
|
||||||
QCoreApplication app(argc, argv);
|
QCoreApplication app(argc, argv);
|
||||||
QDnsLookup dns(QDnsLookup::A, "a-single.test.macieira.org");
|
QDnsLookup dns(QDnsLookup::A, "a-single.test.qt-project.org");
|
||||||
dns.lookup();
|
dns.lookup();
|
||||||
if (!dns.isFinished()) {
|
if (!dns.isFinished()) {
|
||||||
QObject::connect(&dns, SIGNAL(finished()),
|
QObject::connect(&dns, SIGNAL(finished()),
|
||||||
|
@ -72,7 +72,7 @@
|
|||||||
|
|
||||||
#include "../../../network-settings.h"
|
#include "../../../network-settings.h"
|
||||||
|
|
||||||
#define TEST_DOMAIN ".test.macieira.org"
|
#define TEST_DOMAIN ".test.qt-project.org"
|
||||||
|
|
||||||
|
|
||||||
class tst_QHostInfo : public QObject
|
class tst_QHostInfo : public QObject
|
||||||
|
@ -6,8 +6,6 @@ windows
|
|||||||
windows
|
windows
|
||||||
[invalidProxy:socks5-on-http]
|
[invalidProxy:socks5-on-http]
|
||||||
windows
|
windows
|
||||||
[disconnectWhileLookingUp]
|
|
||||||
windows
|
|
||||||
[timeoutConnect:ip]
|
[timeoutConnect:ip]
|
||||||
windows
|
windows
|
||||||
]
|
]
|
||||||
|
@ -1445,8 +1445,15 @@ void tst_QTcpSocket::disconnectWhileLookingUp()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// let anything queued happen
|
// let anything queued happen
|
||||||
|
|
||||||
QEventLoop loop;
|
QEventLoop loop;
|
||||||
QTimer::singleShot(50, &loop, SLOT(quit()));
|
// If 'doClose' is false then we called '::waitForDisconnected' earlier, meaning
|
||||||
|
// we are already 'Unconnected'. So we don't need to wait for any potentially slow host lookups.
|
||||||
|
QTimer::singleShot(doClose ? 4000 : 50, &loop, SLOT(quit()));
|
||||||
|
connect(socket, &QTcpSocket::stateChanged, [&loop](QAbstractSocket::SocketState state) {
|
||||||
|
if (state == QAbstractSocket::UnconnectedState)
|
||||||
|
loop.exit(); // we don't need to wait for the timer to expire; we're done.
|
||||||
|
});
|
||||||
loop.exec();
|
loop.exec();
|
||||||
|
|
||||||
// recheck
|
// recheck
|
||||||
|
Loading…
x
Reference in New Issue
Block a user