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