File tree Expand file tree Collapse file tree 4 files changed +36
-2
lines changed Expand file tree Collapse file tree 4 files changed +36
-2
lines changed Original file line number Diff line number Diff line change 368
368
PyThreadState_Clear (PyThreadState * tstate )
369
369
{
370
370
#ifdef STACKLESS
371
- STACKLESS_PYSTATE_CLEAR ;
371
+ slp_kill_tasks_with_stacks ( tstate ) ;
372
372
#endif
373
373
if (Py_VerboseFlag && tstate -> frame != NULL )
374
374
fprintf (stderr ,
@@ -391,6 +391,9 @@ PyThreadState_Clear(PyThreadState *tstate)
391
391
tstate -> c_tracefunc = NULL ;
392
392
Py_CLEAR (tstate -> c_profileobj );
393
393
Py_CLEAR (tstate -> c_traceobj );
394
+ #ifdef STACKLESS
395
+ STACKLESS_PYSTATE_CLEAR ;
396
+ #endif
394
397
}
395
398
396
399
Original file line number Diff line number Diff line change @@ -14,6 +14,11 @@ What's New in Stackless 3.X.X?
14
14
block leak errors from the test suite. The performance penalty is irrelevant in
15
15
debug builds.
16
16
17
+ - https://bitbucket.org/stackless-dev/stackless/issues/121
18
+ Fix a reference leak. If Python clears a thread state and a destructor or a
19
+ weakref-callback runs Python code, Python used to leak a reference to a
20
+ C-stack object.
21
+
17
22
- https://bitbucket.org/stackless-dev/stackless/issues/119
18
23
Fix a rare bug in the stack unwinding mechanism, that caused a SystemError
19
24
exception or an assertion violation, if a __del__()-method or a weakref
Original file line number Diff line number Diff line change @@ -114,7 +114,6 @@ struct _ts; /* Forward */
114
114
void slp_kill_tasks_with_stacks (struct _ts * tstate );
115
115
116
116
#define __STACKLESS_PYSTATE_CLEAR \
117
- slp_kill_tasks_with_stacks(tstate); \
118
117
Py_CLEAR(tstate->st.initial_stub); \
119
118
Py_CLEAR(tstate->st.del_post_switch); \
120
119
Py_CLEAR(tstate->st.interrupted); \
Original file line number Diff line number Diff line change @@ -616,6 +616,33 @@ def test_setup_from_other_thread(self):
616
616
theThread .join ()
617
617
618
618
619
+ @unittest .skipUnless (withThreads , "requires thread support" )
620
+ class TestThreadLocalStorage (StacklessTestCase ):
621
+ class ObjectWithDestructor (object ):
622
+ def __init__ (self , event ):
623
+ self .event = event
624
+
625
+ def __del__ (self ):
626
+ self .event .set ()
627
+
628
+ def test_destructor_at_end_of_thread (self ):
629
+ # Test case for issue #121 https://bitbucket.org/stackless-dev/stackless/issue/121
630
+ # Run a destructor during clean up of thread local storage
631
+ # Until issue #121 got fixed, this caused a reference leak
632
+ tls = threading .local ()
633
+ deleted = threading .Event ()
634
+
635
+ def other_thread ():
636
+ tls .owd = self .ObjectWithDestructor (deleted )
637
+
638
+ self .assertFalse (deleted .is_set ())
639
+ t = threading .Thread (target = other_thread , name = "other thread" )
640
+ t .start ()
641
+ t .join ()
642
+ time .sleep (0.1 ) # give the thread time to clean up
643
+ self .assertTrue (deleted .is_set ())
644
+
645
+
619
646
if __name__ == '__main__' :
620
647
if not sys .argv [1 :]:
621
648
sys .argv .append ('-v' )
You can’t perform that action at this time.
0 commit comments