1 /**
2 This file provides `ScopedForeignCallback`, a RAII object
3 to be conventionally in every foreign callback.
4
5 Copyright: Guillaume Piolat 2015-2023.
6 License: http://www.boost.org/LICENSE_1_0.txt
7 */
8 module dplug.core.runtime;
9
10 import dplug.core.fpcontrol;
11
12
13 /**
14 RAII struct to cover extern callbacks.
15 Nowadays it only deals with FPU/SSE control words
16 save/restore.
17
18 When we used a D runtime, this used to manage thread
19 attachment and deattachment in each incoming exported
20 function.
21
22 Calling this on callbacks is still mandatory, since
23 changing floating-point control work can happen and
24 create issues.
25
26 Example:
27
28 extern(C) myCallback()
29 {
30 ScopedForeignCallback!(false, true) cb;
31 cb.enter();
32
33 // Rounding mode preserved here...
34 }
35
36 */
37 struct ScopedForeignCallback(bool dummyDeprecated,
38 bool saveRestoreFPU)
39 {
40 public:
41 nothrow:
42 @nogc:
43
44 /// Call this in each callback.
45 void enter()
46 {
47 debug _entered = true;
48
49 static if (saveRestoreFPU)
50 _fpControl.initialize();
51 }
52
53 ~this()
54 {
55 // Ensure enter() was called.
56 debug assert(_entered);
57 }
58
59 @disable this(this);
60
61 private:
62
63 static if (saveRestoreFPU)
64 FPControl _fpControl;
65
66 debug bool _entered = false;
67 }
68
69
70