1 /**
2 This file provides `ScopedForeignCallback` to be used in every callback.
3 
4 Copyright: Guillaume Piolat 2015-2023.
5 License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
6 */
7 module dplug.core.runtime;
8 
9 import core.runtime;
10 import core.atomic;
11 import core.stdc.stdlib;
12 
13 import std.traits;
14 import std.functional: toDelegate;
15 
16 import dplug.core.fpcontrol;
17 import dplug.core.nogc;
18 
19 
20 /// RAII struct to cover extern callbacks.
21 /// This only deals with CPU identification and FPU control words save/restore.
22 /// But when we used an enabled D runtime, this used to manage thread attachment 
23 /// and disappearance, so calling this on callbacks is still mandated.
24 struct ScopedForeignCallback(bool dummyDeprecated, bool saveRestoreFPU)
25 {
26 public:
27 nothrow:
28 @nogc:
29 
30     /// Thread that shouldn't be attached are eg. the audio threads.
31     void enter()
32     {
33         debug _entered = true;
34 
35         static if (saveRestoreFPU)
36             _fpControl.initialize();
37     }
38 
39     ~this()
40     {
41         // Ensure enter() was called.
42         debug assert(_entered);
43     }
44 
45     @disable this(this);
46 
47 private:
48 
49     static if (saveRestoreFPU)
50         FPControl _fpControl;
51 
52     debug bool _entered = false;
53 }
54 
55 
56