Index: third_party/twisted_8_1/twisted/internet/iocpreactor/tcp.py |
diff --git a/third_party/twisted_8_1/twisted/internet/iocpreactor/tcp.py b/third_party/twisted_8_1/twisted/internet/iocpreactor/tcp.py |
deleted file mode 100644 |
index 2300bef0f47c6683a8fc79f7e62fde5152039f6c..0000000000000000000000000000000000000000 |
--- a/third_party/twisted_8_1/twisted/internet/iocpreactor/tcp.py |
+++ /dev/null |
@@ -1,497 +0,0 @@ |
-# Copyright (c) 2008 Twisted Matrix Laboratories. |
-# See LICENSE for details. |
- |
- |
-""" |
-TCP support for IOCP reactor |
-""" |
- |
-from twisted.internet import interfaces, error, address, main, defer |
-from twisted.internet.abstract import isIPAddress |
-from twisted.internet.tcp import _SocketCloser, Connector as TCPConnector |
-from twisted.persisted import styles |
-from twisted.python import log, failure, reflect, util |
- |
-from zope.interface import implements |
-import socket, operator, errno, struct |
- |
-from twisted.internet.iocpreactor import iocpsupport as _iocp, abstract |
-from twisted.internet.iocpreactor.interfaces import IReadWriteHandle |
-from twisted.internet.iocpreactor.const import ERROR_IO_PENDING |
-from twisted.internet.iocpreactor.const import SO_UPDATE_CONNECT_CONTEXT |
-from twisted.internet.iocpreactor.const import SO_UPDATE_ACCEPT_CONTEXT |
-from twisted.internet.iocpreactor.const import ERROR_CONNECTION_REFUSED |
-from twisted.internet.iocpreactor.const import ERROR_NETWORK_UNREACHABLE |
- |
-# ConnectEx returns these. XXX: find out what it does for timeout |
-connectExErrors = { |
- ERROR_CONNECTION_REFUSED: errno.WSAECONNREFUSED, |
- ERROR_NETWORK_UNREACHABLE: errno.WSAENETUNREACH, |
- } |
- |
- |
- |
-class Connection(abstract.FileHandle, _SocketCloser): |
- implements(IReadWriteHandle, interfaces.ITCPTransport, |
- interfaces.ISystemHandle) |
- |
- |
- def __init__(self, sock, proto, reactor=None): |
- abstract.FileHandle.__init__(self, reactor) |
- self.socket = sock |
- self.getFileHandle = sock.fileno |
- self.protocol = proto |
- |
- |
- def getHandle(self): |
- return self.socket |
- |
- |
- def dataReceived(self, rbuffer): |
- # XXX: some day, we'll have protocols that can handle raw buffers |
- self.protocol.dataReceived(str(rbuffer)) |
- |
- |
- def readFromHandle(self, bufflist, evt): |
- return _iocp.recv(self.getFileHandle(), bufflist, evt) |
- |
- |
- def writeToHandle(self, buff, evt): |
- return _iocp.send(self.getFileHandle(), buff, evt) |
- |
- |
- def _closeWriteConnection(self): |
- try: |
- getattr(self.socket, self._socketShutdownMethod)(1) |
- except socket.error: |
- pass |
- p = interfaces.IHalfCloseableProtocol(self.protocol, None) |
- if p: |
- try: |
- p.writeConnectionLost() |
- except: |
- f = failure.Failure() |
- log.err() |
- self.connectionLost(f) |
- |
- |
- def readConnectionLost(self, reason): |
- p = interfaces.IHalfCloseableProtocol(self.protocol, None) |
- if p: |
- try: |
- p.readConnectionLost() |
- except: |
- log.err() |
- self.connectionLost(failure.Failure()) |
- else: |
- self.connectionLost(reason) |
- |
- |
- def connectionLost(self, reason): |
- abstract.FileHandle.connectionLost(self, reason) |
- self._closeSocket() |
- protocol = self.protocol |
- del self.protocol |
- del self.socket |
- del self.getFileHandle |
- protocol.connectionLost(reason) |
- |
- |
- def logPrefix(self): |
- """ |
- Return the prefix to log with when I own the logging thread. |
- """ |
- return self.logstr |
- |
- |
- def getTcpNoDelay(self): |
- return operator.truth(self.socket.getsockopt(socket.IPPROTO_TCP, |
- socket.TCP_NODELAY)) |
- |
- |
- def setTcpNoDelay(self, enabled): |
- self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, enabled) |
- |
- |
- def getTcpKeepAlive(self): |
- return operator.truth(self.socket.getsockopt(socket.SOL_SOCKET, |
- socket.SO_KEEPALIVE)) |
- |
- |
- def setTcpKeepAlive(self, enabled): |
- self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, enabled) |
- |
- |
- |
-class Client(Connection): |
- addressFamily = socket.AF_INET |
- socketType = socket.SOCK_STREAM |
- |
- |
- def __init__(self, host, port, bindAddress, connector, reactor): |
- self.connector = connector |
- self.addr = (host, port) |
- self.reactor = reactor |
- # ConnectEx documentation says socket _has_ to be bound |
- if bindAddress is None: |
- bindAddress = ('', 0) |
- |
- try: |
- try: |
- skt = reactor.createSocket(self.addressFamily, self.socketType) |
- except socket.error, se: |
- raise error.ConnectBindError(se[0], se[1]) |
- else: |
- try: |
- skt.bind(bindAddress) |
- except socket.error, se: |
- raise error.ConnectBindError(se[0], se[1]) |
- self.socket = skt |
- Connection.__init__(self, skt, None) |
- reactor.callLater(0, self.resolveAddress) |
- except error.ConnectBindError, err: |
- reactor.callLater(0, self.failIfNotConnected, err) |
- |
- |
- def resolveAddress(self): |
- if isIPAddress(self.addr[0]): |
- self._setRealAddress(self.addr[0]) |
- else: |
- d = self.reactor.resolve(self.addr[0]) |
- d.addCallbacks(self._setRealAddress, self.failIfNotConnected) |
- |
- |
- def _setRealAddress(self, address): |
- self.realAddress = (address, self.addr[1]) |
- self.doConnect() |
- |
- |
- def failIfNotConnected(self, err): |
- if (self.connected or self.disconnected or |
- not hasattr(self, "connector")): |
- return |
- |
- try: |
- self._closeSocket() |
- except AttributeError: |
- pass |
- else: |
- del self.socket, self.getFileHandle |
- self.reactor.removeActiveHandle(self) |
- |
- self.connector.connectionFailed(failure.Failure(err)) |
- del self.connector |
- |
- |
- def stopConnecting(self): |
- """ |
- Stop attempt to connect. |
- """ |
- self.failIfNotConnected(error.UserError()) |
- |
- |
- def cbConnect(self, rc, bytes, evt): |
- if rc: |
- rc = connectExErrors.get(rc, rc) |
- self.failIfNotConnected(error.getConnectError((rc, |
- errno.errorcode.get(rc, 'Unknown error')))) |
- else: |
- self.socket.setsockopt(socket.SOL_SOCKET, |
- SO_UPDATE_CONNECT_CONTEXT, |
- struct.pack('I', self.socket.fileno())) |
- self.protocol = self.connector.buildProtocol(self.getPeer()) |
- self.connected = True |
- self.logstr = self.protocol.__class__.__name__+",client" |
- self.protocol.makeConnection(self) |
- self.startReading() |
- |
- |
- def doConnect(self): |
- if not hasattr(self, "connector"): |
- # this happens if we connector.stopConnecting in |
- # factory.startedConnecting |
- return |
- assert _iocp.have_connectex |
- self.reactor.addActiveHandle(self) |
- evt = _iocp.Event(self.cbConnect, self) |
- |
- rc = _iocp.connect(self.socket.fileno(), self.realAddress, evt) |
- if rc == ERROR_IO_PENDING: |
- return |
- else: |
- evt.ignore = True |
- self.cbConnect(rc, 0, 0, evt) |
- |
- |
- def getHost(self): |
- """ |
- Returns an IPv4Address. |
- |
- This indicates the address from which I am connecting. |
- """ |
- return address.IPv4Address('TCP', *(self.socket.getsockname() + |
- ('INET',))) |
- |
- |
- def getPeer(self): |
- """ |
- Returns an IPv4Address. |
- |
- This indicates the address that I am connected to. |
- """ |
- return address.IPv4Address('TCP', *(self.addr + ('INET',))) |
- |
- |
- def __repr__(self): |
- s = ('<%s to %s at %x>' % |
- (self.__class__, self.addr, util.unsignedID(self))) |
- return s |
- |
- |
- def connectionLost(self, reason): |
- if not self.connected: |
- self.failIfNotConnected(error.ConnectError(string=reason)) |
- else: |
- Connection.connectionLost(self, reason) |
- self.connector.connectionLost(reason) |
- |
- |
- |
-class Server(Connection): |
- """ |
- Serverside socket-stream connection class. |
- |
- I am a serverside network connection transport; a socket which came from an |
- accept() on a server. |
- """ |
- |
- |
- def __init__(self, sock, protocol, clientAddr, serverAddr, sessionno): |
- """ |
- Server(sock, protocol, client, server, sessionno) |
- |
- Initialize me with a socket, a protocol, a descriptor for my peer (a |
- tuple of host, port describing the other end of the connection), an |
- instance of Port, and a session number. |
- """ |
- Connection.__init__(self, sock, protocol) |
- self.serverAddr = serverAddr |
- self.clientAddr = clientAddr |
- self.sessionno = sessionno |
- self.logstr = "%s,%s,%s" % (self.protocol.__class__.__name__, |
- sessionno, self.clientAddr.host) |
- self.repstr = "<%s #%s on %s>" % (self.protocol.__class__.__name__, |
- self.sessionno, self.serverAddr.port) |
- self.connected = True |
- self.startReading() |
- |
- |
- def __repr__(self): |
- """ |
- A string representation of this connection. |
- """ |
- return self.repstr |
- |
- |
- def getHost(self): |
- """ |
- Returns an IPv4Address. |
- |
- This indicates the server's address. |
- """ |
- return self.serverAddr |
- |
- |
- def getPeer(self): |
- """ |
- Returns an IPv4Address. |
- |
- This indicates the client's address. |
- """ |
- return self.clientAddr |
- |
- |
- |
-class Connector(TCPConnector): |
- def _makeTransport(self): |
- return Client(self.host, self.port, self.bindAddress, self, |
- self.reactor) |
- |
- |
- |
-class Port(styles.Ephemeral, _SocketCloser): |
- implements(interfaces.IListeningPort) |
- |
- connected = False |
- disconnected = False |
- disconnecting = False |
- addressFamily = socket.AF_INET |
- socketType = socket.SOCK_STREAM |
- |
- sessionno = 0 |
- |
- maxAccepts = 100 |
- |
- # Actual port number being listened on, only set to a non-None |
- # value when we are actually listening. |
- _realPortNumber = None |
- |
- |
- def __init__(self, port, factory, backlog=50, interface='', reactor=None): |
- self.port = port |
- self.factory = factory |
- self.backlog = backlog |
- self.interface = interface |
- self.reactor = reactor |
- |
- skt = socket.socket(self.addressFamily, self.socketType) |
- self.addrLen = _iocp.maxAddrLen(skt.fileno()) |
- |
- |
- def __repr__(self): |
- if self._realPortNumber is not None: |
- return "<%s of %s on %s>" % (self.__class__, |
- self.factory.__class__, |
- self._realPortNumber) |
- else: |
- return "<%s of %s (not listening)>" % (self.__class__, |
- self.factory.__class__) |
- |
- |
- def startListening(self): |
- try: |
- skt = self.reactor.createSocket(self.addressFamily, |
- self.socketType) |
- # TODO: resolve self.interface if necessary |
- skt.bind((self.interface, self.port)) |
- except socket.error, le: |
- raise error.CannotListenError, (self.interface, self.port, le) |
- |
- # Make sure that if we listened on port 0, we update that to |
- # reflect what the OS actually assigned us. |
- self._realPortNumber = skt.getsockname()[1] |
- |
- log.msg("%s starting on %s" % (self.factory.__class__, |
- self._realPortNumber)) |
- |
- self.factory.doStart() |
- skt.listen(self.backlog) |
- self.connected = True |
- self.reactor.addActiveHandle(self) |
- self.socket = skt |
- self.getFileHandle = self.socket.fileno |
- self.doAccept() |
- |
- |
- def loseConnection(self, connDone=failure.Failure(main.CONNECTION_DONE)): |
- """ |
- Stop accepting connections on this port. |
- |
- This will shut down my socket and call self.connectionLost(). |
- It returns a deferred which will fire successfully when the |
- port is actually closed. |
- """ |
- self.disconnecting = True |
- if self.connected: |
- self.deferred = defer.Deferred() |
- self.reactor.callLater(0, self.connectionLost, connDone) |
- return self.deferred |
- |
- stopListening = loseConnection |
- |
- |
- def connectionLost(self, reason): |
- """ |
- Cleans up my socket. |
- """ |
- log.msg('(Port %s Closed)' % self._realPortNumber) |
- self._realPortNumber = None |
- self.disconnected = True |
- self.reactor.removeActiveHandle(self) |
- self.connected = False |
- self._closeSocket() |
- del self.socket |
- del self.getFileHandle |
- self.factory.doStop() |
- if hasattr(self, "deferred"): |
- self.deferred.callback(None) |
- del self.deferred |
- |
- |
- def logPrefix(self): |
- """ |
- Returns the name of my class, to prefix log entries with. |
- """ |
- return reflect.qual(self.factory.__class__) |
- |
- |
- def getHost(self): |
- """ |
- Returns an IPv4Address. |
- |
- This indicates the server's address. |
- """ |
- return address.IPv4Address('TCP', *(self.socket.getsockname() + |
- ('INET',))) |
- |
- |
- def cbAccept(self, rc, bytes, evt): |
- self.handleAccept(rc, evt) |
- if not (self.disconnecting or self.disconnected): |
- self.doAccept() |
- |
- |
- def handleAccept(self, rc, evt): |
- if self.disconnecting or self.disconnected: |
- return False |
- |
- # possible errors: |
- # (WSAEMFILE, WSAENOBUFS, WSAENFILE, WSAENOMEM, WSAECONNABORTED) |
- if rc: |
- log.msg("Could not accept new connection -- %s (%s)" % |
- (errno.errorcode.get(rc, 'unknown error'), rc)) |
- return False |
- else: |
- evt.newskt.setsockopt(socket.SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, |
- struct.pack('I', self.socket.fileno())) |
- family, lAddr, rAddr = _iocp.get_accept_addrs(evt.newskt.fileno(), |
- evt.buff) |
- assert family == self.addressFamily |
- |
- protocol = self.factory.buildProtocol( |
- address._ServerFactoryIPv4Address('TCP', rAddr[0], rAddr[1])) |
- if protocol is None: |
- evt.newskt.close() |
- else: |
- s = self.sessionno |
- self.sessionno = s+1 |
- transport = Server(evt.newskt, protocol, |
- address.IPv4Address('TCP', rAddr[0], rAddr[1], 'INET'), |
- address.IPv4Address('TCP', lAddr[0], lAddr[1], 'INET'), |
- s) |
- protocol.makeConnection(transport) |
- return True |
- |
- |
- def doAccept(self): |
- numAccepts = 0 |
- while 1: |
- evt = _iocp.Event(self.cbAccept, self) |
- |
- # see AcceptEx documentation |
- evt.buff = buff = _iocp.AllocateReadBuffer(2 * (self.addrLen + 16)) |
- |
- evt.newskt = newskt = self.reactor.createSocket(self.addressFamily, |
- self.socketType) |
- rc = _iocp.accept(self.socket.fileno(), newskt.fileno(), buff, evt) |
- |
- if (rc == ERROR_IO_PENDING |
- or (not rc and numAccepts >= self.maxAccepts)): |
- break |
- else: |
- evt.ignore = True |
- if not self.handleAccept(rc, evt): |
- break |
- numAccepts += 1 |
- |
- |