Example #1
0
    def test_local_1(self):
        import thread
        from thread import _local as tlsobject

        freed = []

        class X:
            def __del__(self):
                freed.append(1)

        ok = []
        TLS1 = tlsobject()
        TLS2 = tlsobject()
        TLS1.aa = "hello"

        def f(i):
            success = False
            try:
                a = TLS1.aa = i
                b = TLS1.bbb = X()
                c = TLS2.cccc = i * 3
                d = TLS2.ddddd = X()
                self.busywait(0.05)
                assert TLS1.aa == a
                assert TLS1.bbb is b
                assert TLS2.cccc == c
                assert TLS2.ddddd is d
                success = True
            finally:
                ok.append(success)

        for i in range(20):
            thread.start_new_thread(f, (i,))
        self.waitfor(lambda: len(ok) == 20, delay=3)
        assert ok == 20 * [True]  # see stdout/stderr for failures in the threads

        self.waitfor(lambda: len(freed) >= 40)
        assert len(freed) == 40
        #  in theory, all X objects should have been freed by now.  Note that
        #  Python's own thread._local objects suffer from the very same "bug" that
        #  tls.py showed originally, and leaves len(freed)==38: the last thread's
        #  __dict__ remains stored in the TLS1/TLS2 instances, although it is not
        #  really accessible any more.

        assert TLS1.aa == "hello"
Example #2
0
    def test_local_1(self):
        import thread
        from thread import _local as tlsobject
        freed = []

        class X:
            def __del__(self):
                freed.append(1)

        ok = []
        TLS1 = tlsobject()
        TLS2 = tlsobject()
        TLS1.aa = "hello"

        def f(i):
            success = False
            try:
                a = TLS1.aa = i
                b = TLS1.bbb = X()
                c = TLS2.cccc = i * 3
                d = TLS2.ddddd = X()
                self.busywait(0.05)
                assert TLS1.aa == a
                assert TLS1.bbb is b
                assert TLS2.cccc == c
                assert TLS2.ddddd is d
                success = True
            finally:
                ok.append(success)

        for i in range(20):
            thread.start_new_thread(f, (i, ))
        self.waitfor(lambda: len(ok) == 20, delay=3)
        assert ok == 20 * [True
                           ]  # see stdout/stderr for failures in the threads

        self.waitfor(lambda: len(freed) >= 40)
        assert len(freed) == 40
        #  in theory, all X objects should have been freed by now.  Note that
        #  Python's own thread._local objects suffer from the very same "bug" that
        #  tls.py showed originally, and leaves len(freed)==38: the last thread's
        #  __dict__ remains stored in the TLS1/TLS2 instances, although it is not
        #  really accessible any more.

        assert TLS1.aa == "hello"
Example #3
0
    def specialize_call(self, hop):
        assert isinstance(hop.args_r[0], raddress.AddressRepr)
        adr, = hop.inputargs(hop.args_r[0])
        hop.exception_cannot_occur()
        return hop.genop('cast_adr_to_int', [adr],
                         resulttype = lltype.Signed)

# ____________________________________________________________
# errno

# this saves in a thread-local way the "current" value that errno
# should have in C.  We have to save it away from one external C function
# call to the next.  Otherwise a non-zero value left behind will confuse
# CPython itself a bit later, and/or CPython will stamp on it before we
# try to inspect it via rposix.get_errno().
TLS = tlsobject()

# helpers to save/restore the C-level errno -- platform-specific because
# ctypes doesn't just do the right thing and expose it directly :-(

# on 2.6 ctypes does it right, use it

if sys.version_info >= (2, 6):
    def _save_c_errno():
        TLS.errno = ctypes.get_errno()

    def _restore_c_errno():
        pass

else:
    def _where_is_errno():