Honeycomb  0.1
Component-Model Framework
Util.h
Go to the documentation of this file.
1 // Honeycomb, Copyright (C) 2015 NewGamePlus Inc. Distributed under the Boost Software License v1.0.
2 #pragma once
3 
4 #include "Honey/Misc/Range.h"
6 
7 namespace honey
8 {
10 namespace lock
11 {
12 
13 //====================================================
14 // tryLock
15 //====================================================
16 
18 inline int tryLock() { return -1; }
21 
25 template<class Lock, class... Locks, typename mt::disable_if<mt::isRange<Lock>::value, int>::type=0>
26 int tryLock(Lock& l, Locks&... ls)
27 {
29  if (!lock) return 0;
30  int failed = tryLock(ls...);
31  if (failed >= 0) return failed+1;
32  lock.release();
33  return -1;
34 }
35 
37 
40 template<class Range, typename std::enable_if<mt::isRange<Range>::value, int>::type=0>
41 auto tryLock(Range&& range) -> mt_iterOf(range)
42 {
43  auto& begin = honey::begin(range);
44  auto& end = honey::end(range);
45  if (begin == end) return end;
47  if (!lock) return begin;
48  auto failed = tryLock(honey::range(next(begin),end));
49  if (failed == end) lock.release();
50  return failed;
51 }
52 
53 //====================================================
54 // lock
55 //====================================================
56 
58 namespace priv
59 {
61  template<class Lock, class... Locks, typename mt::disable_if<mt::isRange<Lock>::value, int>::type=0>
62  int lockTest(Lock& l, Locks&... ls)
63  {
65  int failed = tryLock(ls...);
66  if (failed >= 0) return failed+1;
67  lock.release();
68  return -1;
69  }
70 
72  template<class Range, typename std::enable_if<mt::isRange<Range>::value, int>::type=0>
73  auto lockTest(Range&& range) -> mt_iterOf(range)
74  {
75  auto& begin = honey::begin(range);
76  auto& end = honey::end(range);
77  if (begin == end) return end;
78  UniqueLock<mt_iterOf(range)::value_type> lock(*begin);
79  auto failed = tryLock(honey::range(next(begin),end));
80  if (failed == end) lock.release();
81  return failed;
82  }
83 
84  template<class Locks, szt... Seq>
85  void lock(Locks&& locks, mt::idxseq<Seq...>)
86  {
87  auto switch_ = mt::make_array<function<int ()>>([&]() -> int
88  {
89  const int offset = Seq;
90  int failed;
91  if ((failed = priv::lockTest(get<(offset+Seq) % sizeof...(Seq)>(locks)...)) == -1) return -1;
92  return (offset+failed) % sizeof...(Seq);
93  }...);
94  int lockFirst = 0;
95  while(lockFirst >= 0) lockFirst = switch_[lockFirst]();
96  }
97 }
100 
109 template<class... Locks, typename mt::disable_if<mt::isRange<mt::typeAt<0, Locks...>>::value, int>::type=0>
110 void lock(Locks&&... locks) { priv::lock(forward_as_tuple(forward<Locks>(locks)...), mt::make_idxseq<sizeof...(Locks)>()); }
111 
113 template<class Range, typename std::enable_if<mt::isRange<Range>::value, int>::type=0>
114 void lock(Range&& range)
115 {
116  auto lockFirst = begin(range);
117  while(true)
118  {
119  auto it = ringRange(range,lockFirst);
120  if ((lockFirst = priv::lockTest(it)) == end(it).iter()) break;
121  }
122 }
123 
124 } }
A scoped lock that references any lockable. Locks on construction and unlocks on destruction.
Definition: Mutex.h:10
Lock (blocking)
Try to lock (non-blocking)
void lock(Locks &&...locks)
Lock all lockables safely without deadlocking.
Definition: Util.h:110
auto ringRange(Range &&range, const Iter &cur) -> Range_< RingIter< Range, Iter >, RingIter< Range, Iter >>
Create an iterator adapter range that does one full cyclic loop starting at cur through the range...
Definition: Range.h:704
std::enable_if<!b, T > disable_if
Opposite of std::enable_if.
Definition: Meta.h:62
Lockable & release()
Release the mutex from further operations. The mutex will no longer be owned and its state will remai...
Definition: Unique.h:147
std::enable_if< mt::isIterator< Iter1 >::value, Range_< Iter1, Iter2 > >::type range(Iter1 &&first, Iter2 &&last)
Range from iterators [first, last)
Definition: Range.h:116
void lock(Range &&range)
Lock all lockables in a range safely without deadlocking.
Definition: Util.h:114
#define mt_iterOf(Range)
iterOf for values
Definition: Range.h:33
size_t szt
Size type, shorthand for size_t.
Definition: Core.h:90
typename priv::typeAt< 0, I, Ts... >::type typeAt
Get type at index of parameter pack.
Definition: Meta.h:106
std::make_index_sequence< N > make_idxseq
Shorthand for std::make_index_sequence.
Definition: Meta.h:113
Global Honeycomb namespace.
int tryLock(Lock &l, Locks &...ls)
Try to lock all lockables. Locks either all or none.
Definition: Util.h:26