YSTest: pseudo_mutex.h 源文件

YSTest PreAlpha_b700_20160611 The YSLib Test Project

- 首页
- 相关页面
- 模块
- 命名空间
- 类
- 文件

- 文件列表
- 文件成员

pseudo_mutex.h
浏览该文件的文档.
1 /*
2 © 2014-2016 FrankHB.
3
4 This file is part of the YSLib project, and may only be used,
5 modified, and distributed under the terms of the YSLib project
6 license, LICENSE.TXT. By continuing to use, modify, or distribute
7 this file you indicate that you have read the license and
8 understand and accept it fully.
9 */
10
28 #ifndef YB_INC_ystdex_pseudo_mutex_h_
29 #define YB_INC_ystdex_pseudo_mutex_h_ 1
30
31 #include "base.h" // for noncopyable, nonmovable, std::declval;
32 #include <chrono> // for std::chrono::duration, std::chrono::time_point;
33 #include "exception.h" // for throw_error, std::errc;
34
35 namespace ystdex
36 {
37
44 namespace single_thread
45 {
46
48
49 yconstexpr const struct defer_lock_t
50 {} defer_lock{};
51
52 yconstexpr const struct try_to_lock_t
53 {} try_to_lock{};
54
55 yconstexpr const struct adopt_lock_t
56 {} adopt_lock{};
57
58
60
61
63 class YB_API mutex : private yimpl(noncopyable), private yimpl(nonmovable)
64 {
65 public:
66 yconstfn
67 mutex() yimpl(= default);
68 ~mutex() yimpl(= default);
69
71 void
72 lock() yimpl(ynothrow)
73 {}
74
75 bool
76 try_lock() yimpl(ynothrow)
77 {
78 return true;
79 }
80
82 void
83 unlock() yimpl(ynothrow)
84 {}
85 };
86
87
88 class YB_API recursive_mutex
89 : private yimpl(noncopyable), private yimpl(nonmovable)
90 {
91 public:
92 recursive_mutex() yimpl(= default);
93 ~recursive_mutex() yimpl(= default);
94
95 void
96 lock() yimpl(ynothrow)
97 {}
98
99 bool
100 try_lock() yimpl(ynothrow)
101 {
102 return true;
103 }
104
106 void
107 unlock() yimpl(ynothrow)
108 {}
109 };
110
111
113
114 class YB_API timed_mutex : private yimpl(noncopyable), private yimpl(nonmovable)
115 {
116 public:
117 timed_mutex() yimpl(= default);
118 ~timed_mutex() yimpl(= default);
119
121
122 void
123 lock() yimpl(ynothrow)
124 {}
125
126 bool
127 try_lock() yimpl(ynothrow)
128 {
129 return true;
130 }
131
132 template<typename _tRep, typename _tPeriod>
133 bool
134 try_lock_for(const std::chrono::duration<_tRep, _tPeriod>&) yimpl(ynothrow)
135 {
136 return true;
137 }
138
139 template<typename _tClock, typename _tDuration>
140 bool
141 try_lock_until(const std::chrono::time_point<_tClock, _tDuration>&)
142 yimpl(ynothrow)
143 {
144 return true;
145 }
147
149 void
150 unlock() yimpl(ynothrow)
151 {}
152 };
153
154
155 class YB_API recursive_timed_mutex
156 : private yimpl(noncopyable), private yimpl(nonmovable)
157 {
158 public:
159 recursive_timed_mutex() yimpl(= default);
160 ~recursive_timed_mutex() yimpl(= default);
161
162 void
163 lock() yimpl(ynothrow)
164 {}
165
166 bool
167 try_lock() yimpl(ynothrow)
168 {
169 return true;
170 }
171
172 template<typename _tRep, typename _tPeriod>
173 bool
174 try_lock_for(const std::chrono::duration<_tRep, _tPeriod>&) yimpl(ynothrow)
175 {
176 return true;
177 }
178
179 template<typename _tClock, typename _tDuration>
180 bool
181 try_lock_until(const std::chrono::time_point<_tClock, _tDuration>&)
182 yimpl(ynothrow)
183 {
184 return true;
185 }
186
188 void
189 unlock() yimpl(ynothrow)
190 {}
191 };
193
194
195
196 template<class _tMutex>
197 class lock_guard : private yimpl(noncopyable), private yimpl(nonmovable)
198 {
199 public:
200 using mutex_type = _tMutex;
201
202 #ifdef NDEBUG
203 explicit
204 lock_guard(mutex_type&) yimpl(ynothrow)
205 {}
206 lock_guard(mutex_type&, adopt_lock_t) yimpl(ynothrow)
207 {}
208
209 #else
210 private:
211 mutex_type& pm;
212
213 public:
218 explicit
219 lock_guard(mutex_type& m) yimpl(ynothrow)
220 : pm(m)
221 {
222 m.lock();
223 }
228 lock_guard(mutex_type& m, adopt_lock_t) yimpl(ynothrow)
229 : pm(&m)
230 {}
231 ~lock_guard() yimpl(ynothrow)
232 {
233 pm.unlock();
234 }
235 #endif
236 };
237
238
240
241 template<class _tMutex>
242 class unique_lock : private yimpl(noncopyable)
243 {
244 public:
245 using mutex_type = _tMutex;
246
247 #ifdef NDEBUG
248
250 unique_lock() yimpl(= default);
251 explicit
252 unique_lock(mutex_type&) yimpl(ynothrow)
253 {}
255 unique_lock(mutex_type&, defer_lock_t) ynothrow
256 {}
257 unique_lock(mutex_type&, try_to_lock_t) yimpl(ynothrow)
258 {}
259 unique_lock(mutex_type&, adopt_lock_t) yimpl(ynothrow)
260 {}
261 template<typename _tClock, typename _tDuration>
262 unique_lock(mutex_type&,
263 const std::chrono::time_point<_tClock, _tDuration>&) yimpl(ynothrow)
264 {}
265 template<typename _tRep, typename _tPeriod>
266 unique_lock(mutex_type&, const std::chrono::duration<_tRep, _tPeriod>&)
267 yimpl(ynothrow)
268 {}
269 unique_lock(unique_lock&&) yimpl(= default);
270
271 explicit
272 operator bool() const ynothrow
273 {
274 return true;
275 }
276
277 void
278 lock()
279 {}
280
281 bool
282 owns_lock() const ynothrow
283 {
284 return true;
285 }
286
287 mutex_type*
288 release() ynothrow
289 {
290 return {};
291 }
292
293 void
294 swap(unique_lock&) ynothrow
295 {}
296
297 bool
298 try_lock() yimpl(ynothrow)
299 {
300 return true;
301 }
302
303 template<typename _tRep, typename _tPeriod>
304 bool
305 try_lock_for(const std::chrono::duration<_tRep, _tPeriod>&) yimpl(ynothrow)
306 {
307 return true;
308 }
309
310 template<typename _tClock, typename _tDuration>
311 bool
312 try_lock_until(const std::chrono::time_point<_tClock, _tDuration>&)
313 yimpl(ynothrow)
314 {
315 return true;
316 }
317
318 void
319 unlock() yimpl(ynothrow)
320 {}
321
322 mutex_type*
323 mutex() const ynothrow
324 {
325 return {};
326 }
328 #else
329 private:
330 mutex_type* pm;
331 bool owns;
332
333 public:
334 unique_lock() ynothrow
335 : pm(), owns()
336 {}
337
339
340 explicit
341 unique_lock(mutex_type& m) yimpl(ynothrow)
342 : unique_lock(m, defer_lock)
343 {
344 lock();
345 owns = true;
346 }
347 unique_lock(mutex_type& m, defer_lock_t) ynothrow
348 : pm(&m), owns()
349 {}
354 unique_lock(mutex_type& m, try_to_lock_t) yimpl(ynothrow)
355 : pm(&m), owns(pm->try_lock())
356 {}
358 unique_lock(mutex_type& m, adopt_lock_t) yimpl(ynothrow)
359 : pm(&m), owns(true)
360 {}
366 template<typename _tClock, typename _tDuration>
367 unique_lock(mutex_type& m, const std::chrono::time_point<_tClock,
368 _tDuration>& abs_time) yimpl(ynothrow)
369 : pm(&m), owns(pm->try_lock_until(abs_time))
370 {}
371 template<typename _tRep, typename _tPeriod>
372 unique_lock(mutex_type& m,
373 const std::chrono::duration<_tRep, _tPeriod>& rel_time) yimpl(ynothrow)
374 : pm(&m), owns(pm->try_lock_for(rel_time))
375 {}
377
378
382 unique_lock(unique_lock&& u) ynothrow
383 : pm(u.pm), owns(u.owns)
384 {
385 yunseq(u.pm = {}, u.owns = {});
386 }
387 ~unique_lock()
388 {
389 if(owns)
390 unlock();
391 }
392
398 unique_lock&
399 operator=(unique_lock&& u) yimpl(ynothrow)
400 {
401 if(owns)
402 unlock();
403 unique_lock(std::move(u)).swap(*this);
404 u.clear_members();
405 return *this;
406 }
407
408 explicit
409 operator bool() const ynothrow
410 {
411 return owns;
412 }
413
414 private:
415 void
416 check_lock() yimpl(ynothrow)
417 {
418 using namespace std;
419
420 if(!pm)
421 throw_error(errc::operation_not_permitted);
422 if(owns)
423 throw_error(errc::resource_deadlock_would_occur);
424 }
425
426 void
427 clear_members() yimpl(ynothrow)
428 {
429 yunseq(pm = {}, owns = {});
430 }
431
432 public:
433 void
434 lock() yimpl(ynothrow)
435 {
436 check_lock();
437 pm->lock();
438 owns = true;
439 }
440
441 bool
442 owns_lock() const ynothrow
443 {
444 return owns;
445 }
446
447 mutex_type*
448 release() ynothrow
449 {
450 const auto res(pm);
451
452 clear_members();
453 return res;
454 }
455
456 void
457 swap(unique_lock& u) ynothrow
458 {
459 std::swap(pm, u.pm),
460 std::swap(owns, u.owns);
461 }
462
464 bool
465 try_lock() yimpl(ynothrow)
466 {
467 check_lock();
468 return owns = pm->lock();
469 }
470
472
473 template<typename _tRep, typename _tPeriod>
474 bool
475 try_lock_for(const std::chrono::duration<_tRep, _tPeriod>& rel_time)
476 yimpl(ynothrow)
477 {
478 check_lock();
479 return owns = pm->try_lock_for(rel_time);
480 }
481
482 template<typename _tClock, typename _tDuration>
483 bool
484 try_lock_until(const std::chrono::time_point<_tClock, _tDuration>& abs_time)
485 yimpl(ynothrow)
486 {
487 check_lock();
488 return owns = pm->try_lock_until(abs_time);
489 }
491
492 void
493 unlock() yimpl(ynothrow)
494 {
495 if(!owns)
496 throw_error(std::errc::operation_not_permitted);
497 if(pm)
498 {
499 pm->unlock();
500 owns = {};
501 }
502 }
503
504 mutex_type*
505 mutex() const ynothrow
506 {
507 return pm;
508 }
509 #endif
510 };
511
512
514 struct YB_API once_flag : private yimpl(noncopyable), private yimpl(nonmovable)
515 {
516 yimpl(bool) state = {};
517
518 yconstfn
519 once_flag() ynothrow yimpl(= default);
520 };
521
522
535 template<typename _fCallable, typename... _tParams>
536 inline void
537 call_once(once_flag& flag, _fCallable&& f, _tParams&&... args)
538 {
539 if(!flag.state)
540 {
541 f(yforward(args)...);
542 flag.state = true;
543 }
544 }
546
548 template<class _tMutex>
549 inline void
550 swap(unique_lock<_tMutex>& x, unique_lock<_tMutex>& y) ynothrow
551 {
552 x.swap(y);
553 }
554
555
556 template<class _tLock1, class _tLock2, class... _tLocks>
557 void
558 lock(_tLock1&&, _tLock2&&, _tLocks&&...) yimpl(ynothrow)
559 {}
560
561 template<class _tLock1, class _tLock2, class... _tLocks>
562 yconstfn int
563 try_lock(_tLock1&&, _tLock2&&, _tLocks&&...) yimpl(ynothrow)
564 {
565 return -1;
566 }
568
569
570 } // namespace single_thread;
571
572
577 namespace threading
578 {
579
585 template<class _tMutex = single_thread::mutex,
586 class _tLock = single_thread::unique_lock<_tMutex>>
587 class unlock_delete : private noncopyable
588 {
589 public:
590 using mutex_type = _tMutex;
591 using lock_type = _tLock;
592
593 mutable lock_type lock;
594
595 unlock_delete(mutex_type& mtx)
596 : lock(mtx)
597 {}
598 template<typename
599 = yimpl(enable_if_t)<is_nothrow_move_constructible<lock_type>::value>>
600 unlock_delete(lock_type&& lck) ynothrow
601 : lock(std::move(lck))
602 {}
603 template<typename... _tParams>
604 unlock_delete(mutex_type& mtx, _tParams&&... args) ynoexcept(
605 std::declval<mutex_type&>()(std::declval<_tParams&&>()...))
606 : lock(mtx, yforward(args)...)
607 {}
608
610 template<typename _tPointer>
611 void
612 operator()(const _tPointer&) const ynothrow
613 {
614 lock.unlock();
615 }
616 };
617
618
623 template<typename _type, class _tMutex = single_thread::mutex,
624 class _tLock = single_thread::unique_lock<_tMutex>>
625 using locked_ptr = std::unique_ptr<_type, unlock_delete<_tMutex, _tLock>>;
626
627 } // namespace threading;
628
629 } // namespace ystdex;
630
631 #endif
632
ystdex::single_thread::unique_lock::pm
mutex_type * pm
Definition: pseudo_mutex.h:330
ystdex::single_thread::timed_mutex::try_lock_for
bool try_lock_for(const std::chrono::duration< _tRep, _tPeriod > &)
Definition: pseudo_mutex.h:134
ystdex::single_thread::unique_lock::try_lock
bool try_lock()
Definition: pseudo_mutex.h:465
YSLib::Drawing::x
The boundary is out of the const Rect SDst SPos x
Definition: YDraw.h:127
ystdex::single_thread::lock_guard::lock_guard
lock_guard(mutex_type &m, adopt_lock_t)
Definition: pseudo_mutex.h:228
yconstexpr
#define yconstexpr
指定编译时常量表达式。
Definition: ydef.h:653
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:740
ystdex::single_thread::unique_lock::unique_lock
unique_lock(unique_lock &&u)
Definition: pseudo_mutex.h:382
ystdex::single_thread::recursive_mutex::lock
void lock()
Definition: pseudo_mutex.h:96
ystdex::single_thread::unique_lock::clear_members
void clear_members()
Definition: pseudo_mutex.h:427
ystdex::swap
void swap(container_adaptor< _tSeqCon > &x, container_adaptor< _tSeqCon > &y)
Definition: container.hpp:179
ystdex::cpp2014::enable_if_t
typename enable_if< _bCond, _type >::type enable_if_t
Definition: type_traits.hpp:350
ystdex::single_thread::unique_lock::mutex_type
_tMutex mutex_type
Definition: pseudo_mutex.h:245
ystdex::single_thread::recursive_timed_mutex
Definition: pseudo_mutex.h:155
ystdex::single_thread::unique_lock::check_lock
void check_lock()
Definition: pseudo_mutex.h:416
ystdex::single_thread::timed_mutex::try_lock_until
bool try_lock_until(const std::chrono::time_point< _tClock, _tDuration > &)
Definition: pseudo_mutex.h:141
ystdex::single_thread::unique_lock::unique_lock
unique_lock()
Definition: pseudo_mutex.h:334
ystdex::single_thread::unique_lock::release
mutex_type * release()
Definition: pseudo_mutex.h:448
ystdex::single_thread::recursive_mutex::try_lock
bool try_lock()
Definition: pseudo_mutex.h:100
ystdex::single_thread::defer_lock
const struct ystdex::single_thread::defer_lock_t defer_lock
ystdex::threading::unlock_delete::unlock_delete
unlock_delete(lock_type &&lck)
Definition: pseudo_mutex.h:600
ystdex::single_thread::unique_lock::swap
void swap(unique_lock< _tMutex > &x, unique_lock< _tMutex > &y)
Definition: pseudo_mutex.h:550
ystdex::single_thread::unique_lock::unique_lock
unique_lock(mutex_type &m, adopt_lock_t)
Definition: pseudo_mutex.h:358
ystdex::single_thread::unique_lock::~unique_lock
~unique_lock()
Definition: pseudo_mutex.h:387
ystdex::threading::unlock_delete::unlock_delete
unlock_delete(mutex_type &mtx, _tParams &&...args)
Definition: pseudo_mutex.h:604
ystdex::single_thread::call_once
void call_once(once_flag &flag, _fCallable &&f, _tParams &&...args)
按标识调用函数，保证调用一次。
Definition: pseudo_mutex.h:537
ystdex::single_thread::timed_mutex
Definition: pseudo_mutex.h:114
ystdex::single_thread::unique_lock::lock
void lock()
Definition: pseudo_mutex.h:434
ystdex::single_thread::unique_lock
Definition: pseudo_mutex.h:242
ystdex::single_thread::adopt_lock
const struct ystdex::single_thread::adopt_lock_t adopt_lock
yimpl
#define yimpl(...)
实现标签。
Definition: ydef.h:256
YB_API
#define YB_API
YBase 应用程序编程接口：用于向库文件约定链接。
Definition: ydef.h:566
ystdex::single_thread::unique_lock::operator=
unique_lock & operator=(unique_lock &&u)
Definition: pseudo_mutex.h:399
ystdex::single_thread::unique_lock::swap
void swap(unique_lock &u)
Definition: pseudo_mutex.h:457
ystdex::single_thread::adopt_lock_t
Definition: pseudo_mutex.h:55
ystdex::single_thread::unique_lock::try_lock_for
bool try_lock_for(const std::chrono::duration< _tRep, _tPeriod > &rel_time)
Definition: pseudo_mutex.h:475
ystdex::throw_error
void throw_error(std::error_code ec, _tParams &&...args)
抛出错误： std::system_error 或允许相同构造函数参数的异常。
Definition: ystdex/exception.h:162
base.h
基类实用设施。
std
Definition: memory.hpp:1100
exception.h
ystdex::single_thread::unique_lock::unique_lock
unique_lock(mutex_type &m)
Definition: pseudo_mutex.h:341
ystdex::threading::unlock_delete::lock
lock_type lock
Definition: pseudo_mutex.h:593
ystdex::single_thread::try_to_lock
const struct ystdex::single_thread::try_to_lock_t try_to_lock
ystdex::single_thread::recursive_mutex::unlock
void unlock()
Definition: pseudo_mutex.h:107
ystdex::single_thread::timed_mutex::unlock
void unlock()
Definition: pseudo_mutex.h:150
ystdex::threading::unlock_delete::mutex_type
_tMutex mutex_type
Definition: pseudo_mutex.h:590
ystdex::single_thread::recursive_timed_mutex::try_lock_for
bool try_lock_for(const std::chrono::duration< _tRep, _tPeriod > &)
Definition: pseudo_mutex.h:174
ystdex::single_thread::unique_lock::unique_lock
unique_lock(mutex_type &m, defer_lock_t)
Definition: pseudo_mutex.h:347
yunseq
#define yunseq
无序列依赖表达式组求值。
Definition: ydef.h:996
ystdex::single_thread::unique_lock::owns
bool owns
Definition: pseudo_mutex.h:331
ystdex
特性测试宏。
Definition: ydef.h:796
ystdex::single_thread::defer_lock_t
Definition: pseudo_mutex.h:49
ystdex::single_thread::recursive_timed_mutex::unlock
void unlock()
Definition: pseudo_mutex.h:189
ystdex::single_thread::unique_lock::try_lock_until
bool try_lock_until(const std::chrono::time_point< _tClock, _tDuration > &abs_time)
Definition: pseudo_mutex.h:484
ystdex::single_thread::timed_mutex::try_lock
bool try_lock()
Definition: pseudo_mutex.h:127
ystdex::threading::unlock_delete::lock_type
_tLock lock_type
Definition: pseudo_mutex.h:591
ystdex::single_thread::recursive_timed_mutex::try_lock_until
bool try_lock_until(const std::chrono::time_point< _tClock, _tDuration > &)
Definition: pseudo_mutex.h:181
ystdex::single_thread::once_flag
Definition: pseudo_mutex.h:514
YSLib::UI::y
SPos SPos y
Definition: YWidget.cpp:44
ystdex::single_thread::unique_lock::unique_lock
unique_lock(mutex_type &m, try_to_lock_t)
Definition: pseudo_mutex.h:354
ystdex::single_thread::lock_guard::mutex_type
_tMutex mutex_type
Definition: pseudo_mutex.h:200
ystdex::threading::locked_ptr
std::unique_ptr< _type, unlock_delete< _tMutex, _tLock >> locked_ptr
独占所有权的锁定指针。
Definition: pseudo_mutex.h:625
ystdex::single_thread::unique_lock::mutex
mutex_type * mutex() const
Definition: pseudo_mutex.h:505
ynoexcept
#define ynoexcept(...)
YSLib 无异常抛出保证：指定特定的异常规范。
Definition: ydef.h:720
ystdex::single_thread::mutex::unlock
void unlock()
Definition: pseudo_mutex.h:83
ystdex::single_thread::lock_guard
Definition: pseudo_mutex.h:197
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:654
ystdex::threading::unlock_delete::unlock_delete
unlock_delete(mutex_type &mtx)
Definition: pseudo_mutex.h:595
ystdex::noncopyable
不可复制对象：禁止派生类调用默认原型的复制构造函数和复制赋值操作符。
Definition: base.h:41
ystdex::single_thread::mutex
Definition: pseudo_mutex.h:63
ystdex::single_thread::lock_guard::~lock_guard
~lock_guard()
Definition: pseudo_mutex.h:231
ystdex::single_thread::unique_lock::unlock
void unlock()
Definition: pseudo_mutex.h:493
ystdex::single_thread::timed_mutex::lock
void lock()
Definition: pseudo_mutex.h:123
ystdex::single_thread::lock_guard::lock_guard
lock_guard(mutex_type &m)
Definition: pseudo_mutex.h:219
yforward
#define yforward(_expr)
根据参数类型使用 std::forward 传递对应参数。
Definition: ydef.h:969
ystdex::single_thread::recursive_mutex
Definition: pseudo_mutex.h:88
ystdex::single_thread::mutex::try_lock
bool try_lock()
Definition: pseudo_mutex.h:76
YSLib::IO::f
const string &path const String &path _func f
Definition: YSLib/Service/FileSystem.h:430
CHRLib::args
_tParams && args
Definition: CharacterProcessing.h:538
ystdex::threading::unlock_delete::operator()
void operator()(const _tPointer &) const
删除：解锁。
Definition: pseudo_mutex.h:612
ystdex::single_thread::unique_lock::unique_lock
unique_lock(mutex_type &m, const std::chrono::time_point< _tClock, _tDuration > &abs_time)
Definition: pseudo_mutex.h:367
ystdex::single_thread::try_to_lock_t
Definition: pseudo_mutex.h:52
ystdex::single_thread::lock_guard::pm
mutex_type & pm
Definition: pseudo_mutex.h:211
ystdex::single_thread::mutex::lock
void lock()
Definition: pseudo_mutex.h:72
platform::bool
std::FILE *fp bool
Definition: FileIO.h:1187
ystdex::single_thread::unique_lock::owns_lock
bool owns_lock() const
Definition: pseudo_mutex.h:442
ystdex::single_thread::recursive_timed_mutex::try_lock
bool try_lock()
Definition: pseudo_mutex.h:167
ystdex::single_thread::recursive_timed_mutex::lock
void lock()
Definition: pseudo_mutex.h:163
ystdex::single_thread::unique_lock::unique_lock
unique_lock(mutex_type &m, const std::chrono::duration< _tRep, _tPeriod > &rel_time)
Definition: pseudo_mutex.h:372
ystdex::threading::unlock_delete
解锁删除器。
Definition: pseudo_mutex.h:587