Some improvements to LockedFile class.

This commit is contained in:
LoRd_MuldeR 2017-04-16 23:59:11 +02:00
parent a9632ce45e
commit 59d99afe8e
2 changed files with 60 additions and 27 deletions

View File

@ -35,7 +35,7 @@
#define VER_LAMEXP_MINOR_LO 5 #define VER_LAMEXP_MINOR_LO 5
#define VER_LAMEXP_TYPE Beta #define VER_LAMEXP_TYPE Beta
#define VER_LAMEXP_PATCH 4 #define VER_LAMEXP_PATCH 4
#define VER_LAMEXP_BUILD 1976 #define VER_LAMEXP_BUILD 1978
#define VER_LAMEXP_CONFG 1934 #define VER_LAMEXP_CONFG 1934
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -48,6 +48,9 @@
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <Windows.h> #include <Windows.h>
//Const
static const quint32 MAX_LOCK_DELAY = 16384U;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// WARNING: Passing file descriptors into Qt does NOT work with dynamically linked CRT! // WARNING: Passing file descriptors into Qt does NOT work with dynamically linked CRT!
@ -59,6 +62,11 @@
#define VALID_HANDLE(H) (((H) != NULL) && ((H) != INVALID_HANDLE_VALUE)) #define VALID_HANDLE(H) (((H) != NULL) && ((H) != INVALID_HANDLE_VALUE))
static __forceinline quint32 NEXT_DELAY(const quint32 delay)
{
return (delay > 0U) ? (delay * 2U) : 1U;
}
static bool PROTECT_HANDLE(const HANDLE &h, const bool &lock) static bool PROTECT_HANDLE(const HANDLE &h, const bool &lock)
{ {
if (SetHandleInformation(h, HANDLE_FLAG_PROTECT_FROM_CLOSE, (lock ? HANDLE_FLAG_PROTECT_FROM_CLOSE : 0U))) if (SetHandleInformation(h, HANDLE_FLAG_PROTECT_FROM_CLOSE, (lock ? HANDLE_FLAG_PROTECT_FROM_CLOSE : 0U)))
@ -92,17 +100,20 @@ static void CLOSE_FILE(int &fd)
static __forceinline void doWriteOutput(QFile &outFile, const QResource *const resource) static __forceinline void doWriteOutput(QFile &outFile, const QResource *const resource)
{ {
for(int i = 0; i < 64; i++) for (quint32 delay = 0U; delay <= MAX_LOCK_DELAY; delay = NEXT_DELAY(delay))
{ {
if (delay > 0U)
{
if (delay <= 1U)
{
qWarning("Failed to open file on first attempt, retrying...");
}
MUtils::OS::sleep_ms(delay);
}
if(outFile.open(QIODevice::WriteOnly)) if(outFile.open(QIODevice::WriteOnly))
{ {
break; break; /*file opened successfully*/
} }
if(i == 0)
{
qWarning("Failed to open file on first attemp, retrying...");
}
Sleep(25);
} }
//Write data to file //Write data to file
@ -141,27 +152,38 @@ static __forceinline void doLockFile(HANDLE &fileHandle, const QString &filePath
fileHandle = INVALID_HANDLE_VALUE; fileHandle = INVALID_HANDLE_VALUE;
//Try to open the file! //Try to open the file!
for(int i = 0; i < 64; i++) for(quint32 delay = 0U; delay <= MAX_LOCK_DELAY; delay = NEXT_DELAY(delay))
{ {
if (delay > 0U)
{
if (delay <= 1U)
{
qWarning("Failed to open file on first attempt, retrying...");
}
MUtils::OS::sleep_ms(delay);
}
const HANDLE hTemp = CreateFileW(MUTILS_WCHR(QDir::toNativeSeparators(filePath)), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL); const HANDLE hTemp = CreateFileW(MUTILS_WCHR(QDir::toNativeSeparators(filePath)), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
if(VALID_HANDLE(hTemp)) if(VALID_HANDLE(hTemp))
{ {
PROTECT_HANDLE(fileHandle = hTemp, true); PROTECT_HANDLE(fileHandle = hTemp, true);
break; /*file opened successfully*/ break; /*file opened successfully*/
} }
if(i == 0)
{
qWarning("Failed to open file on first attemp, retrying...");
}
Sleep(1);
} }
//Now try to actually lock the file! //Now try to actually lock the file!
if (VALID_HANDLE(fileHandle)) if (VALID_HANDLE(fileHandle))
{ {
for (int i = 0; i < 64; i++) for (quint32 delay = 0U; delay <= MAX_LOCK_DELAY; delay = NEXT_DELAY(delay))
{ {
LARGE_INTEGER fileSize; LARGE_INTEGER fileSize;
if (delay > 0U)
{
if (delay <= 1U)
{
qWarning("Failed to lock file on first attempt, retrying...");
}
MUtils::OS::sleep_ms(delay);
}
if (GetFileSizeEx(fileHandle, &fileSize)) if (GetFileSizeEx(fileHandle, &fileSize))
{ {
OVERLAPPED overlapped = { 0U, 0U, 0U, 0U, 0U }; OVERLAPPED overlapped = { 0U, 0U, 0U, 0U, 0U };
@ -170,11 +192,6 @@ static __forceinline void doLockFile(HANDLE &fileHandle, const QString &filePath
success = true; success = true;
break; /*file locked successfully*/ break; /*file locked successfully*/
} }
Sleep(1);
}
if (i == 0)
{
qWarning("Failed to lock file on first attemp, retrying...");
} }
} }
} }
@ -212,11 +229,20 @@ static __forceinline void doValidateHash(HANDLE &fileHandle, const int &fileDesc
else else
{ {
checkFile.setFileName(filePath); checkFile.setFileName(filePath);
for(int i = 0; i < 64; i++) for (quint32 delay = 0U; delay <= MAX_LOCK_DELAY; delay = NEXT_DELAY(delay))
{ {
if(checkFile.open(QIODevice::ReadOnly)) break; if (delay > 0U)
if(!i) qWarning("Failed to re-open file on first attemp, retrying..."); {
Sleep(100); if (delay <= 1U)
{
qWarning("Failed to open file on first attempt, retrying...");
}
MUtils::OS::sleep_ms(delay);
}
if (checkFile.open(QIODevice::ReadOnly))
{
break; /*file locked successfully*/
}
} }
} }
@ -243,13 +269,20 @@ static __forceinline void doValidateHash(HANDLE &fileHandle, const int &fileDesc
static __forceinline bool doRemoveFile(const QString &filePath) static __forceinline bool doRemoveFile(const QString &filePath)
{ {
for(int i = 0; i < 32; i++) for (quint32 delay = 0U; delay <= MAX_LOCK_DELAY / 4; delay = NEXT_DELAY(delay))
{ {
if (delay > 0U)
{
if (delay <= 1U)
{
qWarning("Failed to delete file on first attempt, retrying...");
}
MUtils::OS::sleep_ms(delay);
}
if(MUtils::remove_file(filePath)) if(MUtils::remove_file(filePath))
{ {
return true; return true; /*file removed successfully*/
} }
MUtils::OS::sleep_ms(1);
} }
return false; return false;
} }