Author: Brian Kearns <[email protected]>
Branch: stdlib-2.7.6
Changeset: r69647:b659126507d5
Date: 2014-03-03 18:55 -0500
http://bitbucket.org/pypy/pypy/changeset/b659126507d5/
Log: raise exception on concurrent calls to poll() (cpython issue8865)
diff --git a/pypy/module/select/interp_select.py
b/pypy/module/select/interp_select.py
--- a/pypy/module/select/interp_select.py
+++ b/pypy/module/select/interp_select.py
@@ -19,6 +19,7 @@
class Poll(W_Root):
def __init__(self):
self.fddict = {}
+ self.running = False
@unwrap_spec(events="c_short")
def register(self, space, w_fd, events=defaultevents):
@@ -41,7 +42,7 @@
raise OperationError(space.w_KeyError,
space.wrap(fd)) # XXX should this maybe be
w_fd?
- @unwrap_spec(w_timeout = WrappedDefault(None))
+ @unwrap_spec(w_timeout=WrappedDefault(None))
def poll(self, space, w_timeout):
if space.is_w(w_timeout, space.w_None):
timeout = -1
@@ -56,6 +57,9 @@
"timeout must be an integer or None")
timeout = space.c_int_w(w_timeout)
+ if self.running:
+ raise oefmt(space.w_RuntimeError, "concurrent poll() invocation")
+ self.running = True
try:
retval = rpoll.poll(self.fddict, timeout)
except rpoll.PollError, e:
@@ -64,6 +68,8 @@
raise OperationError(w_errortype,
space.newtuple([space.wrap(e.errno),
space.wrap(message)]))
+ finally:
+ self.running = False
retval_w = []
for fd, revents in retval:
diff --git a/pypy/module/select/test/test_select.py
b/pypy/module/select/test/test_select.py
--- a/pypy/module/select/test/test_select.py
+++ b/pypy/module/select/test/test_select.py
@@ -1,5 +1,4 @@
import sys
-
import py
from pypy.interpreter.error import OperationError
@@ -234,7 +233,7 @@
class AppTestSelectWithPipes(_AppTestSelect):
"Use a pipe to get pairs of file descriptors"
spaceconfig = {
- "usemodules": ["select", "rctime"]
+ "usemodules": ["select", "rctime", "thread"]
}
def setup_class(cls):
@@ -258,6 +257,37 @@
s1, s2 = os.pipe()
return FileAsSocket(s1), FileAsSocket(s2)
+ def test_poll_threaded(self):
+ import os, select, threading, time
+ if not hasattr(select, 'poll'):
+ skip("no select.poll() on this platform")
+ r, w = os.pipe()
+ rfds = [os.dup(r) for _ in range(10)]
+ try:
+ pollster = select.poll()
+ for fd in rfds:
+ pollster.register(fd, select.POLLIN)
+
+ t = threading.Thread(target=pollster.poll)
+ t.start()
+ try:
+ time.sleep(0.5); print '', # print to release GIL untranslated
+ # trigger ufds array reallocation
+ for fd in rfds:
+ pollster.unregister(fd)
+ pollster.register(w, select.POLLOUT)
+ exc = raises(RuntimeError, pollster.poll)
+ assert exc.value[0] == 'concurrent poll() invocation'
+ finally:
+ # and make the call to poll() from the thread return
+ os.write(w, b'spam')
+ t.join()
+ finally:
+ os.close(r)
+ os.close(w)
+ for fd in rfds:
+ os.close(fd)
+
class AppTestSelectWithSockets(_AppTestSelect):
"""Same tests with connected sockets.
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit