@@ -2915,21 +2915,43 @@ function PythonVersionFromRegVersion(const ARegVersion: string;
2915
2915
out AMajorVersion, AMinorVersion: integer): boolean;
2916
2916
function PyStatus_Exception (const APyStatus: PyStatus): Boolean;
2917
2917
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
+
2918
2937
{ Helper functions}
2938
+
2919
2939
(*
2920
2940
Checks whether the PythonVersion x.x is Registered
2921
2941
*)
2922
2942
{ $IFDEF MSWINDOWS}
2923
2943
function IsPythonVersionRegistered (PythonVersion : string;
2924
2944
out InstallPath: string; out AllUserInstall: Boolean) : Boolean;
2925
2945
{ $ENDIF}
2946
+
2926
2947
(*
2927
2948
Mask FPU Excptions - Useful for importing SciPy and other Python libs
2928
2949
See http://bugs.python.org/issue9980 and
2929
2950
http://stackoverflow.com/questions/3933851/
2930
2951
*)
2931
2952
procedure MaskFPUExceptions (ExceptionsMasked : boolean;
2932
2953
MatchPythonPrecision : Boolean = True);
2954
+
2933
2955
(*
2934
2956
Converts line breaks to LF and optionally adds a line break at the end
2935
2957
*)
@@ -9788,5 +9810,53 @@ function PyStatus_Exception(const APyStatus: PyStatus): Boolean;
9788
9810
Result := APyStatus._type <> _PyStatus_TYPE_OK;
9789
9811
end ;
9790
9812
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
+
9791
9861
end .
9792
9862
0 commit comments