Remote Call Framework 3.3
RecursionLimiter.hpp
1 
2 //******************************************************************************
3 // RCF - Remote Call Framework
4 //
5 // Copyright (c) 2005 - 2022, Delta V Software. All rights reserved.
6 // https://www.deltavsoft.com
7 //
8 // RCF is distributed under dual licenses - closed source or GPL.
9 // Consult your particular license for conditions of use.
10 //
11 // If you have not purchased a commercial license, you are using RCF under GPL terms.
12 //
13 // Version: 3.3
14 // Contact: support <at> deltavsoft.com
15 //
16 //******************************************************************************
17 
18 #ifndef INCLUDE_RCF_RECURSIONLIMITER_HPP
19 #define INCLUDE_RCF_RECURSIONLIMITER_HPP
20 
21 #include <type_traits>
22 
23 #include <RCF/TypeTraits.hpp>
24 #include <RCF/Tools.hpp>
25 
26 namespace RCF {
27 
28  class ByteBuffer;
29 
30  template<typename T1,typename T2>
31  class RecursionState
32  {
33  public:
34  RecursionState() :
35  mRecursing(),
36  mBreak(),
37  mT1(),
38  mT2()
39  {}
40 
41  void assign(const T1 &t1)
42  {
43  mT1 = t1;
44 
45  clearArg(t1);
46  }
47 
48  void assign(const T1 &t1, const T2 &t2)
49  {
50  mT1 = t1;
51  mT2 = t2;
52 
53  clearArg(t1);
54  clearArg(t2);
55  }
56 
57  void clear()
58  {
59  mRecursing = false;
60  mBreak = true;
61  mT1 = T1();
62  mT2 = T2();
63  }
64 
65  bool mRecursing;
66  bool mBreak;
67  T1 mT1;
68  T2 mT2;
69 
70  private:
71  void clearArg_(const ByteBuffer &byteBuffer, std::true_type *)
72  {
73  const_cast<ByteBuffer &>(byteBuffer).clear();
74  }
75 
76  template<typename T>
77  void clearArg_(const T &, std::false_type *)
78  {}
79 
80  template<typename T>
81  void clearArg(const T &t)
82  {
83  typedef typename std::is_same<T, ByteBuffer>::type type;
84  clearArg_(t, (type*) 0);
85  }
86  };
87 
88  // Utility for avoiding recursive function calls on the stack, by unwinding
89  // the relevant part of the stack and then reissuing the requested function
90  // call.
91 
92  template<typename StateT, typename X, typename Pfn>
93  void applyRecursionLimiter(
94  StateT & state,
95  Pfn pfn,
96  X & x)
97  {
98  state.mBreak = false;
99 
100  if (state.mRecursing)
101  {
102  state.mRecursing = false;
103  }
104  else
105  {
106  ScopeGuard guard([&]() { state.clear(); });
107 
108  while (!state.mRecursing && !state.mBreak)
109  {
110  state.mRecursing = true;
111  ((&x)->*pfn)();
112  }
113  }
114  }
115 
116 
117  template<typename StateT, typename X, typename Pfn, typename T1>
118  void applyRecursionLimiter(
119  StateT & state,
120  Pfn pfn,
121  X & x,
122  const T1 & t1)
123  {
124  state.mBreak = false;
125 
126  state.assign(t1);
127  if (state.mRecursing)
128  {
129  state.mRecursing = false;
130  }
131  else
132  {
133  ScopeGuard guard([&]() { state.clear(); });
134 
135  while (!state.mRecursing && !state.mBreak)
136  {
137  state.mRecursing = true;
138  ((&x)->*pfn)(state.mT1);
139  }
140  }
141  }
142 
143  template<typename StateT, typename X, typename Pfn, typename T1, typename T2>
144  void applyRecursionLimiter(
145  StateT & state,
146  Pfn pfn,
147  X & x,
148  const T1 & t1,
149  const T2 & t2)
150  {
151  state.mBreak = false;
152 
153  state.assign(t1, t2);
154  if (state.mRecursing)
155  {
156  state.mRecursing = false;
157  }
158  else
159  {
160  ScopeGuard guard([&]() { state.clear(); });
161 
162  while (!state.mRecursing && !state.mBreak)
163  {
164  state.mRecursing = true;
165  ((&x)->*pfn)(state.mT1, state.mT2);
166  }
167  }
168  }
169 
170 } // namespace RCF
171 
172 #endif // ! INCLUDE_RCF_RECURSIONLIMITER_HPP
Definition: AmiIoHandler.hpp:23