Example #1
0
    def setup_class(cls):
        from test_basic import compile, run

        class EC(object):
            def __init__(self, value):
                self.value = value

        raw_thread_local = rthread.ThreadLocalReference(EC)

        def bootstrap():
            rthread.gc_thread_start()
            _sleep(1)
            ec = EC(4567)
            raw_thread_local.set(ec)
            revdb.stop_point()
            print raw_thread_local.get().value
            assert raw_thread_local.get() is ec
            rthread.gc_thread_die()

        def main(argv):
            revdb.stop_point()
            ec = EC(12)
            raw_thread_local.set(ec)
            rthread.start_new_thread(bootstrap, ())
            _sleep(2)
            print raw_thread_local.get().value
            assert raw_thread_local.get() is ec
            return 9

        compile(cls, main, backendopt=False, thread=True)
        assert run(cls, '') == '4567\n12\n'
Example #2
0
    def test_threadlocal(self):
        class EC(object):
            def __init__(self, value):
                self.value = value

        raw_thread_local = rthread.ThreadLocalReference(EC)

        def bootstrap():
            rthread.gc_thread_start()
            _sleep(1)
            ec = EC(4567)
            raw_thread_local.set(ec)
            print raw_thread_local.get().value
            assert raw_thread_local.get() is ec
            rthread.gc_thread_die()

        def main(argv):
            ec = EC(12)
            raw_thread_local.set(ec)
            rthread.start_new_thread(bootstrap, ())
            _sleep(2)
            print raw_thread_local.get().value
            assert raw_thread_local.get() is ec
            return 9

        self.compile(main, backendopt=False, thread=True)
        out = self.run('Xx')
        # should have printed 4567 and 12
        rdb = self.fetch_rdb([self.exename, 'Xx'])
        th_A = rdb.main_thread_id
        rdb.same_stack()  # RPyGilAllocate()

        th_B = self.start_thread_B(rdb, th_A)

        rdb.gil_acquire()
        rdb.gil_release()

        rdb.switch_thread(th_B)
        rdb.same_stack()  # sleep() (finishes here)
        rdb.next('i')  # sleep()
        rdb.gil_acquire()
        rdb.write_call("4567\n")
        rdb.gil_release()

        rdb.switch_thread(th_A)
        rdb.same_stack()  # sleep()
        rdb.next('i')  # sleep()
        rdb.gil_acquire()
        rdb.write_call("12\n")
        rdb.done()
Example #3
0
 def __init__(self, space):
     "NOT_RPYTHON"
     #
     # This object tracks code that enters and leaves threads.
     # There are two APIs.  For Python-level threads, we know when
     # the thread starts and ends, and we call enter_thread() and
     # leave_thread().  In a few other cases, like callbacks, we
     # might be running in some never-seen-before thread: in this
     # case, the callback logic needs to call try_enter_thread() at
     # the start, and if this returns True it needs to call
     # leave_thread() at the end.
     #
     # We implement an optimization for the second case (which only
     # works if we translate with a framework GC and with
     # rweakref).  If try_enter_thread() is called in a
     # never-seen-before thread, it still returns False and
     # remembers the ExecutionContext with 'self._weaklist'.  The
     # next time we call try_enter_thread() again in the same
     # thread, the ExecutionContext is reused.  The optimization is
     # not completely invisible to the user: '******'
     # values will remain.  We can argue that it is the correct
     # behavior to do that, and the behavior we get if the
     # optimization is disabled is buggy (but hard to do better
     # then).
     #
     # 'self._valuedict' is a dict mapping the thread idents to
     # ExecutionContexts; it does not list the ExecutionContexts
     # which are in 'self._weaklist'.  (The latter is more precisely
     # a list of AutoFreeECWrapper objects, defined below, which
     # each references the ExecutionContext.)
     #
     self.space = space
     self._valuedict = {}
     self._cleanup_()
     self.raw_thread_local = rthread.ThreadLocalReference(
         ExecutionContext, loop_invariant=True)
Example #4
0
 def __init__(self):
     "NOT_RPYTHON"
     self._valuedict = {}  # {thread_ident: ExecutionContext()}
     self._cleanup_()
     self.raw_thread_local = rthread.ThreadLocalReference(
         ExecutionContext, loop_invariant=True)