I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Commit 1aa3e0cc authored by sunshine's avatar sunshine Committed by zzz
Browse files

Fixed bug in select

parent b0f8064d
No related branches found
No related tags found
No related merge requests found
......@@ -67,71 +67,99 @@ def poll():
"""
return Poll()
def _has_data(S):
"""True if the given I2P socket has data waiting."""
try:
S.recv(1, i2p.socket.MSG_PEEK | i2p.socket.MSG_DONTWAIT)
return True
except:
return False
def _noblock_select(readlist, writelist, errlist):
"""Makes a single query of the given sockets, like
select() with timeout 0.0."""
Rans = []
Wans = []
Eans = []
# Check for read availability.
for R in readlist:
if isinstance(R, int) or hasattr(R, 'fileno'):
# Python socket
if len(pyselect.select([R], [], [], 0.0)[0]) > 0:
Rans.append(R)
else:
# SAM Socket
if _has_data(R):
Rans.append(R)
# if R.type == i2p.socket.SOCK_STREAM:
# try:
# R._verify_connected()
# Rans.append(R)
# except:
# pass
# else:
# if len(R.sessobj) > 0: Rans.append(R)
# Check for write availability.
for W in writelist:
if isinstance(W, int) or hasattr(W, 'fileno'):
# Python socket
if len(pyselect.select([], [W], [], 0.0)[1]) > 0:
Wans.append(W)
else:
# SAM Socket
if W.type == i2p.socket.SOCK_STREAM:
try:
W._verify_connected()
Wans.append(W)
except:
pass
else:
Wans.append(W)
# Check for error conditions.
# These can only be stream errors.
for E in errlist:
if isinstance(E, int) or hasattr(E, 'fileno'):
# Python socket
if len(pyselect.select([], [], [E], 0.0)[2]) > 0:
Eans.append(E)
else:
if E.type == i2p.socket.SOCK_STREAM:
try:
# FIXME: Use a ._get_error() function for errors.
# Socket can only have an error if it connected.
E._verify_connected()
if E.sessobj.err != None:
Eans.append(E)
except:
pass
return (Rans, Wans, Eans)
def select(readlist, writelist, errlist, timeout=None):
"""Performs a select call. Works on SAM sockets and Python
sockets. See select.select() in the Python library for more
information."""
Rans = []
Wans = []
Eans = []
if timeout != None: end = time.clock() + timeout
while True:
# FIXME: Check performance.
# Use pyselect.poll for Python sockets, if needed for speed.
(Rans, Wans, Eans) = _noblock_select(readlist,writelist,errlist)
# Check for read availability.
for R in readlist:
if isinstance(R, int) or hasattr(R, 'fileno'):
# Python socket
if len(pyselect.select([R], [], [], 0.0)[0]) > 0:
Rans.append(R)
else:
# SAM Socket
if R.type == i2p.socket.SOCK_STREAM:
try:
R._verify_connected()
Rans.append(R)
except:
pass
else:
if len(R) > 0: Rans.append(R)
# Check for write availability.
for W in writelist:
if isinstance(W, int) or hasattr(W, 'fileno'):
# Python socket
if len(pyselect.select([], [W], [], 0.0)[1]) > 0:
Wans.append(W)
else:
# SAM Socket
if W.type == i2p.socket.SOCK_STREAM:
try:
W._verify_connected()
Wans.append(W)
except:
pass
else:
Wans.append(W)
# Check for error conditions.
# These can only be stream errors.
for E in errlist:
if isinstance(E, int) or hasattr(E, 'fileno'):
# Python socket
if len(pyselect.select([], [], [E], 0.0)[2]) > 0:
Eans.append(E)
else:
if E.type == i2p.socket.SOCK_STREAM:
try:
# FIXME: Use a ._get_error() function for errors.
# Socket can only have an error if it connected.
E._verify_connected()
if E.sessobj.err != None:
Eans.append(E)
except:
pass
if timeout != None and time.clock() >= end: break
if len(Rans) != 0 or len(Wans) != 0 or len(Eans) != 0: break
if len(Rans) != 0 or len(Wans) != 0 or len(Eans) != 0:
# One or more sockets are ready.
if timeout != 0.0:
# Check again, because sockets may have changed state while
# we did _noblock_select (it's safer to check twice, since
# they usually go from no data => data ready, and so forth).
(Rans, Wans, Eans) = _noblock_select(readlist, writelist,
errlist)
return (Rans, Wans, Eans)
time.sleep(0.01)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment