Nix 2.26.3
Nix, the purely functional package manager; unstable internal interfaces
 
Loading...
Searching...
No Matches
sync.hh
Go to the documentation of this file.
1#pragma once
3
4#include <cstdlib>
5#include <mutex>
6#include <shared_mutex>
7#include <condition_variable>
8#include <cassert>
9
10#include "error.hh"
11
12namespace nix {
13
30template<class T, class M, class WL, class RL>
31class SyncBase
32{
33private:
34 M mutex;
35 T data;
36
37public:
38
39 SyncBase() { }
40 SyncBase(const T & data) : data(data) { }
41 SyncBase(T && data) noexcept : data(std::move(data)) { }
42
43 template<class L>
44 class Lock
45 {
46 protected:
47 SyncBase * s;
48 L lk;
49 friend SyncBase;
50 Lock(SyncBase * s) : s(s), lk(s->mutex) { }
51 public:
52 Lock(Lock && l) : s(l.s) { unreachable(); }
53 Lock(const Lock & l) = delete;
54 ~Lock() { }
55
56 void wait(std::condition_variable & cv)
57 {
58 assert(s);
59 cv.wait(lk);
60 }
61
62 template<class Rep, class Period>
63 std::cv_status wait_for(std::condition_variable & cv,
64 const std::chrono::duration<Rep, Period> & duration)
65 {
66 assert(s);
67 return cv.wait_for(lk, duration);
68 }
69
70 template<class Rep, class Period, class Predicate>
71 bool wait_for(std::condition_variable & cv,
72 const std::chrono::duration<Rep, Period> & duration,
73 Predicate pred)
74 {
75 assert(s);
76 return cv.wait_for(lk, duration, pred);
77 }
78
79 template<class Clock, class Duration>
80 std::cv_status wait_until(std::condition_variable & cv,
81 const std::chrono::time_point<Clock, Duration> & duration)
82 {
83 assert(s);
84 return cv.wait_until(lk, duration);
85 }
86 };
87
88 struct WriteLock : Lock<WL>
89 {
90 T * operator -> () { return &WriteLock::s->data; }
91 T & operator * () { return WriteLock::s->data; }
92 };
93
97 WriteLock lock() { return WriteLock(this); }
98
99 struct ReadLock : Lock<RL>
100 {
101 const T * operator -> () { return &ReadLock::s->data; }
102 const T & operator * () { return ReadLock::s->data; }
103 };
104
109 ReadLock readLock() const { return ReadLock(const_cast<SyncBase *>(this)); }
110};
111
112template<class T>
113using Sync = SyncBase<T, std::mutex, std::unique_lock<std::mutex>, std::unique_lock<std::mutex>>;
114
115template<class T>
116using SharedSync = SyncBase<T, std::shared_mutex, std::unique_lock<std::shared_mutex>, std::shared_lock<std::shared_mutex>>;
117
118}
WriteLock lock()
Definition sync.hh:97
ReadLock readLock() const
Definition sync.hh:109
This file defines two main structs/classes used in nix error handling.
Definition sync.hh:100
Definition sync.hh:89