@@ -12,6 +12,15 @@ namespace Python.Runtime
1212 /// </summary>
1313 public class PythonEngine : IDisposable
1414 {
15+ [ DllImport ( "Kernel32" , EntryPoint = "GetCurrentThreadId" , ExactSpelling = true ) ]
16+ private static extern uint GetCurrentThreadId ( ) ;
17+
18+ [ DllImport ( "libc" , EntryPoint = "pthread_self" ) ]
19+ private static extern IntPtr pthread_selfLinux ( ) ;
20+
21+ [ DllImport ( "pthread" , EntryPoint = "pthread_self" , CallingConvention = CallingConvention . Cdecl ) ]
22+ private static extern ulong pthread_selfOSX ( ) ;
23+
1524 public static ShutdownMode ShutdownMode
1625 {
1726 get => Runtime . ShutdownMode ;
@@ -567,14 +576,59 @@ public static void Exec(string code, IntPtr? globals = null, IntPtr? locals = nu
567576 }
568577 }
569578
579+ /// <summary>
580+ /// Gets the native thread ID.
581+ /// </summary>
582+ /// <returns>The native thread ID.</returns>
583+ public static ulong GetNativeThreadID ( )
584+ {
585+ if ( Runtime . PyVersion >= new Version ( 3 , 8 ) )
586+ {
587+ dynamic threading = Py . Import ( "threading" ) ;
588+ return threading . get_native_id ( ) ;
589+ }
590+
591+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
592+ {
593+ return GetCurrentThreadId ( ) ;
594+ }
595+
596+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Linux ) )
597+ {
598+ return ( ulong ) pthread_selfLinux ( ) ;
599+ }
600+
601+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . OSX ) )
602+ {
603+ return pthread_selfOSX ( ) ;
604+ }
605+
606+ return 0 ;
607+ }
608+
570609 /// <summary>
571610 /// Interrupts the execution of a thread.
572611 /// </summary>
573- /// <param name="nativeThreadId ">The native thread id .</param>
612+ /// <param name="nativeThreadID ">The native thread ID .</param>
574613 /// <returns>The number of thread states modified; this is normally one, but will be zero if the thread id isn’t found.</returns>
575- public static int Interrupt ( ulong nativeThreadId )
614+ public static int Interrupt ( ulong nativeThreadID )
576615 {
577- return Runtime . PyThreadState_SetAsyncExc ( nativeThreadId , Exceptions . KeyboardInterrupt ) ;
616+ if ( Runtime . PyVersion >= new Version ( 3 , 7 ) )
617+ {
618+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
619+ {
620+ return Runtime . PyThreadState_SetAsyncExc37Windows ( nativeThreadID , Exceptions . KeyboardInterrupt ) ;
621+ }
622+
623+ return Runtime . PyThreadState_SetAsyncExc37NonWindows ( ( UIntPtr ) nativeThreadID , Exceptions . KeyboardInterrupt ) ;
624+ }
625+
626+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
627+ {
628+ return Runtime . PyThreadState_SetAsyncExc36Windows ( ( long ) nativeThreadID , Exceptions . KeyboardInterrupt ) ;
629+ }
630+
631+ return Runtime . PyThreadState_SetAsyncExc36NonWindows ( ( IntPtr ) nativeThreadID , Exceptions . KeyboardInterrupt ) ;
578632 }
579633
580634 /// <summary>
0 commit comments