FileSystem: Add non-blocking option to POSIXLock
This commit is contained in:
parent
d93c713fb7
commit
04e472d088
|
@ -2788,18 +2788,24 @@ bool FileSystem::SetPathCompression(const char* path, bool enable)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool SetLock(int fd, bool lock)
|
static bool SetLock(int fd, bool lock, bool block, Error* error)
|
||||||
{
|
{
|
||||||
// We want to lock the whole file.
|
// We want to lock the whole file.
|
||||||
const off_t offs = lseek(fd, 0, SEEK_CUR);
|
const off_t offs = lseek(fd, 0, SEEK_CUR);
|
||||||
if (offs < 0)
|
if (offs < 0)
|
||||||
{
|
{
|
||||||
|
if (error)
|
||||||
|
error->SetErrno("lseek() failed: ", errno);
|
||||||
|
else
|
||||||
ERROR_LOG("lseek({}) failed: {}", fd, errno);
|
ERROR_LOG("lseek({}) failed: {}", fd, errno);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offs != 0 && lseek(fd, 0, SEEK_SET) < 0)
|
if (offs != 0 && lseek(fd, 0, SEEK_SET) < 0)
|
||||||
{
|
{
|
||||||
|
if (error)
|
||||||
|
error->SetErrno("lseek(0) failed: ", errno);
|
||||||
|
else
|
||||||
ERROR_LOG("lseek({}, 0) failed: {}", fd, errno);
|
ERROR_LOG("lseek({}, 0) failed: {}", fd, errno);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2808,19 +2814,24 @@ static bool SetLock(int fd, bool lock)
|
||||||
bool res;
|
bool res;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
res = (lockf(fd, lock ? F_LOCK : F_ULOCK, 0) == 0);
|
res = (lockf(fd, lock ? (block ? F_TLOCK : F_LOCK) : F_ULOCK, 0) == 0);
|
||||||
if (!res && errno == EINTR)
|
if (!res && errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
if (error)
|
||||||
|
error->SetErrno("lockf() failed: ", errno);
|
||||||
|
else
|
||||||
|
ERROR_LOG("lockf() for {} failed: {}", lock ? "lock" : "unlock", errno);
|
||||||
|
}
|
||||||
|
|
||||||
if (lseek(fd, offs, SEEK_SET) < 0)
|
if (lseek(fd, offs, SEEK_SET) < 0)
|
||||||
Panic("Repositioning file descriptor after lock failed.");
|
Panic("Repositioning file descriptor after lock failed.");
|
||||||
|
|
||||||
if (!res)
|
|
||||||
ERROR_LOG("lockf() for {} failed: {}", lock ? "lock" : "unlock", errno);
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2828,15 +2839,15 @@ FileSystem::POSIXLock::POSIXLock() : m_fd(-1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSystem::POSIXLock::POSIXLock(int fd) : m_fd(fd)
|
FileSystem::POSIXLock::POSIXLock(int fd, bool block, Error* error) : m_fd(fd)
|
||||||
{
|
{
|
||||||
if (!SetLock(m_fd, true))
|
if (!SetLock(m_fd, true, block, error))
|
||||||
m_fd = -1;
|
m_fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSystem::POSIXLock::POSIXLock(std::FILE* fp) : m_fd(fileno(fp))
|
FileSystem::POSIXLock::POSIXLock(std::FILE* fp, bool block, Error* error) : m_fd(fileno(fp))
|
||||||
{
|
{
|
||||||
if (!SetLock(m_fd, true))
|
if (!SetLock(m_fd, true, block, error))
|
||||||
m_fd = -1;
|
m_fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2846,9 +2857,17 @@ FileSystem::POSIXLock::POSIXLock(POSIXLock&& move)
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSystem::POSIXLock::~POSIXLock()
|
FileSystem::POSIXLock::~POSIXLock()
|
||||||
|
{
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileSystem::POSIXLock::Unlock()
|
||||||
{
|
{
|
||||||
if (m_fd >= 0)
|
if (m_fd >= 0)
|
||||||
SetLock(m_fd, false);
|
{
|
||||||
|
SetLock(m_fd, false, true, nullptr);
|
||||||
|
m_fd = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSystem::POSIXLock& FileSystem::POSIXLock::operator=(POSIXLock&& move)
|
FileSystem::POSIXLock& FileSystem::POSIXLock::operator=(POSIXLock&& move)
|
||||||
|
|
|
@ -160,8 +160,8 @@ class POSIXLock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
POSIXLock();
|
POSIXLock();
|
||||||
POSIXLock(int fd);
|
POSIXLock(int fd, bool block = true, Error* error = nullptr);
|
||||||
POSIXLock(std::FILE* fp);
|
POSIXLock(std::FILE* fp, bool block = true, Error* error = nullptr);
|
||||||
POSIXLock(POSIXLock&& move);
|
POSIXLock(POSIXLock&& move);
|
||||||
POSIXLock(const POSIXLock&) = delete;
|
POSIXLock(const POSIXLock&) = delete;
|
||||||
~POSIXLock();
|
~POSIXLock();
|
||||||
|
@ -169,6 +169,9 @@ public:
|
||||||
POSIXLock& operator=(POSIXLock&& move);
|
POSIXLock& operator=(POSIXLock&& move);
|
||||||
POSIXLock& operator=(const POSIXLock&) = delete;
|
POSIXLock& operator=(const POSIXLock&) = delete;
|
||||||
|
|
||||||
|
ALWAYS_INLINE bool IsLocked() const { return (m_fd >= 0); }
|
||||||
|
void Unlock();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_fd;
|
int m_fd;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue