Implement settimeout and gettimeout
This commit is contained in:
@@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
"""
|
"""
|
||||||
from eventlet.api import trampoline, get_hub
|
from eventlet.api import exc_after, TimeoutError, trampoline, get_hub
|
||||||
from eventlet import util
|
from eventlet import util
|
||||||
|
|
||||||
BUFFER_SIZE = 4096
|
BUFFER_SIZE = 4096
|
||||||
@@ -86,37 +86,55 @@ def socket_accept(descriptor):
|
|||||||
|
|
||||||
|
|
||||||
def socket_send(descriptor, data):
|
def socket_send(descriptor, data):
|
||||||
|
timeout = descriptor.gettimeout()
|
||||||
|
if timeout:
|
||||||
|
cancel = exc_after(timeout, TimeoutError)
|
||||||
|
else:
|
||||||
|
cancel = None
|
||||||
try:
|
try:
|
||||||
return descriptor.send(data)
|
try:
|
||||||
except socket.error, e:
|
return descriptor.send(data)
|
||||||
if e[0] == errno.EWOULDBLOCK:
|
except socket.error, e:
|
||||||
|
if e[0] == errno.EWOULDBLOCK:
|
||||||
|
return 0
|
||||||
|
raise
|
||||||
|
except SSL.WantWriteError:
|
||||||
return 0
|
return 0
|
||||||
raise
|
except SSL.WantReadError:
|
||||||
except SSL.WantWriteError:
|
return 0
|
||||||
return 0
|
finally:
|
||||||
except SSL.WantReadError:
|
if cancel:
|
||||||
return 0
|
cancel.cancel()
|
||||||
|
|
||||||
|
|
||||||
# winsock sometimes throws ENOTCONN
|
# winsock sometimes throws ENOTCONN
|
||||||
SOCKET_CLOSED = (errno.ECONNRESET, errno.ENOTCONN, errno.ESHUTDOWN)
|
SOCKET_CLOSED = (errno.ECONNRESET, errno.ENOTCONN, errno.ESHUTDOWN)
|
||||||
def socket_recv(descriptor, buflen):
|
def socket_recv(descriptor, buflen):
|
||||||
|
timeout = descriptor.gettimeout()
|
||||||
|
if timeout:
|
||||||
|
cancel = exc_after(timeout, TimeoutError)
|
||||||
|
else:
|
||||||
|
cancel = None
|
||||||
try:
|
try:
|
||||||
return descriptor.recv(buflen)
|
try:
|
||||||
except socket.error, e:
|
return descriptor.recv(buflen)
|
||||||
if e[0] == errno.EWOULDBLOCK:
|
except socket.error, e:
|
||||||
|
if e[0] == errno.EWOULDBLOCK:
|
||||||
|
return None
|
||||||
|
if e[0] in SOCKET_CLOSED:
|
||||||
|
return ''
|
||||||
|
raise
|
||||||
|
except SSL.WantReadError:
|
||||||
return None
|
return None
|
||||||
if e[0] in SOCKET_CLOSED:
|
except SSL.ZeroReturnError:
|
||||||
return ''
|
return ''
|
||||||
raise
|
except SSL.SysCallError, e:
|
||||||
except SSL.WantReadError:
|
if e[0] == -1 or e[0] > 0:
|
||||||
return None
|
raise socket.error(errno.ECONNRESET, errno.errorcode[errno.ECONNRESET])
|
||||||
except SSL.ZeroReturnError:
|
raise
|
||||||
return ''
|
finally:
|
||||||
except SSL.SysCallError, e:
|
if cancel:
|
||||||
if e[0] == -1 or e[0] > 0:
|
cancel.cancel()
|
||||||
raise socket.error(errno.ECONNRESET, errno.errorcode[errno.ECONNRESET])
|
|
||||||
raise
|
|
||||||
|
|
||||||
|
|
||||||
def file_recv(fd, buflen):
|
def file_recv(fd, buflen):
|
||||||
@@ -149,7 +167,7 @@ def file_send(fd, data):
|
|||||||
|
|
||||||
class GreenSocket(object):
|
class GreenSocket(object):
|
||||||
is_secure = False
|
is_secure = False
|
||||||
|
timeout = None
|
||||||
def __init__(self, fd):
|
def __init__(self, fd):
|
||||||
self.fd = fd
|
self.fd = fd
|
||||||
self._fileno = fd.fileno()
|
self._fileno = fd.fileno()
|
||||||
@@ -254,9 +272,6 @@ class GreenSocket(object):
|
|||||||
fn = self.setblocking = self.fd.setblocking
|
fn = self.setblocking = self.fd.setblocking
|
||||||
return fn(*args, **kw)
|
return fn(*args, **kw)
|
||||||
|
|
||||||
# TODO settimeout
|
|
||||||
# TODO gettimeout
|
|
||||||
|
|
||||||
def setsockopt(self, *args, **kw):
|
def setsockopt(self, *args, **kw):
|
||||||
fn = self.setsockopt = self.fd.setsockopt
|
fn = self.setsockopt = self.fd.setsockopt
|
||||||
return fn(*args, **kw)
|
return fn(*args, **kw)
|
||||||
@@ -264,7 +279,13 @@ class GreenSocket(object):
|
|||||||
def shutdown(self, *args, **kw):
|
def shutdown(self, *args, **kw):
|
||||||
fn = self.shutdown = self.fd.shutdown
|
fn = self.shutdown = self.fd.shutdown
|
||||||
return fn(*args, **kw)
|
return fn(*args, **kw)
|
||||||
|
|
||||||
|
def settimeout(self, howlong):
|
||||||
|
self.timeout = howlong
|
||||||
|
|
||||||
|
def gettimeout(self):
|
||||||
|
return self.timeout
|
||||||
|
|
||||||
|
|
||||||
class GreenFile(object):
|
class GreenFile(object):
|
||||||
newlines = '\r\n'
|
newlines = '\r\n'
|
||||||
|
Reference in New Issue
Block a user