Implement settimeout and gettimeout

This commit is contained in:
donovan
2008-04-29 18:34:28 -07:00
parent a253013629
commit f61bcd8621

View File

@@ -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'