test_ok1/contrib/pygreen/pipe/gsocket.py

114 lines
3.0 KiB
Python

from pygreen import greensock2
import socket, errno, os
error = socket.error
class _delegate(object):
def __init__(self, methname):
self.methname = methname
def __get__(self, obj, typ=None):
result = getattr(obj._s, self.methname)
setattr(obj, self.methname, result)
return result
class GreenSocket(object):
def __init__(self, family = socket.AF_INET,
type = socket.SOCK_STREAM,
proto = 0):
self._s = socket.socket(family, type, proto)
self._s.setblocking(False)
def fromsocket(cls, s):
if isinstance(s, GreenSocket):
s = s._s
result = GreenSocket.__new__(cls)
result._s = s
s.setblocking(False)
return result
fromsocket = classmethod(fromsocket)
def accept(self):
while 1:
try:
s, addr = self._s.accept()
break
except error, e:
if e.args[0] not in (errno.EAGAIN, errno.EWOULDBLOCK):
raise
self.wait_input()
return self.fromsocket(s), addr
bind = _delegate("bind")
close = _delegate("close")
def connect(self, addr):
err = self.connect_ex(addr)
if err:
raise error(err, os.strerror(err))
def connect_ex(self, addr):
err = self._s.connect_ex(addr)
if err == errno.EINPROGRESS:
greensock2.wait_output(self._s)
err = self._s.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
return err
#XXX dup
fileno = _delegate("fileno")
getpeername = _delegate("getpeername")
getsockname = _delegate("getsockname")
getsockopt = _delegate("getsockopt")
listen = _delegate("listen")
def makefile(self, mode='r', bufsize=-1):
# hack, but reusing the internal socket._fileobject should just work
return socket._fileobject(self, mode, bufsize)
def recv(self, bufsize):
return greensock2.recv(self._s, bufsize)
def recvall(self, bufsize):
return greensock2.recvall(self._s, bufsize)
def recvfrom(self, bufsize):
self.wait_input()
buf, addr = self._s.recvfrom(bufsize)
if not buf:
raise ConnexionClosed("inbound connexion closed")
return buf, addr
def send(self, data):
self.wait_output()
return self._s.send(data)
def sendto(self, data, addr):
self.wait_output()
return self._s.sendto(data, addr)
def sendall(self, data):
greensock2.sendall(self._s, data)
setsockopt = _delegate("setsockopt")
shutdown = _delegate("shutdown")
def shutdown_rd(self):
try:
self._s.shutdown(socket.SHUT_RD)
except error:
pass
def shutdown_wr(self):
try:
self._s.shutdown(socket.SHUT_WR)
except error:
pass
def wait_input(self):
greensock2.wait_input(self._s)
def wait_output(self):
greensock2.wait_output(self._s)