From fdcfd2816eaaa03cc58949721fd19eaee07e3673 Mon Sep 17 00:00:00 2001 From: Peter Elliott Date: Wed, 21 Jul 2021 21:04:24 -0600 Subject: [PATCH] LibCore: Add LockFile, a filesystem based mutex This API wraps flock(2) and also handles the file creation and deletion when the LockFile goes out of scope. --- Userland/Libraries/LibCore/CMakeLists.txt | 1 + Userland/Libraries/LibCore/LockFile.cpp | 57 +++++++++++++++++++++++ Userland/Libraries/LibCore/LockFile.h | 32 +++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 Userland/Libraries/LibCore/LockFile.cpp create mode 100644 Userland/Libraries/LibCore/LockFile.h diff --git a/Userland/Libraries/LibCore/CMakeLists.txt b/Userland/Libraries/LibCore/CMakeLists.txt index 20418e4f20..adafbcc559 100644 --- a/Userland/Libraries/LibCore/CMakeLists.txt +++ b/Userland/Libraries/LibCore/CMakeLists.txt @@ -15,6 +15,7 @@ set(SOURCES IODevice.cpp LocalServer.cpp LocalSocket.cpp + LockFile.cpp MimeData.cpp NetworkJob.cpp NetworkResponse.cpp diff --git a/Userland/Libraries/LibCore/LockFile.cpp b/Userland/Libraries/LibCore/LockFile.cpp new file mode 100644 index 0000000000..df35982169 --- /dev/null +++ b/Userland/Libraries/LibCore/LockFile.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021, Peter Elliott + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include +#include + +namespace Core { + +LockFile::LockFile(char const* filename, Type type) + : m_filename(filename) +{ + if (!Core::File::ensure_parent_directories(m_filename)) + return; + + m_fd = open(filename, O_RDONLY | O_CREAT, 0666); + if (m_fd == -1) { + m_errno = errno; + return; + } + + if (flock(m_fd, LOCK_NB | ((type == Type::Exclusive) ? LOCK_EX : LOCK_SH)) == -1) { + m_errno = errno; + close(m_fd); + m_fd = -1; + } +} + +LockFile::~LockFile() +{ + release(); +} + +bool LockFile::is_held() const +{ + return m_fd != -1; +} + +void LockFile::release() +{ + if (m_fd == -1) + return; + + unlink(m_filename); + flock(m_fd, LOCK_NB | LOCK_UN); + close(m_fd); + + m_fd = -1; +} + +} diff --git a/Userland/Libraries/LibCore/LockFile.h b/Userland/Libraries/LibCore/LockFile.h new file mode 100644 index 0000000000..4a52f114a8 --- /dev/null +++ b/Userland/Libraries/LibCore/LockFile.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021, Peter Elliott + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +namespace Core { + +class LockFile { +public: + enum class Type { + Exclusive, + Shared + }; + + LockFile(LockFile const& other) = delete; + LockFile(char const* filename, Type type = Type::Exclusive); + ~LockFile(); + + bool is_held() const; + int error_code() const { return m_errno; } + void release(); + +private: + int m_fd { -1 }; + int m_errno { 0 }; + char const* m_filename { nullptr }; +}; + +}