Commit 7fa0f290 authored by Jay Oster's avatar Jay Oster

Fix EPROTOTYPE race condition on macOS [supersedes #1033]

parent 778b8f44
......@@ -322,7 +322,7 @@ class socket(object):
try:
return sock.send(data, flags)
except error as ex:
if ex.args[0] != EWOULDBLOCK or timeout == 0.0:
if ex.args[0] not in _socketcommon.GSENDAGAIN or timeout == 0.0:
raise
sys.exc_clear()
self._wait(self._write_event)
......
......@@ -389,7 +389,7 @@ class socket(object):
try:
return _socket.socket.send(self._sock, data, flags)
except error as ex:
if ex.args[0] != EWOULDBLOCK or timeout == 0.0:
if ex.args[0] not in _socketcommon.GSENDAGAIN or timeout == 0.0:
raise
self._wait(self._write_event)
try:
......
......@@ -78,6 +78,8 @@ from gevent._util import copy_globals
from gevent._util import _NONE
is_windows = sys.platform == 'win32'
is_macos = sys.platform == 'darwin'
# pylint:disable=no-name-in-module,unused-import
if is_windows:
# no such thing as WSAEPERM or error code 10001 according to winsock.h or MSDN
......@@ -102,6 +104,17 @@ try:
except ImportError:
EBADF = 9
# macOS can return EPROTOTYPE when writing to a socket that is shutting
# Down. Retrying the write should return the expected EPIPE error.
# Downstream classes (like pywsgi) know how to handle/ignore EPIPE.
# This set is used by socket.send() to decide whether the write should
# be retried. The default is to retry only on EWOULDBLOCK. Here we add
# EPROTOTYPE on macOS to handle this platform-specific race condition.
GSENDAGAIN = (EWOULDBLOCK,)
if is_macos:
from errno import EPROTOTYPE
GSENDAGAIN += (EPROTOTYPE,)
import _socket
_realsocket = _socket.socket
import socket as __socket__
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment