Add gitlab issue/merge request templates
[staging/basesystem.git] / service / native / framework_unified / client / NS_UtilityCenter / include / ns_utility_sys_internal.hpp
1 /*
2  * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 ////////////////////////////////////////////////////////////////////////////////////////////////////
18 /// @file  ns_utility_sys_internal.hpp
19 /// @brief    This file contains declaration of common APIs for NS_UtilityCenter.
20 ///
21 ////////////////////////////////////////////////////////////////////////////////////////////////////
22 //@{
23
24 #ifndef FRAMEWORK_UNIFIED_CLIENT_NS_UTILITYCENTER_INCLUDE_NS_UTILITY_SYS_INTERNAL_HPP_
25 #define FRAMEWORK_UNIFIED_CLIENT_NS_UTILITYCENTER_INCLUDE_NS_UTILITY_SYS_INTERNAL_HPP_
26
27 #include <native_service/frameworkunified_types.h>
28 #include <pthread.h>
29 #include <errno.h>
30
31 #include <native_service/ns_utility.hpp>
32
33 UI_32 utility_sys_rand();  // NOLINT (readability/nolint)
34
35 // Random Functions //////////////////////////////////////////////////////////
36
37 template< class T>
38 T randomValue(T min, T max) {
39   const int32_t lmin = static_cast< int32_t >(min);
40   const int32_t range = static_cast< int32_t >(max) - lmin + 1;
41   if (range > 0) {
42     return static_cast< T >(utility_sys_rand() % range + lmin);
43   } else {
44     return min;
45   }
46 }
47
48 template< class T, UI_32 N >
49 T randomItem(const T(&arr)[ N ]) {
50   return arr[ randomValue< UI_32 >(0, N - 1) ];
51 }
52
53
54 template< class T, class Lock > class CLockedData;
55 template< class T, class Lock, class Fn > typename FSig< Fn >::RType WithWriteLock(Fn, CLockedData< T, Lock > &);
56 template< class T, class Lock, class Fn > typename FSig< Fn >::RType WithWriteLock(Fn, CLockedData< T, Lock > &,  // NOLINT (readability/nolint)
57                                                                                    typename FSig< Fn >::TArg2);  // NOLINT (readability/nolint)
58 template< class T, class Lock, class Fn > typename FSig< Fn >::RType WithWriteLock(Fn, CLockedData< T, Lock > &,
59                                                                                    typename FSig< Fn >::TArg2, typename FSig< Fn >::TArg3);
60 template< class T, class Lock, class Fn > typename FSig< Fn >::RType WithWriteLock(Fn, CLockedData< T, Lock > &,
61                                                                                    typename FSig< Fn >::TArg2, typename FSig< Fn >::TArg3, typename FSig< Fn >::TArg4);
62 template< class T, class Lock, class Fn > typename FSig< Fn >::RType WithWriteLock(Fn, CLockedData< T, Lock > &,
63                                                                                    typename FSig< Fn >::TArg2, typename FSig< Fn >::TArg3, typename FSig< Fn >::TArg4, typename FSig< Fn >::TArg5);
64 template< class T, class Lock, class Fn > typename FSig< Fn >::RType WithWriteLock(Fn, CLockedData< T, Lock > &,
65                                                                                    typename FSig< Fn >::TArg2, typename FSig< Fn >::TArg3, typename FSig< Fn >::TArg4, typename FSig< Fn >::TArg5,
66                                                                                    typename FSig< Fn >::TArg6);
67 template< class T, class Lock, class Fn > typename FSig< Fn >::RType WithWriteLock(Fn, CLockedData< T, Lock > &,
68                                                                                    typename FSig< Fn >::TArg2, typename FSig< Fn >::TArg3, typename FSig< Fn >::TArg4, typename FSig< Fn >::TArg5,
69                                                                                    typename FSig< Fn >::TArg6, typename FSig< Fn >::TArg7);
70 template< class T, class Lock, class Fn > typename FSig< Fn >::RType WithReadLock(Fn, CLockedData< T, Lock > &);  // NOLINT (readability/nolint)
71 template< class T, class Lock, class Fn > typename FSig< Fn >::RType WithReadLock(Fn, CLockedData< T, Lock > &,
72                                                                                   typename FSig< Fn >::TArg2);
73 template< class T, class Lock, class Fn > typename FSig< Fn >::RType WithReadLock(Fn, CLockedData< T, Lock > &,
74                                                                                   typename FSig< Fn >::TArg2, typename FSig< Fn >::TArg3);
75 template< class T, class Lock, class Fn > typename FSig< Fn >::RType WithReadLock(Fn, CLockedData< T, Lock > &,
76                                                                                   typename FSig< Fn >::TArg2, typename FSig< Fn >::TArg3, typename FSig< Fn >::TArg4);
77 template< class T, class Lock, class Fn > typename FSig< Fn >::RType WithReadLock(Fn, CLockedData< T, Lock > &,
78                                                                                   typename FSig< Fn >::TArg2, typename FSig< Fn >::TArg3, typename FSig< Fn >::TArg4, typename FSig< Fn >::TArg5);
79 template< class T, class Lock, class Fn > typename FSig< Fn >::RType WithReadLock(Fn, CLockedData< T, Lock > &,
80                                                                                   typename FSig< Fn >::TArg2, typename FSig< Fn >::TArg3, typename FSig< Fn >::TArg4, typename FSig< Fn >::TArg5,
81                                                                                   typename FSig< Fn >::TArg6);
82 template< class T, class Lock, class Fn > typename FSig< Fn >::RType WithReadLock(Fn, CLockedData< T, Lock > &,
83                                                                                   typename FSig< Fn >::TArg2, typename FSig< Fn >::TArg3, typename FSig< Fn >::TArg4, typename FSig< Fn >::TArg5,
84                                                                                   typename FSig< Fn >::TArg6, typename FSig< Fn >::TArg7);
85
86
87 template< class T, class Lock >
88 class CWithReadLock {
89  public:
90   typedef const T TData;
91
92   CWithReadLock(CLockedData< T, Lock > &);
93   ~CWithReadLock();
94
95   template< class T1, class Lock1, class Fn >
96   friend typename FSig< Fn >::RType WithReadLock(Fn, CLockedData< T1, Lock1 > &);
97
98   template< class T1, class Lock1, class Fn >
99   friend typename FSig< Fn >::RType WithReadLock(Fn, CLockedData< T1, Lock1 > &, typename FSig< Fn >::TArg2);
100
101   template< class T1, class Lock1, class Fn >
102   friend typename FSig< Fn >::RType WithReadLock(Fn, CLockedData< T1, Lock1 > &, typename FSig< Fn >::TArg2,
103                                                  typename FSig< Fn >::TArg3);
104
105   template< class T1, class Lock1, class Fn >
106   friend typename FSig< Fn >::RType WithReadLock(Fn, CLockedData< T1, Lock1 > &, typename FSig< Fn >::TArg2,
107                                                  typename FSig< Fn >::TArg3, typename FSig< Fn >::TArg4);
108
109   template< class T1, class Lock1, class Fn >
110   friend typename FSig< Fn >::RType WithReadLock(Fn, CLockedData< T1, Lock1 > &, typename FSig< Fn >::TArg2,
111                                                  typename FSig< Fn >::TArg3, typename FSig< Fn >::TArg4, typename FSig< Fn >::TArg5);
112
113   template< class T1, class Lock1, class Fn >
114   friend typename FSig< Fn >::RType WithReadLock(Fn, CLockedData< T1, Lock1 > &, typename FSig< Fn >::TArg2,
115                                                  typename FSig< Fn >::TArg3, typename FSig< Fn >::TArg4, typename FSig< Fn >::TArg5, typename FSig< Fn >::TArg6);
116
117   template< class T1, class Lock1, class Fn >
118   friend typename FSig< Fn >::RType WithReadLock(Fn, CLockedData< T1, Lock1 > &, typename FSig< Fn >::TArg2,
119                                                  typename FSig< Fn >::TArg3, typename FSig< Fn >::TArg4, typename FSig< Fn >::TArg5, typename FSig< Fn >::TArg6,
120                                                  typename FSig< Fn >::TArg7);
121
122  private:
123   DISALLOW_COPY_AND_ASSIGN(CWithReadLock);
124
125   const TData &data() const;  // NOLINT (readability/nolint)
126   CLockedData< T, Lock > &m_LockedData;
127 };
128
129 template< class T, class Lock >
130 class CWithWriteLock {
131  public:
132   typedef T TData;
133
134   CWithWriteLock(CLockedData< T, Lock > &);
135   ~CWithWriteLock();
136
137   template< class T1, class Lock1, class Fn >
138   friend typename FSig< Fn >::RType WithWriteLock(Fn, CLockedData< T1, Lock1 > &);
139
140   template< class T1, class Lock1, class Fn >
141   friend typename FSig< Fn >::RType WithWriteLock(Fn, CLockedData< T1, Lock1 > &, typename FSig< Fn >::TArg2);
142
143   template< class T1, class Lock1, class Fn >
144   friend typename FSig< Fn >::RType WithWriteLock(Fn, CLockedData< T1, Lock1 > &, typename FSig< Fn >::TArg2,
145                                                   typename FSig< Fn >::TArg3);
146
147   template< class T1, class Lock1, class Fn >
148   friend typename FSig< Fn >::RType WithWriteLock(Fn, CLockedData< T1, Lock1 > &, typename FSig< Fn >::TArg2,
149                                                   typename FSig< Fn >::TArg3, typename FSig< Fn >::TArg4);
150
151   template< class T1, class Lock1, class Fn >
152   friend typename FSig< Fn >::RType WithWriteLock(Fn, CLockedData< T1, Lock1 > &, typename FSig< Fn >::TArg2,
153                                                   typename FSig< Fn >::TArg3, typename FSig< Fn >::TArg4, typename FSig< Fn >::TArg5);
154
155   template< class T1, class Lock1, class Fn >
156   friend typename FSig< Fn >::RType WithWriteLock(Fn, CLockedData< T1, Lock1 > &, typename FSig< Fn >::TArg2,
157                                                   typename FSig< Fn >::TArg3, typename FSig< Fn >::TArg4, typename FSig< Fn >::TArg5, typename FSig< Fn >::TArg6);
158
159   template< class T1, class Lock1, class Fn >
160   friend typename FSig< Fn >::RType WithWriteLock(Fn, CLockedData< T1, Lock1 > &, typename FSig< Fn >::TArg2,
161                                                   typename FSig< Fn >::TArg3, typename FSig< Fn >::TArg4, typename FSig< Fn >::TArg5, typename FSig< Fn >::TArg6,
162                                                   typename FSig< Fn >::TArg7);
163
164  private:
165   DISALLOW_COPY_AND_ASSIGN(CWithWriteLock);
166
167   TData &data();  // NOLINT (readability/nolint)
168   CLockedData< T, Lock > &m_LockedData;
169 };
170
171 /// \brief Represents a piece of data protected by a lock
172 ///
173 /// Data wrapped with Can only be accessed using helper functions
174 /// WithReadLock and WithWriteLock
175 ///
176 /// Example usage:
177 ///
178 /// void ModifySharedData( int& n ) { ... modify n ... };
179 /// int ReadSharedData( const int& n ){ ... read n ... };
180 ///
181 /// void DoSomething()
182 /// {
183 ///   CLocked< int > my_data( -1 );  // initialize value to -1
184 ///   WithWriteLock( ModifySharedData, my_data );
185 ///   int val = WithReadLock( ReadSharedData, my_data );
186 /// }
187 ///
188 /// NOTE: that data is locked for the duration of the time that helper functions
189 /// ModifySharedData, and ReadSharedData are called - once they return, the data becomes
190 /// unlocked automatically.
191 template< class T, class Lock = CMutex >
192 class CLockedData {
193  public:
194   typedef CWithReadLock< T, Lock > TReadLock;
195   typedef CWithWriteLock< T, Lock > TWriteLock;
196
197   CLockedData() {}
198   template< class T1 > CLockedData(T1 t1) : m_data(t1) {}
199   template< class T1, class T2 > CLockedData(T1 t1, T2 t2) : m_data(t1, t2) {}
200   template< class T1, class T2, class T3 > CLockedData(T1 t1, T2 t2, T3 t3) : m_data(t1, t2, t3) {}
201   template< class T1, class T2, class T3, class T4 > CLockedData(T1 t1, T2 t2, T3 t3, T4 t4) : m_data(t1, t2, t3,
202                                                                                                         t4) {}
203   template< class T1, class T2, class T3, class T4, class T5 > CLockedData(T1 t1, T2 t2, T3 t3, T4 t4,
204                                                                            T5 t5) : m_data(t1, t2, t3, t4, t5) {}
205   template< class T1, class T2, class T3, class T4, class T5, class T6 > CLockedData(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5,
206                                                                                      T6 t6) : m_data(t1, t2, t3, t4, t5, t6) {}
207   template< class T1, class T2, class T3, class T4, class T5, class T6, class T7 > CLockedData(T1 t1, T2 t2, T3 t3,
208                                                                                                T4 t4, T5 t5, T6 t6, T7 t7) : m_data(t1, t2, t3, t4, t5, t6, t7) {}
209
210   friend class CWithReadLock< T, Lock >;
211   friend class CWithWriteLock< T, Lock >;
212
213  private:
214   T m_data;
215   Lock m_lock;
216 };
217
218 // CWithReadLock and CWithWriteLock implementation //////////////////////////////////////////////
219
220 template< class T, class Lock >
221 CWithReadLock< T, Lock >::CWithReadLock(CLockedData< T, Lock > &ld) : m_LockedData(ld) {
222   m_LockedData.m_lock.ReadLock();
223 }
224
225 template< class T, class Lock >
226 CWithReadLock< T, Lock >::~CWithReadLock() {
227   m_LockedData.m_lock.Unlock();
228 }
229
230 template< class T, class Lock >
231 const typename CWithReadLock< T, Lock >::TData &CWithReadLock< T, Lock >::data() const {  // NOLINT (readability/nolint)
232   return m_LockedData.m_data;
233 }
234
235 template< class T, class Lock >
236 CWithWriteLock< T, Lock >::CWithWriteLock(CLockedData< T, Lock > &ld) :  m_LockedData(ld) {
237   m_LockedData.m_lock.WriteLock();
238 }
239
240 template< class T, class Lock >
241 CWithWriteLock< T, Lock >::~CWithWriteLock() {
242   m_LockedData.m_lock.Unlock();
243 }
244
245 template< class T, class Lock >
246 typename CWithWriteLock< T, Lock >::TData &CWithWriteLock< T, Lock >::data() {  // NOLINT (readability/nolint)
247   return m_LockedData.m_data;
248 }
249
250 // WithReadLock / WithWriteLock ///////////////////////////////////////////////
251
252 template< class T, class Lock, class Fn >
253 typename FSig< Fn >::RType WithReadLock(Fn f, CLockedData< T, Lock > &data) {
254   typename CLockedData< T, Lock >::TReadLock rl(data);
255   return f(rl.data());
256 }
257
258 template< class T, class Lock, class Fn >
259 typename FSig< Fn >::RType WithReadLock(Fn f, CLockedData< T, Lock > &data, typename FSig< Fn >::TArg2 t2) {
260   typename CLockedData< T, Lock >::TReadLock rl(data);
261   return f(rl.data(), t2);
262 }
263
264 template< class T, class Lock, class Fn >
265 typename FSig< Fn >::RType WithReadLock(Fn f, CLockedData< T, Lock > &data, typename FSig< Fn >::TArg2 t2,
266                                         typename FSig< Fn >::TArg3 t3) {
267   typename CLockedData< T, Lock >::TReadLock rl(data);
268   return f(rl.data(), t2, t3);
269 }
270
271 template< class T, class Lock, class Fn >
272 typename FSig< Fn >::RType WithReadLock(Fn f, CLockedData< T, Lock > &data, typename FSig< Fn >::TArg2 t2,
273                                         typename FSig< Fn >::TArg3 t3, typename FSig< Fn >::TArg4 t4) {
274   typename CLockedData< T, Lock >::TReadLock rl(data);
275   return f(rl.data(), t2, t3, t4);
276 }
277
278 template< class T, class Lock, class Fn >
279 typename FSig< Fn >::RType WithReadLock(Fn f, CLockedData< T, Lock > &data, typename FSig< Fn >::TArg2 t2,
280                                         typename FSig< Fn >::TArg3 t3, typename FSig< Fn >::TArg4 t4, typename FSig< Fn >::TArg5 t5) {
281   typename CLockedData< T, Lock >::TReadLock rl(data);
282   return f(rl.data(), t2, t3, t4, t5);
283 }
284
285 template< class T, class Lock, class Fn >
286 typename FSig< Fn >::RType WithReadLock(Fn f, CLockedData< T, Lock > &data, typename FSig< Fn >::TArg2 t2,
287                                         typename FSig< Fn >::TArg3 t3, typename FSig< Fn >::TArg4 t4, typename FSig< Fn >::TArg5 t5,
288                                         typename FSig< Fn >::TArg6 t6) {
289   typename CLockedData< T, Lock >::TReadLock rl(data);
290   return f(rl.data(), t2, t3, t4, t5, t6);
291 }
292
293 template< class T, class Lock, class Fn >
294 typename FSig< Fn >::RType WithReadLock(Fn f, CLockedData< T, Lock > &data, typename FSig< Fn >::TArg2 t2,
295                                         typename FSig< Fn >::TArg3 t3, typename FSig< Fn >::TArg4 t4, typename FSig< Fn >::TArg5 t5,
296                                         typename FSig< Fn >::TArg6 t6, typename FSig< Fn >::TArg7 t7) {
297   typename CLockedData< T, Lock >::TReadLock rl(data);
298   return f(rl.data(), t2, t3, t4, t5, t6, t7);
299 }
300
301
302 template< class T, class Lock, class Fn >
303 typename FSig< Fn >::RType WithWriteLock(Fn f, CLockedData< T, Lock > &data) {
304   typename CLockedData< T, Lock >::TWriteLock wl(data);
305   return f(wl.data());
306 }
307
308 template< class T, class Lock, class Fn >
309 typename FSig< Fn >::RType WithWriteLock(Fn f, CLockedData< T, Lock > &data, typename FSig< Fn >::TArg2 t2) {
310   typename CLockedData< T, Lock >::TWriteLock wl(data);
311   return f(wl.data(), t2);
312 }
313
314 template< class T, class Lock, class Fn >
315 typename FSig< Fn >::RType WithWriteLock(Fn f, CLockedData< T, Lock > &data, typename FSig< Fn >::TArg2 t2,
316                                          typename FSig< Fn >::TArg3 t3) {
317   typename CLockedData< T, Lock >::TWriteLock wl(data);
318   return f(wl.data(), t2, t3);
319 }
320
321 template< class T, class Lock, class Fn >
322 typename FSig< Fn >::RType WithWriteLock(Fn f, CLockedData< T, Lock > &data, typename FSig< Fn >::TArg2 t2,
323                                          typename FSig< Fn >::TArg3 t3, typename FSig< Fn >::TArg4 t4) {
324   typename CLockedData< T, Lock >::TWriteLock wl(data);
325   return f(wl.data(), t2, t3, t4);
326 }
327
328 template< class T, class Lock, class Fn >
329 typename FSig< Fn >::RType WithWriteLock(Fn f, CLockedData< T, Lock > &data, typename FSig< Fn >::TArg2 t2,
330                                          typename FSig< Fn >::TArg3 t3, typename FSig< Fn >::TArg4 t4, typename FSig< Fn >::TArg5 t5) {
331   typename CLockedData< T, Lock >::TWriteLock wl(data);
332   return f(wl.data(), t2, t3, t4, t5);
333 }
334
335 template< class T, class Lock, class Fn >
336 typename FSig< Fn >::RType WithWriteLock(Fn f, CLockedData< T, Lock > &data, typename FSig< Fn >::TArg2 t2,
337                                          typename FSig< Fn >::TArg3 t3, typename FSig< Fn >::TArg4 t4, typename FSig< Fn >::TArg5 t5,
338                                          typename FSig< Fn >::TArg6 t6) {
339   typename CLockedData< T, Lock >::TWriteLock wl(data);
340   return f(wl.data(), t2, t3, t4, t5, t6);
341 }
342
343 template< class T, class Lock, class Fn >
344 typename FSig< Fn >::RType WithWriteLock(Fn f, CLockedData< T, Lock > &data, typename FSig< Fn >::TArg2 t2,
345                                          typename FSig< Fn >::TArg3 t3, typename FSig< Fn >::TArg4 t4, typename FSig< Fn >::TArg5 t5,
346                                          typename FSig< Fn >::TArg6 t6, typename FSig< Fn >::TArg7 t7) {
347   typename CLockedData< T, Lock >::TWriteLock wl(data);
348   return f(wl.data(), t2, t3, t4, t5, t6, t7);
349 }
350
351
352 #endif  // FRAMEWORK_UNIFIED_CLIENT_NS_UTILITYCENTER_INCLUDE_NS_UTILITY_SYS_INTERNAL_HPP_
353 //@}