@@ -2341,6 +2341,15 @@ test_get_incomplete_frame(void)
23412341 return result ;
23422342}
23432343
2344+ const char * THREAD_CODE = "import time\n"
2345+ "time.sleep(0.2)\n"
2346+ "def fib(n):\n"
2347+ " if n <= 1:\n"
2348+ " return n\n"
2349+ " else:\n"
2350+ " return fib(n - 1) + fib(n - 2)\n"
2351+ "fib(10)" ;
2352+
23442353static void
23452354non_daemon_native (void * arg )
23462355{
@@ -2350,15 +2359,7 @@ non_daemon_native(void *arg)
23502359 int res = PyThreadState_SetDaemon (0 );
23512360 assert (res == 1 );
23522361 _PyEvent_Notify (event );
2353- const char * code = "import time\n"
2354- "time.sleep(0.2)\n"
2355- "def fib(n):\n"
2356- " if n <= 1:\n"
2357- " return n\n"
2358- " else:\n"
2359- " return fib(n - 1) + fib(n - 2)\n"
2360- "fib(10)" ;
2361- res = PyRun_SimpleString (code );
2362+ res = PyRun_SimpleString (THREAD_CODE );
23622363 assert (res == 0 );
23632364 PyThreadState_Clear (tstate );
23642365 PyThreadState_Swap (NULL );
@@ -2371,7 +2372,7 @@ test_non_daemon_native_thread(void)
23712372 _testembed_Py_InitializeFromConfig ();
23722373 PyThread_handle_t handle ;
23732374 PyThread_ident_t ident ;
2374- PyEvent event ;
2375+ PyEvent event = { 0 } ;
23752376 if (PyThread_start_joinable_thread (non_daemon_native , & event ,
23762377 & ident , & handle ) < 0 ) {
23772378 return -1 ;
@@ -2381,6 +2382,41 @@ test_non_daemon_native_thread(void)
23812382 return 0 ;
23822383}
23832384
2385+ typedef struct {
2386+ PyInterpreterState * interp ;
2387+ PyEvent * event ;
2388+ } ThreadData ;
2389+
2390+ static void
2391+ do_tstate_ensure (void * arg )
2392+ {
2393+ ThreadData * data = (ThreadData * )arg ;
2394+ PyEvent * event = data -> event ;
2395+ int res = PyThreadState_Ensure (data -> interp );
2396+ assert (res == 0 );
2397+ _PyEvent_Notify (event );
2398+ res = PyRun_SimpleString (THREAD_CODE );
2399+ assert (res == 0 );
2400+ PyThreadState_Release ();
2401+ }
2402+
2403+ static int
2404+ test_thread_state_ensure (void )
2405+ {
2406+ _testembed_Py_InitializeFromConfig ();
2407+ PyThread_handle_t handle ;
2408+ PyThread_ident_t ident ;
2409+ PyEvent event = {0 };
2410+ ThreadData data = { PyInterpreterState_Hold (), & event };
2411+ if (PyThread_start_joinable_thread (non_daemon_native , & data ,
2412+ & ident , & handle ) < 0 ) {
2413+ return -1 ;
2414+ }
2415+ PyEvent_Wait (& event );
2416+ Py_Finalize ();
2417+ return 0 ;
2418+ }
2419+
23842420/* *********************************************************
23852421 * List of test cases and the function that implements it.
23862422 *
@@ -2471,6 +2507,7 @@ static struct TestCase TestCases[] = {
24712507#endif
24722508 {"test_get_incomplete_frame" , test_get_incomplete_frame },
24732509 {"test_non_daemon_native_thread" , test_non_daemon_native_thread },
2510+ {"test_thread_state_ensure" , test_thread_state_ensure },
24742511
24752512 {NULL , NULL }
24762513};
0 commit comments