QLockFile: fix deadlock when the lock file is corrupted
[ChangeLog][QtCore][QLockFile] Fixed a deadlock when the lock file is corrupted. Task-number: QTBUG-44771 Change-Id: Ic490b09d70ff1cc1733b64949889a73720b2d0f3 Reviewed-by: David Faure <david.faure@kdab.com>
This commit is contained in:
parent
d238f7e019
commit
f58e882b75
@ -181,11 +181,11 @@ bool QLockFilePrivate::isApparentlyStale() const
|
|||||||
{
|
{
|
||||||
qint64 pid;
|
qint64 pid;
|
||||||
QString hostname, appname;
|
QString hostname, appname;
|
||||||
if (!getLockInfo(&pid, &hostname, &appname))
|
if (getLockInfo(&pid, &hostname, &appname)) {
|
||||||
return false;
|
if (hostname.isEmpty() || hostname == QString::fromLocal8Bit(localHostName())) {
|
||||||
if (hostname.isEmpty() || hostname == QString::fromLocal8Bit(localHostName())) {
|
if (::kill(pid, 0) == -1 && errno == ESRCH)
|
||||||
if (::kill(pid, 0) == -1 && errno == ESRCH)
|
return true; // PID doesn't exist anymore
|
||||||
return true; // PID doesn't exist anymore
|
}
|
||||||
}
|
}
|
||||||
const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime());
|
const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime());
|
||||||
return staleLockTime > 0 && age > staleLockTime;
|
return staleLockTime > 0 && age > staleLockTime;
|
||||||
|
@ -115,21 +115,21 @@ bool QLockFilePrivate::isApparentlyStale() const
|
|||||||
{
|
{
|
||||||
qint64 pid;
|
qint64 pid;
|
||||||
QString hostname, appname;
|
QString hostname, appname;
|
||||||
if (!getLockInfo(&pid, &hostname, &appname))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// On WinRT there seems to be no way of obtaining information about other
|
// On WinRT there seems to be no way of obtaining information about other
|
||||||
// processes due to sandboxing
|
// processes due to sandboxing
|
||||||
#ifndef Q_OS_WINRT
|
#ifndef Q_OS_WINRT
|
||||||
if (hostname == QString::fromLocal8Bit(localHostName())) {
|
if (getLockInfo(&pid, &hostname, &appname)) {
|
||||||
HANDLE procHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
|
if (hostname == QString::fromLocal8Bit(localHostName())) {
|
||||||
if (!procHandle)
|
HANDLE procHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
|
||||||
return true;
|
if (!procHandle)
|
||||||
// We got a handle but check if process is still alive
|
return true;
|
||||||
DWORD dwR = ::WaitForSingleObject(procHandle, 0);
|
// We got a handle but check if process is still alive
|
||||||
::CloseHandle(procHandle);
|
DWORD dwR = ::WaitForSingleObject(procHandle, 0);
|
||||||
if (dwR == WAIT_TIMEOUT)
|
::CloseHandle(procHandle);
|
||||||
return true;
|
if (dwR == WAIT_TIMEOUT)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif // !Q_OS_WINRT
|
#endif // !Q_OS_WINRT
|
||||||
const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime());
|
const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime());
|
||||||
|
@ -58,6 +58,7 @@ private slots:
|
|||||||
void staleLongLockFromBusyProcess();
|
void staleLongLockFromBusyProcess();
|
||||||
void staleLockRace();
|
void staleLockRace();
|
||||||
void noPermissions();
|
void noPermissions();
|
||||||
|
void corruptedLockFile();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QString m_helperApp;
|
QString m_helperApp;
|
||||||
@ -415,5 +416,21 @@ void tst_QLockFile::noPermissions()
|
|||||||
QCOMPARE(int(lockFile.error()), int(QLockFile::PermissionError));
|
QCOMPARE(int(lockFile.error()), int(QLockFile::PermissionError));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QLockFile::corruptedLockFile()
|
||||||
|
{
|
||||||
|
const QString fileName = dir.path() + "/corruptedLockFile";
|
||||||
|
|
||||||
|
{
|
||||||
|
// Create a empty file. Typically the result of a computer crash or hard disk full.
|
||||||
|
QFile file(fileName);
|
||||||
|
QVERIFY(file.open(QFile::WriteOnly));
|
||||||
|
}
|
||||||
|
|
||||||
|
QLockFile secondLock(fileName);
|
||||||
|
secondLock.setStaleLockTime(100);
|
||||||
|
QVERIFY(secondLock.tryLock(10000));
|
||||||
|
QCOMPARE(int(secondLock.error()), int(QLockFile::NoError));
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QLockFile)
|
QTEST_MAIN(tst_QLockFile)
|
||||||
#include "tst_qlockfile.moc"
|
#include "tst_qlockfile.moc"
|
||||||
|
Loading…
Reference in New Issue
Block a user