Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8154c90

Browse files
committed
Add Interrupt method in PythonEngine
1 parent d6c0081 commit 8154c90

File tree

5 files changed

+102
-2
lines changed

5 files changed

+102
-2
lines changed

AUTHORS.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@
6666
- Ville M. Vainio ([@vivainio](https://github.com/vivainio))
6767
- Virgil Dupras ([@hsoft](https://github.com/hsoft))
6868
- Wenguang Yang ([@yagweb](https://github.com/yagweb))
69-
- William Sardar ([@williamsardar])(https://github.com/williamsardar)
69+
- William Sardar ([@williamsardar](https://github.com/williamsardar))
7070
- Xavier Dupré ([@sdpython](https://github.com/sdpython))
7171
- Zane Purvis ([@zanedp](https://github.com/zanedp))
72-
- ([@amos402]https://github.com/amos402)
72+
- ([@amos402](https://github.com/amos402))
7373
- ([@bltribble](https://github.com/bltribble))
7474
- ([@civilx64](https://github.com/civilx64))
7575
- ([@GSPP](https://github.com/GSPP))
@@ -82,3 +82,4 @@
8282
- ([@testrunner123](https://github.com/testrunner123))
8383
- ([@DanBarzilian](https://github.com/DanBarzilian))
8484
- ([@alxnull](https://github.com/alxnull))
85+
- ([@gpetrou](https://github.com/gpetrou))

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].
1010
### Added
1111

1212
- Ability to instantiate new .NET arrays using `Array[T](dim1, dim2, ...)` syntax
13+
<<<<<<< HEAD
1314
- Python operator method will call C# operator method for supported binary and unary operators ([#1324][p1324]).
15+
=======
16+
- Add Interrupt method in PythonEngine
17+
>>>>>>> Add Interrupt method in PythonEngine
1418
1519
### Changed
1620
- Drop support for Python 2, 3.4, and 3.5

src/embed_tests/TestInterrupt.cs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
2+
using System;
3+
using System.Runtime.InteropServices;
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
7+
using NUnit.Framework;
8+
9+
using Python.Runtime;
10+
11+
namespace Python.EmbeddingTest
12+
{
13+
public class TestInterrupt
14+
{
15+
private IntPtr _threadState;
16+
17+
[DllImport("Kernel32", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)]
18+
private static extern uint GetCurrentThreadId();
19+
20+
[DllImport("libc", EntryPoint = "pthread_self")]
21+
private static extern IntPtr pthread_selfLinux();
22+
23+
[DllImport("pthread", EntryPoint = "pthread_self", CallingConvention = CallingConvention.Cdecl)]
24+
private static extern ulong pthread_selfOSX();
25+
26+
[OneTimeSetUp]
27+
public void SetUp()
28+
{
29+
PythonEngine.Initialize();
30+
_threadState = PythonEngine.BeginAllowThreads();
31+
}
32+
33+
[OneTimeTearDown]
34+
public void Dispose()
35+
{
36+
PythonEngine.EndAllowThreads(_threadState);
37+
PythonEngine.Shutdown();
38+
}
39+
40+
[Test]
41+
public void InterruptTest()
42+
{
43+
int runSimpleStringReturnValue = int.MinValue;
44+
ulong nativeThreadId = 0;
45+
Task.Factory.StartNew(() =>
46+
{
47+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
48+
{
49+
nativeThreadId = GetCurrentThreadId();
50+
}
51+
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
52+
{
53+
nativeThreadId = (ulong)pthread_selfLinux();
54+
}
55+
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
56+
{
57+
nativeThreadId = pthread_selfOSX();
58+
}
59+
60+
using (Py.GIL())
61+
{
62+
runSimpleStringReturnValue = PythonEngine.RunSimpleString(@"
63+
import time
64+
65+
while True:
66+
time.sleep(0.2)");
67+
}
68+
});
69+
70+
Thread.Sleep(200);
71+
72+
using (Py.GIL())
73+
{
74+
int interruptReturnValue = PythonEngine.Interrupt(nativeThreadId);
75+
Assert.AreEqual(1, interruptReturnValue);
76+
}
77+
78+
Thread.Sleep(300);
79+
80+
Assert.AreEqual(-1, runSimpleStringReturnValue);
81+
}
82+
}
83+
}

src/runtime/pythonengine.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,15 @@ public static void Exec(string code, IntPtr? globals = null, IntPtr? locals = nu
567567
}
568568
}
569569

570+
/// <summary>
571+
/// Interrupts the execution of a thread.
572+
/// </summary>
573+
/// <param name="nativeThreadId">The native thread id.</param>
574+
/// <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)
576+
{
577+
return Runtime.PyThreadState_SetAsyncExc(nativeThreadId, Exceptions.KeyboardInterrupt);
578+
}
570579

571580
/// <summary>
572581
/// RunString Method. Function has been deprecated and will be removed.

src/runtime/runtime.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,6 +2146,9 @@ internal static void Py_CLEAR(ref IntPtr ob)
21462146
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
21472147
internal static extern int Py_AddPendingCall(IntPtr func, IntPtr arg);
21482148

2149+
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
2150+
internal static extern int PyThreadState_SetAsyncExc(ulong id, IntPtr exc);
2151+
21492152
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
21502153
internal static extern int Py_MakePendingCalls();
21512154

0 commit comments

Comments
 (0)