[Python-checkins] cpython (3.2): fix #10340: properly handle EINVAL on OSX and also avoid to call
giampaolo.rodola
python-checkins at python.org
Thu Mar 22 16:19:53 CET 2012
http://hg.python.org/cpython/rev/e2cddb3f4526
changeset: 75881:e2cddb3f4526
branch: 3.2
parent: 75877:79422b3684f1
user: Giampaolo Rodola' <g.rodola at gmail.com>
date: Thu Mar 22 16:17:43 2012 +0100
summary:
fix #10340: properly handle EINVAL on OSX and also avoid to call handle_connect() in case of a disconnetected socket which is not meant to connect.
files:
Lib/asyncore.py | 17 +++++++++--------
Lib/test/test_asyncore.py | 16 ++++++++++++++++
2 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/Lib/asyncore.py b/Lib/asyncore.py
--- a/Lib/asyncore.py
+++ b/Lib/asyncore.py
@@ -225,6 +225,7 @@
debug = False
connected = False
accepting = False
+ connecting = False
closing = False
addr = None
ignore_log_types = frozenset(['warning'])
@@ -248,7 +249,7 @@
try:
self.addr = sock.getpeername()
except socket.error as err:
- if err.args[0] == ENOTCONN:
+ if err.args[0] in (ENOTCONN, EINVAL):
# To handle the case where we got an unconnected
# socket.
self.connected = False
@@ -342,6 +343,7 @@
def connect(self, address):
self.connected = False
+ self.connecting = True
err = self.socket.connect_ex(address)
if err in (EINPROGRESS, EALREADY, EWOULDBLOCK) \
or err == EINVAL and os.name in ('nt', 'ce'):
@@ -401,6 +403,7 @@
def close(self):
self.connected = False
self.accepting = False
+ self.connecting = False
self.del_channel()
try:
self.socket.close()
@@ -439,7 +442,8 @@
# sockets that are connected
self.handle_accept()
elif not self.connected:
- self.handle_connect_event()
+ if self.connecting:
+ self.handle_connect_event()
self.handle_read()
else:
self.handle_read()
@@ -450,6 +454,7 @@
raise socket.error(err, _strerror(err))
self.handle_connect()
self.connected = True
+ self.connecting = False
def handle_write_event(self):
if self.accepting:
@@ -458,12 +463,8 @@
return
if not self.connected:
- #check for errors
- err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
- if err != 0:
- raise socket.error(err, _strerror(err))
-
- self.handle_connect_event()
+ if self.connecting:
+ self.handle_connect_event()
self.handle_write()
def handle_expt_event(self):
diff --git a/Lib/test/test_asyncore.py b/Lib/test/test_asyncore.py
--- a/Lib/test/test_asyncore.py
+++ b/Lib/test/test_asyncore.py
@@ -7,6 +7,7 @@
import time
import warnings
import errno
+import struct
from test import support
from test.support import TESTFN, run_unittest, unlink
@@ -730,6 +731,21 @@
finally:
sock.close()
+ @unittest.skipUnless(threading, 'Threading required for this test.')
+ @support.reap_threads
+ def test_quick_connect(self):
+ # see: http://bugs.python.org/issue10340
+ server = TCPServer()
+ t = threading.Thread(target=lambda: asyncore.loop(timeout=0.1, count=500))
+ t.start()
+
+ for x in range(20):
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER,
+ struct.pack('ii', 1, 0))
+ s.connect(server.address)
+ s.close()
+
class TestAPI_UseSelect(BaseTestAPI):
use_poll = False
--
Repository URL: http://hg.python.org/cpython
More information about the Python-checkins
mailing list