sjef
Loading...
Searching...
No Matches
Locker.h
Go to the documentation of this file.
1#ifndef SJEF_LIB_LOCKER_H_
2#define SJEF_LIB_LOCKER_H_
3#define BOOST_ALL_NO_LIB
4#include <filesystem>
5#include <map>
6#include <mutex>
7#include <string>
8#include <thread>
9namespace fs = std::filesystem;
10
12class file_lock;
13}
14
15namespace sjef::util {
32class Locker {
33public:
34 explicit Locker(fs::path path);
35 virtual ~Locker();
36 const fs::path& path() const { return m_path; }
37
38 void add_bolt();
40
41private:
42 const fs::path m_path;
43 std::unique_ptr<std::scoped_lock<std::mutex>> m_lock;
44 std::mutex m_mutex;
45 // Guards m_bolts, m_owning_thread and m_file_lock against add_bolt()'s reentrant-call check,
46 // which (by design) has to read m_owning_thread/m_bolts *before* it knows whether this thread
47 // already holds m_mutex -- so that read can't itself be protected by m_mutex. Without a separate
48 // mutex for just these fields, that read races every other thread's writes to them.
49 std::mutex m_state_mutex;
50 int m_bolts = 0;
51 // Opened lazily, only while a bolt is actually held (see add_bolt()/remove_bolt()), rather than
52 // for this Locker's whole lifetime: a Locker lives in a process-wide, path-keyed cache for as
53 // long as any Project pointing at that path is alive, so an eagerly-opened, never-closed handle
54 // here means one leaked file descriptor per distinct project path ever opened, for the life of
55 // the process -- fine for a handful of projects, but exhausted a constrained file descriptor
56 // budget outright on a workload that legitimately visits thousands of distinct paths (many
57 // parameter variants across many molecules) while keeping every resulting Project alive.
58 std::unique_ptr<boost::interprocess::file_lock> m_file_lock;
59 std::thread::id m_owning_thread;
60
61public:
62 // RAII
63 struct Bolt {
64 explicit Bolt(Locker& locker);
66 Bolt() = delete;
67 Bolt(const Bolt&) = delete;
68 Bolt& operator=(const Bolt&) = delete;
69
70 private:
71 Locker& m_locker;
72 };
74};
75
76} // namespace sjef::util
77#endif // SJEF_LIB_LOCKER_H_
A thread-safe class for an inter-thread/inter-process lock. The lock mechanism is based on a locked f...
Definition Locker.h:32
const fs::path & path() const
Definition Locker.h:36
Locker(fs::path path)
Definition Locker.h:11
Definition sjef.h:26
Definition Locker.h:63
Bolt(const Bolt &)=delete
Bolt & operator=(const Bolt &)=delete
Bolt(Locker &locker)