21#ifndef LIBDAP4_MP_LOCK_GUARD_H
22#define LIBDAP4_MP_LOCK_GUARD_H
35static inline std::string get_errno() {
36 const char *s_err = strerror(errno);
37 return s_err ? s_err :
"unknown error";
50 virtual void log(
const std::string &msg)
const = 0;
52 virtual void error(
const std::string &msg)
const = 0;
65 void log(
const std::string &msg)
const override { std::cerr <<
"~mp_lock_guard: " << msg << std::endl; }
67 void error(
const std::string &msg)
const override {
throw std::runtime_error(
"mp_lock_guard: " + msg); }
85 bool d_locked =
false;
86 bool d_released =
false;
93 lock.l_type = F_WRLCK;
94 lock.l_whence = SEEK_SET;
97 lock.l_pid = getpid();
98 if (fcntl(d_fd, F_SETLKW, &lock) == -1) {
99 d_logger.
error(
"Could not write lock the cache-control file: " + get_errno());
102 struct flock lock {};
103 lock.l_type = F_RDLCK;
104 lock.l_whence = SEEK_SET;
107 lock.l_pid = getpid();
108 if (fcntl(d_fd, F_SETLKW, &lock) == -1) {
109 d_logger.error(
"Could not read lock the cache-control file: " + get_errno());
131 : d_fd(fd), d_op(op), d_logger(logger) {
143 if (!d_released && d_locked) {
144 struct flock lock {};
145 lock.l_type = F_UNLCK;
146 lock.l_whence = SEEK_SET;
149 lock.l_pid = getpid();
150 if (fcntl(d_fd, F_SETLK, &lock) == -1) {
151 d_logger.log(
"Could not unlock the cache-control file: " + get_errno());
166 struct flock lock {};
167 lock.l_type = F_UNLCK;
168 lock.l_whence = SEEK_SET;
171 lock.l_pid = getpid();
172 if (fcntl(fd, F_SETLK, &lock) == -1) {
173 logger.error(
"Could not unlock the cache-control file: " + get_errno());
Default logger for mp_lock_guard For this implementation of mp_lock_guard_logger, the log() method wr...
void log(const std::string &msg) const override
mp_lock_guard_logger_default()=default
void error(const std::string &msg) const override
~mp_lock_guard_logger_default() override=default
Interface for the logger used by mp_lock_guard The idea behind this abstract class (aka,...
virtual void log(const std::string &msg) const =0
mp_lock_guard_logger()=default
virtual void error(const std::string &msg) const =0
virtual ~mp_lock_guard_logger()=default
friend class mp_lock_guard_test
static void unlock(int fd, const mp_lock_guard_logger &logger=mp_lock_guard_logger_default())
mp_lock_guard & operator=(const mp_lock_guard &)=delete
mp_lock_guard(const mp_lock_guard &)=delete
mp_lock_guard(int fd, operation op, const mp_lock_guard_logger &logger=mp_lock_guard_logger_default())
Lock the cache for reading or writing. These are blocking locks.
~mp_lock_guard()
Unlock the cache. Works for both read and write locks.
top level DAP object to house generic methods