@@ -2915,21 +2915,43 @@ function PythonVersionFromRegVersion(const ARegVersion: string;
29152915 out AMajorVersion, AMinorVersion: integer): boolean;
29162916function PyStatus_Exception (const APyStatus: PyStatus): Boolean;
29172917
2918+ // #######################################################
2919+ // ## ##
2920+ // ## Support routines for running python ##
2921+ // ## code in threads ##
2922+ // ## ##
2923+ // #######################################################
2924+
2925+ type
2926+ IPyEngineAndGIL = interface
2927+ function GetPyEngine : TPythonEngine;
2928+ function GetThreadState : PPyThreadState;
2929+ property PythonEngine: TPythonEngine read GetPyEngine;
2930+ property ThreadState: PPyThreadState read GetThreadState;
2931+ end ;
2932+
2933+ // Access the PythonEngine with thread safety
2934+ function SafePyEngine : IPyEngineAndGIL;
2935+
2936+
29182937{ Helper functions}
2938+
29192939(*
29202940 Checks whether the PythonVersion x.x is Registered
29212941*)
29222942{ $IFDEF MSWINDOWS}
29232943function IsPythonVersionRegistered (PythonVersion : string;
29242944 out InstallPath: string; out AllUserInstall: Boolean) : Boolean;
29252945{ $ENDIF}
2946+
29262947(*
29272948 Mask FPU Excptions - Useful for importing SciPy and other Python libs
29282949 See http://bugs.python.org/issue9980 and
29292950 http://stackoverflow.com/questions/3933851/
29302951*)
29312952procedure MaskFPUExceptions (ExceptionsMasked : boolean;
29322953 MatchPythonPrecision : Boolean = True);
2954+
29332955(*
29342956 Converts line breaks to LF and optionally adds a line break at the end
29352957*)
@@ -9788,5 +9810,53 @@ function PyStatus_Exception(const APyStatus: PyStatus): Boolean;
97889810 Result := APyStatus._type <> _PyStatus_TYPE_OK;
97899811end ;
97909812
9813+ { TPyEngineAndGIL - Internal class for SafePythonEngine }
9814+
9815+ type
9816+ TPyEngineAndGIL = class (TInterfacedObject, IPyEngineAndGIL)
9817+ fPythonEngine: TPythonEngine;
9818+ fThreadState: PPyThreadState;
9819+ fGILState: PyGILstate_STATE;
9820+ private
9821+ function GetPyEngine : TPythonEngine;
9822+ function GetThreadState : PPyThreadState;
9823+ public
9824+ constructor Create;
9825+ destructor Destroy; override;
9826+ end ;
9827+
9828+
9829+ constructor TPyEngineAndGIL.Create;
9830+ begin
9831+ inherited Create;
9832+ fPythonEngine := GetPythonEngine;
9833+ fGILState := fPythonEngine.PyGILState_Ensure;
9834+ fThreadState := fPythonEngine.PyThreadState_Get;
9835+ end ;
9836+
9837+ destructor TPyEngineAndGIL.Destroy;
9838+ begin
9839+ fPythonEngine.PyGILState_Release(fGILState);
9840+ inherited ;
9841+ end ;
9842+
9843+ function TPyEngineAndGIL.GetPyEngine : TPythonEngine;
9844+ begin
9845+ Result := fPythonEngine;
9846+ end ;
9847+
9848+ function TPyEngineAndGIL.GetThreadState : PPyThreadState;
9849+ begin
9850+ Result := fThreadState;
9851+ end ;
9852+
9853+ { SafePythonEngine }
9854+ function SafePyEngine : IPyEngineAndGIL;
9855+ begin
9856+ Result := TPyEngineAndGIL.Create
9857+ end ;
9858+
9859+
9860+
97919861end .
97929862
0 commit comments