120 {
121 LLFIO_LOG_FUNCTION_CALL(this);
122 std::chrono::steady_clock::time_point began_steady;
123 std::chrono::system_clock::time_point end_utc;
124 if(d)
125 {
126 if((d).steady)
127 {
128 began_steady = std::chrono::steady_clock::now();
129 }
130 else
131 {
132 end_utc = (d).to_time_point();
133 }
134 }
135
136 auto disableunlock = make_scope_exit([&]() noexcept { out.release(); });
137 size_t n;
138 for(;;)
139 {
140 auto was_contended = static_cast<size_t>(-1);
141 {
142 auto undo = make_scope_exit([&]() noexcept {
143
144 if(n > 0)
145 {
146 --n;
147
148 for(; n > 0; n--)
149 {
151 }
153 }
154 });
155 for(n = 0; n < out.entities.size(); n++)
156 {
157 deadline nd;
158
159 if(n != 0u)
160 {
161 nd = deadline(std::chrono::seconds(0));
162 }
163 else
164 {
165 nd = deadline();
166 if(d)
167 {
168 if((d).steady)
169 {
170 std::chrono::nanoseconds ns = std::chrono::duration_cast<std::chrono::nanoseconds>((began_steady + std::chrono::nanoseconds((d).nsecs)) - std::chrono::steady_clock::now());
171 if(ns.count() < 0)
172 {
173 (nd).nsecs = 0;
174 }
175 else
176 {
177 (nd).nsecs = ns.count();
178 }
179 }
180 else
181 {
182 (nd) = (d);
183 }
184 }
185 }
187 if(!outcome)
188 {
189 was_contended = n;
190 goto failed;
191 }
192 outcome.value().release();
193 }
194
195 undo.release();
196 disableunlock.release();
197 return success();
198 }
199 failed:
200 if(d)
201 {
202 if((d).steady)
203 {
204 if(std::chrono::steady_clock::now() >= (began_steady + std::chrono::nanoseconds((d).nsecs)))
205 {
206 return errc::timed_out;
207 }
208 }
209 else
210 {
211 if(std::chrono::system_clock::now() >= end_utc)
212 {
213 return errc::timed_out;
214 }
215 }
216 }
217
218 std::swap(out.entities[was_contended], out.entities[0]);
219 auto front = out.entities.begin();
220 ++front;
221 QUICKCPPLIB_NAMESPACE::algorithm::small_prng::random_shuffle(front, out.entities.end());
222 if(!spin_not_sleep)
223 {
224 std::this_thread::yield();
225 }
226 }
227
228 }
virtual void unlock_file_range(extent_type offset, extent_type bytes) noexcept
EXTENSION: Unlocks a byte range previously locked.
virtual result< extent_guard > lock_file_range(extent_type offset, extent_type bytes, lock_kind kind, deadline d=deadline()) noexcept
EXTENSION: Tries to lock the range of bytes specified for shared or exclusive access....
@ shared
Exclude only those requesting an exclusive lock on the same inode.
@ exclusive
Exclude those requesting any kind of lock on the same inode.