diff options
author | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-20 14:33:09 +1000 |
---|---|---|
committer | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-20 14:33:09 +1000 |
commit | 6352e8e3196f78388b6c771073f9e03eaa612673 (patch) | |
tree | e23772f79a7fbc41bc9108951e9e136857484bf4 /source/core/StarLockFile_windows.cpp | |
parent | 6741a057e5639280d85d0f88ba26f000baa58f61 (diff) |
everything everywhere
all at once
Diffstat (limited to 'source/core/StarLockFile_windows.cpp')
-rw-r--r-- | source/core/StarLockFile_windows.cpp | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/source/core/StarLockFile_windows.cpp b/source/core/StarLockFile_windows.cpp new file mode 100644 index 0000000..1cf1473 --- /dev/null +++ b/source/core/StarLockFile_windows.cpp @@ -0,0 +1,80 @@ +#include "StarLockFile.hpp" +#include "StarTime.hpp" +#include "StarThread.hpp" + +#include "StarString_windows.hpp" + +#include <windows.h> + +namespace Star { + +int64_t const LockFile::MaximumSleepMillis; + +Maybe<LockFile> LockFile::acquireLock(String const& filename, int64_t lockTimeout) { + LockFile lock(move(filename)); + if (lock.lock(lockTimeout)) + return move(lock); + return {}; +} + +LockFile::LockFile(String const& filename) : m_filename(move(filename)) {} + +LockFile::LockFile(LockFile&& lockFile) { + operator=(move(lockFile)); +} + +LockFile::~LockFile() { + unlock(); +} + +LockFile& LockFile::operator=(LockFile&& lockFile) { + m_filename = move(lockFile.m_filename); + m_handle = move(lockFile.m_handle); + + return *this; +} + +bool LockFile::lock(int64_t timeout) { + auto doFLock = [](String const& filename) -> shared_ptr<HANDLE> { + HANDLE handle = CreateFileW( + stringToUtf16(filename).get(), GENERIC_READ, 0, nullptr, OPEN_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, nullptr); + if (handle == INVALID_HANDLE_VALUE) { + if (GetLastError() == ERROR_SHARING_VIOLATION) + return {}; + throw StarException(strf("Could not open lock file %s, error code %s\n", filename, GetLastError())); + } + + return make_shared<HANDLE>(handle); + }; + + if (timeout == 0) { + m_handle = doFLock(m_filename); + return (bool)m_handle; + } else { + int64_t startTime = Time::monotonicMilliseconds(); + while (true) { + m_handle = doFLock(m_filename); + if (m_handle) + return true; + + if (timeout > 0 && Time::monotonicMilliseconds() - startTime > timeout) + return false; + + Thread::sleep(min(timeout / 4, MaximumSleepMillis)); + } + } +} + +void LockFile::unlock() { + if (m_handle) { + HANDLE handle = *(HANDLE*)m_handle.get(); + CloseHandle(handle); + m_handle.reset(); + } +} + +bool LockFile::isLocked() const { + return (bool)m_handle; +} + +} |