mirror of
https://github.com/pocoproject/poco.git
synced 2025-04-16 06:56:41 +02:00
fixed GH #990: Potential race condition in on Windows
This commit is contained in:
parent
c59ec564c2
commit
efdeadef2a
@ -254,6 +254,7 @@ POCO_DECLARE_EXCEPTION(Foundation_API, CreateFileException, FileException)
|
|||||||
POCO_DECLARE_EXCEPTION(Foundation_API, OpenFileException, FileException)
|
POCO_DECLARE_EXCEPTION(Foundation_API, OpenFileException, FileException)
|
||||||
POCO_DECLARE_EXCEPTION(Foundation_API, WriteFileException, FileException)
|
POCO_DECLARE_EXCEPTION(Foundation_API, WriteFileException, FileException)
|
||||||
POCO_DECLARE_EXCEPTION(Foundation_API, ReadFileException, FileException)
|
POCO_DECLARE_EXCEPTION(Foundation_API, ReadFileException, FileException)
|
||||||
|
POCO_DECLARE_EXCEPTION(Foundation_API, DirectoryNotEmptyException, FileException)
|
||||||
POCO_DECLARE_EXCEPTION(Foundation_API, UnknownURISchemeException, RuntimeException)
|
POCO_DECLARE_EXCEPTION(Foundation_API, UnknownURISchemeException, RuntimeException)
|
||||||
POCO_DECLARE_EXCEPTION(Foundation_API, TooManyURIRedirectsException, RuntimeException)
|
POCO_DECLARE_EXCEPTION(Foundation_API, TooManyURIRedirectsException, RuntimeException)
|
||||||
POCO_DECLARE_EXCEPTION(Foundation_API, URISyntaxException, SyntaxException)
|
POCO_DECLARE_EXCEPTION(Foundation_API, URISyntaxException, SyntaxException)
|
||||||
|
@ -178,6 +178,7 @@ POCO_IMPLEMENT_EXCEPTION(CreateFileException, FileException, "Cannot create file
|
|||||||
POCO_IMPLEMENT_EXCEPTION(OpenFileException, FileException, "Cannot open file")
|
POCO_IMPLEMENT_EXCEPTION(OpenFileException, FileException, "Cannot open file")
|
||||||
POCO_IMPLEMENT_EXCEPTION(WriteFileException, FileException, "Cannot write file")
|
POCO_IMPLEMENT_EXCEPTION(WriteFileException, FileException, "Cannot write file")
|
||||||
POCO_IMPLEMENT_EXCEPTION(ReadFileException, FileException, "Cannot read file")
|
POCO_IMPLEMENT_EXCEPTION(ReadFileException, FileException, "Cannot read file")
|
||||||
|
POCO_IMPLEMENT_EXCEPTION(DirectoryNotEmptyException, FileException, "Directory not empty")
|
||||||
POCO_IMPLEMENT_EXCEPTION(UnknownURISchemeException, RuntimeException, "Unknown URI scheme")
|
POCO_IMPLEMENT_EXCEPTION(UnknownURISchemeException, RuntimeException, "Unknown URI scheme")
|
||||||
POCO_IMPLEMENT_EXCEPTION(TooManyURIRedirectsException, RuntimeException, "Too many URI redirects")
|
POCO_IMPLEMENT_EXCEPTION(TooManyURIRedirectsException, RuntimeException, "Too many URI redirects")
|
||||||
POCO_IMPLEMENT_EXCEPTION(URISyntaxException, SyntaxException, "Bad URI syntax")
|
POCO_IMPLEMENT_EXCEPTION(URISyntaxException, SyntaxException, "Bad URI syntax")
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#else
|
#else
|
||||||
#include "File_VMS.cpp"
|
#include "File_VMS.cpp"
|
||||||
#endif
|
#endif
|
||||||
|
#include "Poco/Thread.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco {
|
||||||
@ -269,8 +270,37 @@ void File::remove(bool recursive)
|
|||||||
{
|
{
|
||||||
it->remove(true);
|
it->remove(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note: On Windows, removing a directory may not succeed at first
|
||||||
|
// try because deleting files is not a synchronous operation. Files
|
||||||
|
// are merely marked as deleted, and actually removed at a later time.
|
||||||
|
//
|
||||||
|
// An alternate strategy would be moving files to a different directory
|
||||||
|
// first (on the same drive, but outside the deleted tree), and marking
|
||||||
|
// them as hidden, before deleting them, but this could lead to other issues.
|
||||||
|
// So we simply retry after some time until we succeed, or give up.
|
||||||
|
|
||||||
|
int retry = 8;
|
||||||
|
long sleep = 10;
|
||||||
|
while (retry > 0)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
removeImpl();
|
||||||
|
retry = 0;
|
||||||
|
}
|
||||||
|
catch (DirectoryNotEmptyException&)
|
||||||
|
{
|
||||||
|
if (--retry == 0) throw;
|
||||||
|
Poco::Thread::sleep(sleep);
|
||||||
|
sleep *= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
removeImpl();
|
||||||
}
|
}
|
||||||
removeImpl();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -507,7 +507,7 @@ void FileImpl::handleLastErrorImpl(const std::string& path)
|
|||||||
throw FileException("disk quota exceeded", path, errno);
|
throw FileException("disk quota exceeded", path, errno);
|
||||||
#if !defined(_AIX)
|
#if !defined(_AIX)
|
||||||
case ENOTEMPTY:
|
case ENOTEMPTY:
|
||||||
throw FileException("directory not empty", path, errno);
|
throw DirectoryNotEmptyException(path, errno);
|
||||||
#endif
|
#endif
|
||||||
case ENAMETOOLONG:
|
case ENAMETOOLONG:
|
||||||
throw PathSyntaxException(path, errno);
|
throw PathSyntaxException(path, errno);
|
||||||
|
@ -405,7 +405,7 @@ void FileImpl::handleLastErrorImpl(const std::string& path)
|
|||||||
case EDQUOT:
|
case EDQUOT:
|
||||||
throw FileException("disk quota exceeded", path);
|
throw FileException("disk quota exceeded", path);
|
||||||
case ENOTEMPTY:
|
case ENOTEMPTY:
|
||||||
throw FileException("directory not empty", path);
|
throw DirectoryNotEmptyException(path, err);
|
||||||
case ENAMETOOLONG:
|
case ENAMETOOLONG:
|
||||||
throw PathSyntaxException(path);
|
throw PathSyntaxException(path);
|
||||||
default:
|
default:
|
||||||
|
@ -389,7 +389,7 @@ void FileImpl::handleLastErrorImpl(const std::string& path)
|
|||||||
case ENOSPC:
|
case ENOSPC:
|
||||||
throw FileException("no space left on device", path);
|
throw FileException("no space left on device", path);
|
||||||
case ENOTEMPTY:
|
case ENOTEMPTY:
|
||||||
throw FileException("directory not empty", path);
|
throw DirectoryNotEmptyException(path);
|
||||||
case ENAMETOOLONG:
|
case ENAMETOOLONG:
|
||||||
throw PathSyntaxException(path);
|
throw PathSyntaxException(path);
|
||||||
case ENFILE:
|
case ENFILE:
|
||||||
|
@ -409,7 +409,7 @@ void FileImpl::handleLastErrorImpl(const std::string& path)
|
|||||||
case ERROR_CANNOT_MAKE:
|
case ERROR_CANNOT_MAKE:
|
||||||
throw CreateFileException(path, err);
|
throw CreateFileException(path, err);
|
||||||
case ERROR_DIR_NOT_EMPTY:
|
case ERROR_DIR_NOT_EMPTY:
|
||||||
throw FileException("directory not empty", path, err);
|
throw DirectoryNotEmptyException(path, err);
|
||||||
case ERROR_WRITE_FAULT:
|
case ERROR_WRITE_FAULT:
|
||||||
throw WriteFileException(path, err);
|
throw WriteFileException(path, err);
|
||||||
case ERROR_READ_FAULT:
|
case ERROR_READ_FAULT:
|
||||||
|
@ -417,7 +417,7 @@ void FileImpl::handleLastErrorImpl(const std::string& path)
|
|||||||
case ERROR_CANNOT_MAKE:
|
case ERROR_CANNOT_MAKE:
|
||||||
throw CreateFileException(path, err);
|
throw CreateFileException(path, err);
|
||||||
case ERROR_DIR_NOT_EMPTY:
|
case ERROR_DIR_NOT_EMPTY:
|
||||||
throw FileException("directory not empty", path, err);
|
throw DirectoryNotEmptyException(path, err);
|
||||||
case ERROR_WRITE_FAULT:
|
case ERROR_WRITE_FAULT:
|
||||||
throw WriteFileException(path, err);
|
throw WriteFileException(path, err);
|
||||||
case ERROR_READ_FAULT:
|
case ERROR_READ_FAULT:
|
||||||
|
@ -407,7 +407,7 @@ void FileImpl::handleLastErrorImpl(const std::string& path)
|
|||||||
case ERROR_CANNOT_MAKE:
|
case ERROR_CANNOT_MAKE:
|
||||||
throw CreateFileException(path);
|
throw CreateFileException(path);
|
||||||
case ERROR_DIR_NOT_EMPTY:
|
case ERROR_DIR_NOT_EMPTY:
|
||||||
throw FileException("directory not empty", path);
|
throw DirectoryNotEmptyException(path);
|
||||||
case ERROR_WRITE_FAULT:
|
case ERROR_WRITE_FAULT:
|
||||||
throw WriteFileException(path);
|
throw WriteFileException(path);
|
||||||
case ERROR_READ_FAULT:
|
case ERROR_READ_FAULT:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user