From bcd8415644bd7a0b1d9878092588ae46995b9564 Mon Sep 17 00:00:00 2001 From: Victor Nova Date: Tue, 21 Sep 2021 22:01:20 -0700 Subject: [PATCH] added a workaround for warning in threading module after TestInterrupt avoid using dynamic in GetPythonThreadID --- src/embed_tests/TestInterrupt.cs | 58 +++++++++++++++++++++++++------- src/runtime/pythonengine.cs | 5 +-- 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/src/embed_tests/TestInterrupt.cs b/src/embed_tests/TestInterrupt.cs index a40407782..e344a8ccb 100644 --- a/src/embed_tests/TestInterrupt.cs +++ b/src/embed_tests/TestInterrupt.cs @@ -11,22 +11,51 @@ namespace Python.EmbeddingTest { public class TestInterrupt { - private IntPtr _threadState; - + PyObject threading; [OneTimeSetUp] public void SetUp() { PythonEngine.Initialize(); - _threadState = PythonEngine.BeginAllowThreads(); + // workaround for assert tlock.locked() warning + threading = Py.Import("threading"); } [OneTimeTearDown] public void Dispose() { - PythonEngine.EndAllowThreads(_threadState); + threading.Dispose(); PythonEngine.Shutdown(); } + [Test] + public void PythonThreadIDStable() + { + long pythonThreadID = 0; + long pythonThreadID2 = 0; + var asyncCall = Task.Factory.StartNew(() => + { + using (Py.GIL()) + { + Interlocked.Exchange(ref pythonThreadID, (long)PythonEngine.GetPythonThreadID()); + Interlocked.Exchange(ref pythonThreadID2, (long)PythonEngine.GetPythonThreadID()); + } + }); + + var timeout = Stopwatch.StartNew(); + + IntPtr threadState = PythonEngine.BeginAllowThreads(); + while (Interlocked.Read(ref pythonThreadID) == 0 || Interlocked.Read(ref pythonThreadID2) == 0) + { + Assert.Less(timeout.Elapsed, TimeSpan.FromSeconds(5), "thread IDs were not assigned in time"); + } + PythonEngine.EndAllowThreads(threadState); + + Assert.IsTrue(asyncCall.Wait(TimeSpan.FromSeconds(5)), "Async thread has not finished in time"); + + Assert.AreEqual(pythonThreadID, pythonThreadID2); + Assert.NotZero(pythonThreadID); + } + [Test] public void InterruptTest() { @@ -39,26 +68,31 @@ public void InterruptTest() return PythonEngine.RunSimpleString(@" import time -while True: - time.sleep(0.2)"); +try: + while True: + time.sleep(0.2) +except KeyboardInterrupt: + pass"); } }); var timeout = Stopwatch.StartNew(); + + IntPtr threadState = PythonEngine.BeginAllowThreads(); while (Interlocked.Read(ref pythonThreadID) == 0) { Assert.Less(timeout.Elapsed, TimeSpan.FromSeconds(5), "thread ID was not assigned in time"); } + PythonEngine.EndAllowThreads(threadState); - using (Py.GIL()) - { - int interruptReturnValue = PythonEngine.Interrupt((ulong)Interlocked.Read(ref pythonThreadID)); - Assert.AreEqual(1, interruptReturnValue); - } + int interruptReturnValue = PythonEngine.Interrupt((ulong)Interlocked.Read(ref pythonThreadID)); + Assert.AreEqual(1, interruptReturnValue); + threadState = PythonEngine.BeginAllowThreads(); Assert.IsTrue(asyncCall.Wait(TimeSpan.FromSeconds(5)), "Async thread was not interrupted in time"); + PythonEngine.EndAllowThreads(threadState); - Assert.AreEqual(-1, asyncCall.Result); + Assert.AreEqual(0, asyncCall.Result); } } } diff --git a/src/runtime/pythonengine.cs b/src/runtime/pythonengine.cs index 4b72dabd7..cd608fe93 100644 --- a/src/runtime/pythonengine.cs +++ b/src/runtime/pythonengine.cs @@ -570,8 +570,9 @@ internal static void Exec(string code, BorrowedReference globals, BorrowedRefere /// The Python thread ID. public static ulong GetPythonThreadID() { - dynamic threading = Py.Import("threading"); - return threading.InvokeMethod("get_ident"); + using PyObject threading = Py.Import("threading"); + using PyObject id = threading.InvokeMethod("get_ident"); + return id.As(); } /// pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy