
python-checkins at python
Nov 6, 2009, 12:20 PM
Post #1 of 1
(103 views)
Permalink
|
|
r76134 - in sandbox/trunk/newgil: Lib/_threading_local.py Lib/importlib/test/source/util.py Lib/test/test_kqueue.py Lib/test/test_telnetlib.py Lib/threading.py Misc/ACKS Misc/NEWS Modules/selectmodule.c
|
|
Author: antoine.pitrou Date: Fri Nov 6 20:40:06 2009 New Revision: 76134 Log: Merged revisions 76111,76113-76114,76119,76124,76133 via svnmerge from svn+ssh://pythondev [at] svn/python/branches/py3k ................ r76111 | antoine.pitrou | 2009-11-04 22:10:38 +0100 (mer., 04 nov. 2009) | 12 lines Merged revisions 76108 via svnmerge from svn+ssh://pythondev [at] svn/python/trunk ........ r76108 | antoine.pitrou | 2009-11-04 20:25:14 +0100 (mer., 04 nov. 2009) | 6 lines Issue #7211: Allow 64-bit values for the `ident` and `data` fields of kevent objects on 64-bit systems. Patch by Michael Broghton. I will revert this checkin if it causes problems on our BSD buildbots. ........ ................ r76113 | brett.cannon | 2009-11-05 02:17:22 +0100 (jeu., 05 nov. 2009) | 3 lines importlib.test.source.util referenced variables in the 'finally' part of a try/finally which may not have been set. ................ r76114 | brett.cannon | 2009-11-05 02:26:57 +0100 (jeu., 05 nov. 2009) | 6 lines Use tempfile.mkdtemp() instead of tempfile.tempdir for where importlib places source files for tests. Allows for concurrent execution of the tests by preventing various executions from trampling each other. Closes issue #7248. ................ r76119 | antoine.pitrou | 2009-11-05 14:49:14 +0100 (jeu., 05 nov. 2009) | 10 lines Merged revisions 76117 via svnmerge from svn+ssh://pythondev [at] svn/python/trunk ........ r76117 | antoine.pitrou | 2009-11-05 14:42:29 +0100 (jeu., 05 nov. 2009) | 5 lines Issue #7264: Fix a possible deadlock when deallocating thread-local objects which are part of a reference cycle. ........ ................ r76124 | r.david.murray | 2009-11-05 18:49:10 +0100 (jeu., 05 nov. 2009) | 9 lines Blocked revisions 76116 via svnmerge ........ r76116 | r.david.murray | 2009-11-04 20:50:56 -0500 (Wed, 04 Nov 2009) | 3 lines Increase the timeout in the bsddb3 replication test to allow the test time to complete on slow buildbots. See issue 6462. ........ ................ r76133 | jack.diederich | 2009-11-06 18:20:42 +0100 (ven., 06 nov. 2009) | 3 lines - issue #6748 intermittent test failures from sockets - telnetlib tests now use mock sockets for most tests ................ Modified: sandbox/trunk/newgil/ (props changed) sandbox/trunk/newgil/Lib/_threading_local.py sandbox/trunk/newgil/Lib/importlib/test/source/util.py sandbox/trunk/newgil/Lib/test/test_kqueue.py sandbox/trunk/newgil/Lib/test/test_telnetlib.py sandbox/trunk/newgil/Lib/threading.py sandbox/trunk/newgil/Misc/ACKS sandbox/trunk/newgil/Misc/NEWS sandbox/trunk/newgil/Modules/selectmodule.c Modified: sandbox/trunk/newgil/Lib/_threading_local.py ============================================================================== --- sandbox/trunk/newgil/Lib/_threading_local.py (original) +++ sandbox/trunk/newgil/Lib/_threading_local.py Fri Nov 6 20:40:06 2009 @@ -217,10 +217,12 @@ key = object.__getattribute__(self, '_local__key') try: - threads = list(threading.enumerate()) + # We use the non-locking API since we might already hold the lock + # (__del__ can be called at any point by the cyclic GC). + threads = threading._enumerate() except: - # If enumerate fails, as it seems to do during - # shutdown, we'll skip cleanup under the assumption + # If enumerating the current threads fails, as it seems to do + # during shutdown, we'll skip cleanup under the assumption # that there is nothing to clean up. return Modified: sandbox/trunk/newgil/Lib/importlib/test/source/util.py ============================================================================== --- sandbox/trunk/newgil/Lib/importlib/test/source/util.py (original) +++ sandbox/trunk/newgil/Lib/importlib/test/source/util.py Fri Nov 6 20:40:06 2009 @@ -42,8 +42,8 @@ that contains the name passed into the context manager that caused the creation of the module. - All files are created in a temporary directory specified by - tempfile.gettempdir(). This directory is inserted at the beginning of + All files are created in a temporary directory returned by + tempfile.mkdtemp(). This directory is inserted at the beginning of sys.path. When the context manager exits all created files (source and bytecode) are explicitly deleted. @@ -55,8 +55,10 @@ source = 'attr = {0!r}' created_paths = [] mapping = {} + state_manager = None + uncache_manager = None try: - temp_dir = tempfile.gettempdir() + temp_dir = tempfile.mkdtemp() mapping['.root'] = temp_dir import_names = set() for name in names: @@ -85,13 +87,8 @@ state_manager.__enter__() yield mapping finally: - state_manager.__exit__(None, None, None) - uncache_manager.__exit__(None, None, None) - # Reverse the order for path removal to unroll directory creation. - for path in reversed(created_paths): - if file_path.endswith('.py'): - support.unlink(path) - support.unlink(path + 'c') - support.unlink(path + 'o') - else: - os.rmdir(path) + if state_manager is not None: + state_manager.__exit__(None, None, None) + if uncache_manager is not None: + uncache_manager.__exit__(None, None, None) + support.rmtree(temp_dir) Modified: sandbox/trunk/newgil/Lib/test/test_kqueue.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_kqueue.py (original) +++ sandbox/trunk/newgil/Lib/test/test_kqueue.py Fri Nov 6 20:40:06 2009 @@ -71,6 +71,17 @@ self.assertEqual(ev, ev) self.assertNotEqual(ev, other) + bignum = sys.maxsize * 2 + 1 + ev = select.kevent(bignum, 1, 2, 3, sys.maxsize, bignum) + self.assertEqual(ev.ident, bignum) + self.assertEqual(ev.filter, 1) + self.assertEqual(ev.flags, 2) + self.assertEqual(ev.fflags, 3) + self.assertEqual(ev.data, sys.maxsize) + self.assertEqual(ev.udata, bignum) + self.assertEqual(ev, ev) + self.assertNotEqual(ev, other) + def test_queue_event(self): serverSocket = socket.socket() serverSocket.bind(('127.0.0.1', 0)) Modified: sandbox/trunk/newgil/Lib/test/test_telnetlib.py ============================================================================== --- sandbox/trunk/newgil/Lib/test/test_telnetlib.py (original) +++ sandbox/trunk/newgil/Lib/test/test_telnetlib.py Fri Nov 6 20:40:06 2009 @@ -1,48 +1,23 @@ import socket +import select import threading import telnetlib import time -import queue -import sys -import io +import contextlib from unittest import TestCase from test import support HOST = support.HOST -EOF_sigil = object() -def server(evt, serv, dataq=None, test_done=None): - """ Open a tcp server in four steps - 1) set evt to true to let the parent know we are ready - 2) [optional] if is not False, write the list of data from dataq.get() - to the socket. - 3) [optional] if test_done is not None, it's an event; wait - for parent to set test_done before closing connection - 4) set evt to true to let the parent know we're done - """ +def server(evt, serv): serv.listen(5) evt.set() try: conn, addr = serv.accept() - if dataq: - data = b'' - new_data = dataq.get(True, 0.5) - dataq.task_done() - for item in new_data: - if item == EOF_sigil: - break - if type(item) in [int, float]: - time.sleep(item) - else: - data += item - written = conn.send(data) - data = data[written:] except socket.timeout: pass finally: - if test_done is not None: - test_done.wait() serv.close() evt.set() @@ -100,163 +75,159 @@ self.assertEqual(telnet.sock.gettimeout(), 30) telnet.sock.close() -def _read_setUp(self): - self.evt = threading.Event() - self.dataq = queue.Queue() - self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.sock.settimeout(3) - self.port = support.bind_port(self.sock) - self.thread = threading.Thread(target=server, args=(self.evt,self.sock, self.dataq)) - self.thread.start() - self.evt.wait() - self.evt.clear() - time.sleep(.1) - -def _read_tearDown(self): - self.evt.wait() - self.thread.join() +class SocketStub(object): + ''' a socket proxy that re-defines sendall() ''' + def __init__(self, reads=[]): + self.reads = reads + self.writes = [] + self.block = False + def sendall(self, data): + self.writes.append(data) + def recv(self, size): + out = b'' + while self.reads and len(out) < size: + out += self.reads.pop(0) + if len(out) > size: + self.reads.insert(0, out[size:]) + out = out[:size] + return out + +class TelnetAlike(telnetlib.Telnet): + def fileno(self): + raise NotImplementedError() + def close(self): pass + def sock_avail(self): + return (not self.sock.block) + def msg(self, msg, *args): + with support.captured_stdout() as out: + telnetlib.Telnet.msg(self, msg, *args) + self._messages += out.getvalue() + return + +def new_select(*s_args): + block = False + for l in s_args: + for fob in l: + if isinstance(fob, TelnetAlike): + block = fob.sock.block + if block: + return [[], [], []] + else: + return s_args + +@contextlib.contextmanager +def test_socket(reads): + def new_conn(*ignored): + return SocketStub(reads) + try: + old_conn = socket.create_connection + socket.create_connection = new_conn + yield None + finally: + socket.create_connection = old_conn + return + +def test_telnet(reads=[], cls=TelnetAlike): + ''' return a telnetlib.Telnet object that uses a SocketStub with + reads queued up to be read ''' + for x in reads: + assert type(x) is bytes, x + with test_socket(reads): + telnet = cls('dummy', 0) + telnet._messages = '' # debuglevel output + return telnet class ReadTests(TestCase): - setUp = _read_setUp - tearDown = _read_tearDown + def setUp(self): + self.old_select = select.select + select.select = new_select + def tearDown(self): + select.select = self.old_select - # use a similar approach to testing timeouts as test_timeout.py - # these will never pass 100% but make the fuzz big enough that it is rare - block_long = 0.6 - block_short = 0.3 - def test_read_until_A(self): + def test_read_until(self): """ - read_until(expected, [timeout]) - Read until the expected string has been seen, or a timeout is - hit (default is no timeout); may block. + read_until(expected, timeout=None) + test the blocking version of read_util """ - want = [b'x' * 10, b'match', b'y' * 10, EOF_sigil] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() + want = [b'xxxmatchyyy'] + telnet = test_telnet(want) data = telnet.read_until(b'match') - self.assertEqual(data, b''.join(want[:-2])) + self.assertEqual(data, b'xxxmatch', msg=(telnet.cookedq, telnet.rawq, telnet.sock.reads)) - def test_read_until_B(self): - # test the timeout - it does NOT raise socket.timeout - want = [b'hello', self.block_long, b'not seen', EOF_sigil] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - data = telnet.read_until(b'not seen', self.block_short) - self.assertEqual(data, want[0]) - self.assertEqual(telnet.read_all(), b'not seen') + reads = [b'x' * 50, b'match', b'y' * 50] + expect = b''.join(reads[:-1]) + telnet = test_telnet(reads) + data = telnet.read_until(b'match') + self.assertEqual(data, expect) - def test_read_all_A(self): + + def test_read_all(self): """ read_all() Read all data until EOF; may block. """ - want = [b'x' * 500, b'y' * 500, b'z' * 500, EOF_sigil] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() + reads = [b'x' * 500, b'y' * 500, b'z' * 500] + expect = b''.join(reads) + telnet = test_telnet(reads) data = telnet.read_all() - self.assertEqual(data, b''.join(want[:-1])) + self.assertEqual(data, expect) return - def _test_blocking(self, func): - self.dataq.put([self.block_long, EOF_sigil]) - self.dataq.join() - start = time.time() - data = func() - self.assertTrue(self.block_short <= time.time() - start) - - def test_read_all_B(self): - self._test_blocking(telnetlib.Telnet(HOST, self.port).read_all) - - def test_read_all_C(self): - self.dataq.put([EOF_sigil]) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - telnet.read_all() - telnet.read_all() # shouldn't raise - - def test_read_some_A(self): + def test_read_some(self): """ read_some() Read at least one byte or EOF; may block. """ # test 'at least one byte' - want = [b'x' * 500, EOF_sigil] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - data = telnet.read_all() + telnet = test_telnet([b'x' * 500]) + data = telnet.read_some() self.assertTrue(len(data) >= 1) - - def test_read_some_B(self): # test EOF - self.dataq.put([EOF_sigil]) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - self.assertEqual(b'', telnet.read_some()) - - def test_read_some_C(self): - self._test_blocking(telnetlib.Telnet(HOST, self.port).read_some) + telnet = test_telnet() + data = telnet.read_some() + self.assertEqual(b'', data) - def _test_read_any_eager_A(self, func_name): + def _read_eager(self, func_name): """ - read_very_eager() + read_*_eager() Read all data available already queued or on the socket, without blocking. """ - want = [self.block_long, b'x' * 100, b'y' * 100, EOF_sigil] - expects = want[1] + want[2] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() + want = b'x' * 100 + telnet = test_telnet([want]) func = getattr(telnet, func_name) + telnet.sock.block = True + self.assertEqual(b'', func()) + telnet.sock.block = False data = b'' while True: try: data += func() - self.assertTrue(expects.startswith(data)) except EOFError: break - self.assertEqual(expects, data) - - def _test_read_any_eager_B(self, func_name): - # test EOF - self.dataq.put([EOF_sigil]) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - time.sleep(self.block_short) - func = getattr(telnet, func_name) - self.assertRaises(EOFError, func) + self.assertEqual(data, want) - # read_eager and read_very_eager make the same gaurantees - # (they behave differently but we only test the gaurantees) - def test_read_very_eager_A(self): - self._test_read_any_eager_A('read_very_eager') - def test_read_very_eager_B(self): - self._test_read_any_eager_B('read_very_eager') - def test_read_eager_A(self): - self._test_read_any_eager_A('read_eager') - def test_read_eager_B(self): - self._test_read_any_eager_B('read_eager') - # NB -- we need to test the IAC block which is mentioned in the docstring - # but not in the module docs - - def _test_read_any_lazy_B(self, func_name): - self.dataq.put([EOF_sigil]) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - func = getattr(telnet, func_name) - telnet.fill_rawq() - self.assertRaises(EOFError, func) - - def test_read_lazy_A(self): - want = [b'x' * 100, EOF_sigil] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - time.sleep(self.block_short) + def test_read_eager(self): + # read_eager and read_very_eager make the same gaurantees + # (they behave differently but we only test the gaurantees) + self._read_eager('read_eager') + self._read_eager('read_very_eager') + # NB -- we need to test the IAC block which is mentioned in the + # docstring but not in the module docs + + def read_very_lazy(self): + want = b'x' * 100 + telnet = test_telnet([want]) + self.assertEqual(b'', telnet.read_very_lazy()) + while telnet.sock.reads: + telnet.fill_rawq() + data = telnet.read_very_lazy() + self.assertEqual(want, data) + self.assertRaises(EOFError, telnet.read_very_lazy) + + def test_read_lazy(self): + want = b'x' * 100 + telnet = test_telnet([want]) self.assertEqual(b'', telnet.read_lazy()) data = b'' while True: @@ -267,35 +238,8 @@ telnet.fill_rawq() except EOFError: break - self.assertTrue(want[0].startswith(data)) - self.assertEqual(data, want[0]) - - def test_read_lazy_B(self): - self._test_read_any_lazy_B('read_lazy') - - def test_read_very_lazy_A(self): - want = [b'x' * 100, EOF_sigil] - self.dataq.put(want) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - time.sleep(self.block_short) - self.assertEqual(b'', telnet.read_very_lazy()) - data = b'' - while True: - try: - read_data = telnet.read_very_lazy() - except EOFError: - break - data += read_data - if not read_data: - telnet.fill_rawq() - self.assertEqual(b'', telnet.cookedq) - telnet.process_rawq() - self.assertTrue(want[0].startswith(data)) - self.assertEqual(data, want[0]) - - def test_read_very_lazy_B(self): - self._test_read_any_lazy_B('read_very_lazy') + self.assertTrue(want.startswith(data)) + self.assertEqual(data, want) class nego_collector(object): def __init__(self, sb_getter=None): @@ -309,91 +253,32 @@ sb_data = self.sb_getter() self.sb_seen += sb_data -class SocketProxy(object): - ''' a socket proxy that re-defines sendall() ''' - def __init__(self, real_sock): - self.socket = real_sock - self._raw_sent = b'' - def __getattr__(self, k): - return getattr(self.socket, k) - def sendall(self, data): - self._raw_sent += data - self.socket.sendall(data) - -class TelnetSockSendall(telnetlib.Telnet): - def open(self, *args, **opts): - telnetlib.Telnet.open(self, *args, **opts) - self.sock = SocketProxy(self.sock) +tl = telnetlib class WriteTests(TestCase): '''The only thing that write does is replace each tl.IAC for tl.IAC+tl.IAC''' - def setUp(self): - self.evt = threading.Event() - self.test_done = threading.Event() - self.dataq = queue.Queue() - self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.sock.settimeout(3) - self.port = support.bind_port(self.sock) - self.thread = threading.Thread(target=server, args=( - self.evt, self.sock, self.dataq, self.test_done)) - self.thread.start() - self.evt.wait() - self.evt.clear() - time.sleep(.1) - - def tearDown(self): - self.test_done.set() - self.evt.wait() - self.thread.join() - - def _test_write(self, data): - self.telnet.sock._raw_sent = b'' - self.telnet.write(data) - after_write = self.telnet.sock._raw_sent - self.assertEqual(data.replace(tl.IAC,tl.IAC+tl.IAC), - after_write) def test_write(self): - self.telnet = TelnetSockSendall() data_sample = [.b'data sample without IAC', b'data sample with' + tl.IAC + b' one IAC', b'a few' + tl.IAC + tl.IAC + b' iacs' + tl.IAC, tl.IAC, b''] - self.telnet.open(HOST, self.port) - for d in data_sample: - self.dataq.put([b'']) - self._test_write(d) - self.telnet.close() - -tl = telnetlib - -class TelnetDebuglevel(tl.Telnet): - ''' Telnet-alike that captures messages written to stdout when - debuglevel > 0 - ''' - _messages = '' - def msg(self, msg, *args): - orig_stdout = sys.stdout - sys.stdout = fake_stdout = io.StringIO() - tl.Telnet.msg(self, msg, *args) - self._messages += fake_stdout.getvalue() - sys.stdout = orig_stdout - return + for data in data_sample: + telnet = test_telnet() + telnet.write(data) + written = b''.join(telnet.sock.writes) + self.assertEqual(data.replace(tl.IAC,tl.IAC+tl.IAC), written) class OptionTests(TestCase): - setUp = _read_setUp - tearDown = _read_tearDown # RFC 854 commands cmds = [tl.AO, tl.AYT, tl.BRK, tl.EC, tl.EL, tl.GA, tl.IP, tl.NOP] def _test_command(self, data): """ helper for testing IAC + cmd """ - self.setUp() - self.dataq.put(data) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() + telnet = test_telnet(data) + data_len = len(b''.join(data)) nego = nego_collector() telnet.set_option_negotiation_callback(nego.do_nego) txt = telnet.read_all() @@ -401,24 +286,16 @@ self.assertTrue(len(cmd) > 0) # we expect at least one command self.assertTrue(cmd[:1] in self.cmds) self.assertEqual(cmd[1:2], tl.NOOPT) - self.assertEqual(len(b''.join(data[:-1])), len(txt + cmd)) + self.assertEqual(data_len, len(txt + cmd)) nego.sb_getter = None # break the nego => telnet cycle - self.tearDown() def test_IAC_commands(self): - # reset our setup - self.dataq.put([EOF_sigil]) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() - self.tearDown() - for cmd in self.cmds: - self._test_command([tl.IAC, cmd, EOF_sigil]) - self._test_command([b'x' * 100, tl.IAC, cmd, b'y'*100, EOF_sigil]) - self._test_command([b'x' * 10, tl.IAC, cmd, b'y'*10, EOF_sigil]) + self._test_command([tl.IAC, cmd]) + self._test_command([b'x' * 100, tl.IAC, cmd, b'y'*100]) + self._test_command([b'x' * 10, tl.IAC, cmd, b'y'*10]) # all at once - self._test_command([tl.IAC + cmd for (cmd) in self.cmds] + [EOF_sigil]) - self.assertEqual(b'', telnet.read_sb_data()) + self._test_command([tl.IAC + cmd for (cmd) in self.cmds]) def test_SB_commands(self): # RFC 855, subnegotiations portion @@ -427,11 +304,8 @@ tl.IAC + tl.SB + tl.IAC + tl.IAC + b'aa' + tl.IAC + tl.SE, tl.IAC + tl.SB + b'bb' + tl.IAC + tl.IAC + tl.IAC + tl.SE, tl.IAC + tl.SB + b'cc' + tl.IAC + tl.IAC + b'dd' + tl.IAC + tl.SE, - EOF_sigil, ] - self.dataq.put(send) - telnet = telnetlib.Telnet(HOST, self.port) - self.dataq.join() + telnet = test_telnet(send) nego = nego_collector(telnet.read_sb_data) telnet.set_option_negotiation_callback(nego.do_nego) txt = telnet.read_all() @@ -441,19 +315,6 @@ self.assertEqual(b'', telnet.read_sb_data()) nego.sb_getter = None # break the nego => telnet cycle - def _test_debuglevel(self, data, expected_msg): - """ helper for testing debuglevel messages """ - self.setUp() - self.dataq.put(data + [EOF_sigil]) - telnet = TelnetDebuglevel(HOST, self.port) - telnet.set_debuglevel(1) - self.dataq.join() - txt = telnet.read_all() - self.assertTrue(expected_msg in telnet._messages, - msg=(telnet._messages, expected_msg)) - telnet.close() - self.tearDown() - def test_debuglevel_reads(self): # test all the various places that self.msg(...) is called given_a_expect_b = [ @@ -467,21 +328,18 @@ (tl.IAC + tl.WONT + bytes([1]), ": IAC WONT 1\n"), ] for a, b in given_a_expect_b: - self._test_debuglevel([a, EOF_sigil], b) + telnet = test_telnet([a]) + telnet.set_debuglevel(1) + txt = telnet.read_all() + self.assertTrue(b in telnet._messages) return def test_debuglevel_write(self): - self.setUp() - telnet = TelnetDebuglevel(HOST, self.port) + telnet = test_telnet() telnet.set_debuglevel(1) - self.dataq.put([b'', EOF_sigil]) - self.dataq.join() telnet.write(b'xxx') expected = "send b'xxx'\n" - self.assertTrue(expected in telnet._messages, - msg=(telnet._messages, expected)) - telnet.close() - self.tearDown() + self.assertTrue(expected in telnet._messages) def test_main(verbose=None): support.run_unittest(GeneralTests, ReadTests, WriteTests, OptionTests) Modified: sandbox/trunk/newgil/Lib/threading.py ============================================================================== --- sandbox/trunk/newgil/Lib/threading.py (original) +++ sandbox/trunk/newgil/Lib/threading.py Fri Nov 6 20:40:06 2009 @@ -798,6 +798,10 @@ activeCount = active_count +def _enumerate(): + # Same as enumerate(), but without the lock. Internal use only. + return list(_active.values()) + list(_limbo.values()) + def enumerate(): with _active_limbo_lock: return list(_active.values()) + list(_limbo.values()) Modified: sandbox/trunk/newgil/Misc/ACKS ============================================================================== --- sandbox/trunk/newgil/Misc/ACKS (original) +++ sandbox/trunk/newgil/Misc/ACKS Fri Nov 6 20:40:06 2009 @@ -95,6 +95,7 @@ Dave Brennan Tom Bridgman Richard Brodie +Michael Broghton Daniel Brotsky Jean Brouwers Gary S. Brown Modified: sandbox/trunk/newgil/Misc/NEWS ============================================================================== --- sandbox/trunk/newgil/Misc/NEWS (original) +++ sandbox/trunk/newgil/Misc/NEWS Fri Nov 6 20:40:06 2009 @@ -123,6 +123,12 @@ Library ------- +- Issue #7264: Fix a possible deadlock when deallocating thread-local objects + which are part of a reference cycle. + +- Issue #7211: Allow 64-bit values for the `ident` and `data` fields of kevent + objects on 64-bit systems. Patch by Michael Broghton. + - Issue #6896: mailbox.Maildir now invalidates its internal cache each time a modification is done through it. This fixes inconsistencies and test failures on systems with slightly bogus mtime behaviour. @@ -351,6 +357,14 @@ Tests ----- +- Issue #7248 (part 2): Use a unique temporary directory for importlib source + tests instead of tempfile.tempdir. This prevents the tests from sharing state + between concurrent executions on the same system. + +- Issue #7248: In importlib.test.source.util a try/finally block did not make + sure that some referenced objects actually were created in the block before + calling methods on the object. + - Issue #7222: Make thread "reaping" more reliable so that reference leak-chasing test runs give sensible results. The previous method of reaping threads could return successfully while some Thread objects were Modified: sandbox/trunk/newgil/Modules/selectmodule.c ============================================================================== --- sandbox/trunk/newgil/Modules/selectmodule.c (original) +++ sandbox/trunk/newgil/Modules/selectmodule.c Fri Nov 6 20:40:06 2009 @@ -1199,6 +1199,30 @@ #define kqueue_queue_Check(op) (PyObject_TypeCheck((op), &kqueue_queue_Type)) +#if (SIZEOF_UINTPTR_T != SIZEOF_VOID_P) +# error uintptr_t does not match void *! +#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG_LONG) +# define T_UINTPTRT T_ULONGLONG +# define T_INTPTRT T_LONGLONG +# define PyLong_AsUintptr_t PyLong_AsUnsignedLongLong +# define UINTPTRT_FMT_UNIT "K" +# define INTPTRT_FMT_UNIT "L" +#elif (SIZEOF_UINTPTR_T == SIZEOF_LONG) +# define T_UINTPTRT T_ULONG +# define T_INTPTRT T_LONG +# define PyLong_AsUintptr_t PyLong_AsUnsignedLong +# define UINTPTRT_FMT_UNIT "k" +# define INTPTRT_FMT_UNIT "l" +#elif (SIZEOF_UINTPTR_T == SIZEOF_INT) +# define T_UINTPTRT T_UINT +# define T_INTPTRT T_INT +# define PyLong_AsUintptr_t PyLong_AsUnsignedLong +# define UINTPTRT_FMT_UNIT "I" +# define INTPTRT_FMT_UNIT "i" +#else +# error uintptr_t does not match int, long, or long long! +#endif + /* Unfortunately, we can't store python objects in udata, because * kevents in the kernel can be removed without warning, which would * forever lose the refcount on the object stored with it. @@ -1206,12 +1230,12 @@ #define KQ_OFF(x) offsetof(kqueue_event_Object, x) static struct PyMemberDef kqueue_event_members[] = { - {"ident", T_UINT, KQ_OFF(e.ident)}, + {"ident", T_UINTPTRT, KQ_OFF(e.ident)}, {"filter", T_SHORT, KQ_OFF(e.filter)}, {"flags", T_USHORT, KQ_OFF(e.flags)}, {"fflags", T_UINT, KQ_OFF(e.fflags)}, - {"data", T_INT, KQ_OFF(e.data)}, - {"udata", T_INT, KQ_OFF(e.udata)}, + {"data", T_INTPTRT, KQ_OFF(e.data)}, + {"udata", T_UINTPTRT, KQ_OFF(e.udata)}, {NULL} /* Sentinel */ }; #undef KQ_OFF @@ -1222,11 +1246,11 @@ char buf[1024]; PyOS_snprintf( buf, sizeof(buf), - "<select.kevent ident=%lu filter=%d flags=0x%x fflags=0x%x " - "data=0x%lx udata=%p>", - (unsigned long)(s->e.ident), s->e.filter, s->e.flags, - s->e.fflags, (long)(s->e.data), s->e.udata); - return PyBytes_FromString(buf); + "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x " + "data=0x%zd udata=%p>", + (size_t)(s->e.ident), s->e.filter, s->e.flags, + s->e.fflags, (Py_ssize_t)(s->e.data), s->e.udata); + return PyUnicode_FromString(buf); } static int @@ -1235,17 +1259,23 @@ PyObject *pfd; static char *kwlist[] = {"ident", "filter", "flags", "fflags", "data", "udata", NULL}; + static char *fmt = "O|hhi" INTPTRT_FMT_UNIT UINTPTRT_FMT_UNIT ":kevent"; EV_SET(&(self->e), 0, EVFILT_READ, EV_ADD, 0, 0, 0); /* defaults */ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|hhiii:kevent", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist, &pfd, &(self->e.filter), &(self->e.flags), &(self->e.fflags), &(self->e.data), &(self->e.udata))) { return -1; } - self->e.ident = PyObject_AsFileDescriptor(pfd); - if (self->e.ident == -1) { + if (PyLong_Check(pfd)) { + self->e.ident = PyLong_AsUintptr_t(pfd); + } + else { + self->e.ident = PyObject_AsFileDescriptor(pfd); + } + if (PyErr_Occurred()) { return -1; } return 0; @@ -1255,7 +1285,7 @@ kqueue_event_richcompare(kqueue_event_Object *s, kqueue_event_Object *o, int op) { - int result = 0; + Py_intptr_t result = 0; if (!kqueue_event_Check(o)) { if (op == Py_EQ || op == Py_NE) { @@ -1298,7 +1328,7 @@ result = (result > 0); break; } - return PyBool_FromLong(result); + return PyBool_FromLong((long)result); } static PyTypeObject kqueue_event_Type = { _______________________________________________ Python-checkins mailing list Python-checkins [at] python http://mail.python.org/mailman/listinfo/python-checkins
|