|
1
|
1 #pragma once
|
|
|
2
|
|
|
3 #include <functional>
|
|
|
4 #include "event.h"
|
|
|
5 #include <memory>
|
|
|
6 #include "lockless.h"
|
|
|
7
|
|
|
8 #ifdef __ANDROID__
|
|
|
9 #define PFC_CUSTOM_ONCE_FLAG 1
|
|
|
10 #endif
|
|
|
11
|
|
|
12 #ifndef PFC_CUSTOM_ONCE_FLAG
|
|
|
13 #define PFC_CUSTOM_ONCE_FLAG 0
|
|
|
14 #endif
|
|
|
15
|
|
|
16 #if ! PFC_CUSTOM_ONCE_FLAG
|
|
|
17 #include <mutex>
|
|
|
18 #endif
|
|
|
19
|
|
|
20 namespace pfc {
|
|
|
21 #if PFC_CUSTOM_ONCE_FLAG
|
|
|
22 struct once_flag {
|
|
|
23 bool inProgress = false, done = false;
|
|
|
24 std::shared_ptr<::pfc::event> waitFor;
|
|
|
25 };
|
|
|
26
|
|
|
27 void call_once( once_flag &, std::function<void () > );
|
|
|
28 #else
|
|
|
29 using std::once_flag;
|
|
|
30 using std::call_once;
|
|
|
31 #endif
|
|
|
32
|
|
|
33 //! Minimalist class to call some function only once. \n
|
|
|
34 //! Presumes low probability of concurrent run() calls actually happening, \n
|
|
|
35 //! but frequent calls once already initialized, hence only using basic volatile bool check. \n
|
|
|
36 //! If using a modern compiler you might want to use std::call_once instead. \n
|
|
|
37 //! The called function is not expected to throw exceptions.
|
|
|
38 struct once_flag_lite {
|
|
|
39 threadSafeInt::val_t guard = 0;
|
|
|
40 volatile bool done = false;
|
|
|
41 };
|
|
|
42
|
|
|
43 void call_once( once_flag_lite &, std::function<void () > );
|
|
|
44
|
|
|
45 class runOnceLock {
|
|
|
46 public:
|
|
|
47 void run(std::function<void()> f) {call_once(m_flag, f);}
|
|
|
48 private:
|
|
|
49 once_flag_lite m_flag;
|
|
|
50 };
|
|
|
51 }
|