@@ -11,22 +11,51 @@ namespace Python.EmbeddingTest
11
11
{
12
12
public class TestInterrupt
13
13
{
14
- private IntPtr _threadState ;
15
-
14
+ PyObject threading ;
16
15
[ OneTimeSetUp ]
17
16
public void SetUp ( )
18
17
{
19
18
PythonEngine . Initialize ( ) ;
20
- _threadState = PythonEngine . BeginAllowThreads ( ) ;
19
+ // workaround for assert tlock.locked() warning
20
+ threading = Py . Import ( "threading" ) ;
21
21
}
22
22
23
23
[ OneTimeTearDown ]
24
24
public void Dispose ( )
25
25
{
26
- PythonEngine . EndAllowThreads ( _threadState ) ;
26
+ threading . Dispose ( ) ;
27
27
PythonEngine . Shutdown ( ) ;
28
28
}
29
29
30
+ [ Test ]
31
+ public void PythonThreadIDStable ( )
32
+ {
33
+ long pythonThreadID = 0 ;
34
+ long pythonThreadID2 = 0 ;
35
+ var asyncCall = Task . Factory . StartNew ( ( ) =>
36
+ {
37
+ using ( Py . GIL ( ) )
38
+ {
39
+ Interlocked . Exchange ( ref pythonThreadID , ( long ) PythonEngine . GetPythonThreadID ( ) ) ;
40
+ Interlocked . Exchange ( ref pythonThreadID2 , ( long ) PythonEngine . GetPythonThreadID ( ) ) ;
41
+ }
42
+ } ) ;
43
+
44
+ var timeout = Stopwatch . StartNew ( ) ;
45
+
46
+ IntPtr threadState = PythonEngine . BeginAllowThreads ( ) ;
47
+ while ( Interlocked . Read ( ref pythonThreadID ) == 0 || Interlocked . Read ( ref pythonThreadID2 ) == 0 )
48
+ {
49
+ Assert . Less ( timeout . Elapsed , TimeSpan . FromSeconds ( 5 ) , "thread IDs were not assigned in time" ) ;
50
+ }
51
+ PythonEngine . EndAllowThreads ( threadState ) ;
52
+
53
+ Assert . IsTrue ( asyncCall . Wait ( TimeSpan . FromSeconds ( 5 ) ) , "Async thread has not finished in time" ) ;
54
+
55
+ Assert . AreEqual ( pythonThreadID , pythonThreadID2 ) ;
56
+ Assert . NotZero ( pythonThreadID ) ;
57
+ }
58
+
30
59
[ Test ]
31
60
public void InterruptTest ( )
32
61
{
@@ -39,26 +68,31 @@ public void InterruptTest()
39
68
return PythonEngine . RunSimpleString ( @"
40
69
import time
41
70
42
- while True:
43
- time.sleep(0.2)" ) ;
71
+ try:
72
+ while True:
73
+ time.sleep(0.2)
74
+ except KeyboardInterrupt:
75
+ pass" ) ;
44
76
}
45
77
} ) ;
46
78
47
79
var timeout = Stopwatch . StartNew ( ) ;
80
+
81
+ IntPtr threadState = PythonEngine . BeginAllowThreads ( ) ;
48
82
while ( Interlocked . Read ( ref pythonThreadID ) == 0 )
49
83
{
50
84
Assert . Less ( timeout . Elapsed , TimeSpan . FromSeconds ( 5 ) , "thread ID was not assigned in time" ) ;
51
85
}
86
+ PythonEngine . EndAllowThreads ( threadState ) ;
52
87
53
- using ( Py . GIL ( ) )
54
- {
55
- int interruptReturnValue = PythonEngine . Interrupt ( ( ulong ) Interlocked . Read ( ref pythonThreadID ) ) ;
56
- Assert . AreEqual ( 1 , interruptReturnValue ) ;
57
- }
88
+ int interruptReturnValue = PythonEngine . Interrupt ( ( ulong ) Interlocked . Read ( ref pythonThreadID ) ) ;
89
+ Assert . AreEqual ( 1 , interruptReturnValue ) ;
58
90
91
+ threadState = PythonEngine . BeginAllowThreads ( ) ;
59
92
Assert . IsTrue ( asyncCall . Wait ( TimeSpan . FromSeconds ( 5 ) ) , "Async thread was not interrupted in time" ) ;
93
+ PythonEngine . EndAllowThreads ( threadState ) ;
60
94
61
- Assert . AreEqual ( - 1 , asyncCall . Result ) ;
95
+ Assert . AreEqual ( 0 , asyncCall . Result ) ;
62
96
}
63
97
}
64
98
}
0 commit comments