Commit d01b3f46 authored by Denis Bilenko's avatar Denis Bilenko

socket: make recv(), send() and other methods keep the reference to socket so...

socket: make recv(), send() and other methods keep the reference to socket so that fd is not closed while we're waiting

- also expect waitxxx() to be cancelled and exit appropriatelly in such case
parent e6e94a33
...@@ -319,15 +319,16 @@ class socket(object): ...@@ -319,15 +319,16 @@ class socket(object):
return result return result
def accept(self): def accept(self):
sock = self._sock
while True: while True:
try: try:
client_socket, address = self._sock.accept() client_socket, address = sock.accept()
break break
except error, ex: except error, ex:
if ex[0] != errno.EWOULDBLOCK or self.timeout == 0.0: if ex[0] != errno.EWOULDBLOCK or self.timeout == 0.0:
raise raise
sys.exc_clear() sys.exc_clear()
if not wait_read(self._sock.fileno(), timeout=self.timeout, event=self._read_event): if not wait_read(sock.fileno(), timeout=self.timeout, event=self._read_event):
raise error(errno.EBADF, 'Bad file descriptor') raise error(errno.EBADF, 'Bad file descriptor')
return socket(_sock=client_socket), address return socket(_sock=client_socket), address
...@@ -401,9 +402,10 @@ class socket(object): ...@@ -401,9 +402,10 @@ class socket(object):
return _fileobject(self.dup(), mode, bufsize) return _fileobject(self.dup(), mode, bufsize)
def recv(self, *args): def recv(self, *args):
sock = self._sock # keeping the reference so that fd is not closed during waiting
while True: while True:
try: try:
return self._sock.recv(*args) return sock.recv(*args)
except error, ex: except error, ex:
if ex[0] == errno.EBADF: if ex[0] == errno.EBADF:
return '' return ''
...@@ -411,52 +413,61 @@ class socket(object): ...@@ -411,52 +413,61 @@ class socket(object):
raise raise
# QQQ without clearing exc_info test__refcount.test_clean_exit fails # QQQ without clearing exc_info test__refcount.test_clean_exit fails
sys.exc_clear() sys.exc_clear()
wait_read(self.fileno(), timeout=self.timeout, event=self._read_event) if not wait_read(sock.fileno(), timeout=self.timeout, event=self._read_event):
return ''
def recvfrom(self, *args): def recvfrom(self, *args):
sock = self._sock
while True: while True:
try: try:
return self._sock.recvfrom(*args) return sock.recvfrom(*args)
except error, ex: except error, ex:
if ex[0] != EWOULDBLOCK or self.timeout == 0.0: if ex[0] != EWOULDBLOCK or self.timeout == 0.0:
raise raise
sys.exc_clear() sys.exc_clear()
wait_read(self._sock.fileno(), timeout=self.timeout, event=self._read_event) if not wait_read(sock.fileno(), timeout=self.timeout, event=self._read_event):
raise error(errno.EBADF, 'Bad file descriptor')
def recvfrom_into(self, *args): def recvfrom_into(self, *args):
sock = self._sock
while True: while True:
try: try:
return self._sock.recvfrom_into(*args) return sock.recvfrom_into(*args)
except error, ex: except error, ex:
if ex[0] != EWOULDBLOCK or self.timeout == 0.0: if ex[0] != EWOULDBLOCK or self.timeout == 0.0:
raise raise
sys.exc_clear() sys.exc_clear()
wait_read(self._sock.fileno(), timeout=self.timeout, event=self._read_event) if not wait_read(sock.fileno(), timeout=self.timeout, event=self._read_event):
raise error(errno.EBADF, 'Bad file descriptor')
def recv_into(self, *args): def recv_into(self, *args):
sock = self._sock
while True: while True:
try: try:
return self._sock.recv_into(*args) return sock.recv_into(*args)
except error, ex: except error, ex:
if ex[0] == errno.EBADF: if ex[0] == errno.EBADF:
return 0 return 0
if ex[0] != EWOULDBLOCK or self.timeout == 0.0: if ex[0] != EWOULDBLOCK or self.timeout == 0.0:
raise raise
sys.exc_clear() sys.exc_clear()
wait_read(self._sock.fileno(), timeout=self.timeout, event=self._read_event) if not wait_read(sock.fileno(), timeout=self.timeout, event=self._read_event):
return 0
def send(self, data, flags=0, timeout=timeout_default): def send(self, data, flags=0, timeout=timeout_default):
sock = self._sock
if timeout is timeout_default: if timeout is timeout_default:
timeout = self.timeout timeout = self.timeout
try: try:
return self._sock.send(data, flags) return sock.send(data, flags)
except error, ex: except error, ex:
if ex[0] != EWOULDBLOCK or timeout == 0.0: if ex[0] != EWOULDBLOCK or timeout == 0.0:
raise raise
sys.exc_clear() sys.exc_clear()
wait_write(self._sock.fileno(), timeout=timeout, event=self._write_event) if not wait_write(sock.fileno(), timeout=timeout, event=self._write_event):
return 0
try: try:
return self._sock.send(data, flags) return sock.send(data, flags)
except error, ex2: except error, ex2:
if ex2[0] == EWOULDBLOCK: if ex2[0] == EWOULDBLOCK:
return 0 return 0
...@@ -484,15 +495,17 @@ class socket(object): ...@@ -484,15 +495,17 @@ class socket(object):
raise timeout('timed out') raise timeout('timed out')
def sendto(self, *args): def sendto(self, *args):
sock = self._sock
try: try:
return self._sock.sendto(*args) return sock.sendto(*args)
except error, ex: except error, ex:
if ex[0] != EWOULDBLOCK or timeout == 0.0: if ex[0] != EWOULDBLOCK or timeout == 0.0:
raise raise
sys.exc_clear() sys.exc_clear()
wait_write(self.fileno(), timeout=self.timeout, event=self._write_event) if not wait_write(sock.fileno(), timeout=self.timeout, event=self._write_event):
raise error(errno.EBADF, 'Bad file descriptor')
try: try:
return self._sock.sendto(*args) return sock.sendto(*args)
except error, ex2: except error, ex2:
if ex2[0] == EWOULDBLOCK: if ex2[0] == EWOULDBLOCK:
return 0 return 0
......
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