def startListening(self): """Create and bind my socket, and begin listening on it. This is called on unserialization, and must be called after creating a server to begin listening on the specified port. """ log.msg("%s starting on %r" % (self.factory.__class__, repr(self.port))) if self.wantPID: self.lockFile = lockfile.FilesystemLock(self.port + ".lock") if not self.lockFile.lock(): raise CannotListenError, (None, self.port, "Cannot acquire lock") else: if not self.lockFile.clean: try: # This is a best-attempt at cleaning up # left-over unix sockets on the filesystem. # If it fails, there's not much else we can # do. The bind() below will fail with an # exception that actually propegates. if stat.S_ISSOCK(os.stat(self.port).st_mode): os.remove(self.port) except: pass self.factory.doStart() try: skt = self.createInternetSocket() skt.bind(self.port) except socket.error, le: raise CannotListenError, (None, self.port, le)
def throttleReads(self): """ Throttle reads on all protocols. """ log.msg("Throttling reads on %s" % self) for p in self.protocols.keys(): p.throttleReads()
def unpickleModule(name): 'support function for copy_reg to unpickle module refs' if oldModules.has_key(name): log.msg("Module has moved: %s" % name) name = oldModules[name] log.msg(name) return __import__(name, {}, {}, 'x')
def throttleWrites(self): """ Throttle writes on all protocols. """ log.msg("Throttling writes on %s" % self) for p in self.protocols.keys(): p.throttleWrites()
def _close(self, conn): if self.noisy: log.msg('adbapi closing: %s' % (self.dbapiName, )) try: conn.close() except: log.err(None, "Connection close failed")
def _close(self, conn): if self.noisy: log.msg('adbapi closing: %s' % (self.dbapiName,)) try: conn.close() except: log.err(None, "Connection close failed")
def __getstate__(self): log.msg("WARNING: serializing ephemeral %s" % self) import gc if getattr(gc, 'get_referrers', None): for r in gc.get_referrers(self): log.msg(" referred to by %s" % (r, )) return None
def unpickleModule(name): 'support function for copy_reg to unpickle module refs' if oldModules.has_key(name): log.msg("Module has moved: %s" % name) name = oldModules[name] log.msg(name) return __import__(name,{},{},'x')
def _readAndWrite(self, source, condition): # note: gtk-1.2's gtk_input_add presents an API in terms of gdk # constants like INPUT_READ and INPUT_WRITE. Internally, it will add # POLL_HUP and POLL_ERR to the poll() events, but if they happen it # will turn them back into INPUT_READ and INPUT_WRITE. gdkevents.c # maps IN/HUP/ERR to INPUT_READ, and OUT/ERR to INPUT_WRITE. This # means there is no immediate way to detect a disconnected socket. # The g_io_add_watch() API is more suited to this task. I don't think # pygtk exposes it, though. why = None didRead = None try: if condition & gtk.GDK.INPUT_READ: why = source.doRead() didRead = source.doRead if not why and condition & gtk.GDK.INPUT_WRITE: # if doRead caused connectionLost, don't call doWrite # if doRead is doWrite, don't call it again. if not source.disconnected and source.doWrite != didRead: why = source.doWrite() didRead = source.doWrite # if failed it was in write except: why = sys.exc_info()[1] log.msg('Error In %s' % source) log.deferr() if why: self._disconnectSelectable(source, why, didRead == source.doRead)
def __getstate__(self): log.msg( "WARNING: serializing ephemeral %s" % self ) import gc if getattr(gc, 'get_referrers', None): for r in gc.get_referrers(self): log.msg( " referred to by %s" % (r,)) return None
def unpickleMethod(im_name, im_self, im_class): 'support function for copy_reg to unpickle method refs' try: unbound = getattr(im_class,im_name) if im_self is None: return unbound bound=instancemethod(unbound.im_func, im_self, im_class) return bound except AttributeError: log.msg("Method",im_name,"not on class",im_class) assert im_self is not None,"No recourse: no instance to guess from." # Attempt a common fix before bailing -- if classes have # changed around since we pickled this method, we may still be # able to get it by looking on the instance's current class. unbound = getattr(im_self.__class__,im_name) log.msg("Attempting fixup with",unbound) if im_self is None: return unbound bound=instancemethod(unbound.im_func, im_self, im_self.__class__) return bound
def _doReadOrWrite(self, source, condition, faildict={ error.ConnectionDone: failure.Failure(error.ConnectionDone()), error.ConnectionLost: failure.Failure(error.ConnectionLost()), }): why = None inRead = False if condition & POLL_DISCONNECTED and not (condition & gobject.IO_IN): if source in self._reads: why = main.CONNECTION_DONE inRead = True else: why = main.CONNECTION_LOST else: try: if condition & gobject.IO_IN: why = source.doRead() inRead = True if not why and condition & gobject.IO_OUT: # if doRead caused connectionLost, don't call doWrite # if doRead is doWrite, don't call it again. if not source.disconnected: why = source.doWrite() except: why = sys.exc_info()[1] log.msg('Error In %s' % source) log.deferr() if why: self._disconnectSelectable(source, why, inRead)
def doWaitForMultipleEvents(self, timeout): log.msg(channel='system', event='iteration', reactor=self) if timeout is None: #timeout = INFINITE timeout = 100 else: timeout = int(timeout * 1000) if not (self._events or self._writes): # sleep so we don't suck up CPU time time.sleep(timeout / 1000.0) return canDoMoreWrites = 0 for fd in self._writes.keys(): if log.callWithLogger(fd, self._runWrite, fd): canDoMoreWrites = 1 if canDoMoreWrites: timeout = 0 handles = self._events.keys() or [self.dummyEvent] val = MsgWaitForMultipleObjects(handles, 0, timeout, QS_ALLINPUT | QS_ALLEVENTS) if val == WAIT_TIMEOUT: return elif val == WAIT_OBJECT_0 + len(handles): exit = win32gui.PumpWaitingMessages() if exit: self.callLater(0, self.stop) return elif val >= WAIT_OBJECT_0 and val < WAIT_OBJECT_0 + len(handles): fd, action = self._events[handles[val - WAIT_OBJECT_0]] log.callWithLogger(fd, self._runAction, action, fd)
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, self.reactor) protocol.makeConnection(transport) return True
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, self.reactor) protocol.makeConnection(transport) return True
def reapProcess(self): """ Try to reap a process (without blocking) via waitpid. This is called when sigchild is caught or a Process object loses its "connection" (stdout is closed) This ought to result in reaping all zombie processes, since it will be called twice as often as it needs to be. (Unfortunately, this is a slightly experimental approach, since UNIX has no way to be really sure that your process is going to go away w/o blocking. I don't want to block.) """ try: try: pid, status = os.waitpid(self.pid, os.WNOHANG) except OSError, e: if e.errno == errno.ECHILD: # no child process pid = None else: raise except: log.msg('Failed to reap %d:' % self.pid) log.err() pid = None if pid: self.processEnded(status) unregisterReapProcessHandler(pid, self)
def buildProtocol(self): if self.ircui: log.msg("already logged in") return None i = IRCUserInterface() i.factory = self self.ircui = i return i
def lineReceived(self, line): if not self.queries: log.msg("Unexpected server response: %r" % (line,)) else: d, _, _ = self.queries.pop(0) self.parseResponse(d, line) if self.queries: self.sendLine('%d, %d' % (self.queries[0][1], self.queries[0][2]))
def _bindSocket(self): log.msg("%s starting on %s"%(self.protocol.__class__, repr(self.port))) try: skt = self.createInternetSocket() # XXX: haha misnamed method if self.port: skt.bind(self.port) except socket.error, le: raise error.CannotListenError, (None, self.port, le)
def jelly(self, obj): try: ao = self.jellyToAO(obj) return ao except: log.msg("Error jellying object! Stacktrace follows::") log.msg(string.join(self.stack, '\n')) raise
def unthrottleWrites(self): """ Stop throttling writes on all protocols. """ self.unthrottleWritesID = None log.msg("Stopped throttling writes on %s" % self) for p in self.protocols.keys(): p.unthrottleWrites()
def runUntilCurrent(self): """Run all pending timed calls. """ if self.threadCallQueue: # Keep track of how many calls we actually make, as we're # making them, in case another call is added to the queue # while we're in this loop. count = 0 total = len(self.threadCallQueue) for (f, a, kw) in self.threadCallQueue: try: f(*a, **kw) except: log.err() count += 1 if count == total: break del self.threadCallQueue[:count] if self.threadCallQueue: self.wakeUp() # insert new delayed calls now self._insertNewDelayedCalls() now = self.seconds() while self._pendingTimedCalls and (self._pendingTimedCalls[0].time <= now): call = heappop(self._pendingTimedCalls) if call.cancelled: self._cancellations -= 1 continue if call.delayed_time > 0: call.activate_delay() heappush(self._pendingTimedCalls, call) continue try: call.called = 1 call.func(*call.args, **call.kw) except: log.deferr() if hasattr(call, "creator"): e = "\n" e += " C: previous exception occurred in " + "a DelayedCall created here:\n" e += " C:" e += "".join(call.creator).rstrip().replace("\n", "\n C:") e += "\n" log.msg(e) if self._cancellations > 50 and self._cancellations > len(self._pendingTimedCalls) >> 1: self._cancellations = 0 self._pendingTimedCalls = [x for x in self._pendingTimedCalls if not x.cancelled] heapify(self._pendingTimedCalls) if self._justStopped: self._justStopped = False self.fireSystemEvent("shutdown")
def __getattr__(self, key): try: return getattr(self.mainMod, key) except AttributeError: if self.initRun: raise else: log.msg("Warning! Loading from __main__: %s" % key) return styles.Ephemeral()
def logPacketData(data): lines = len(data) / 16 if lines * 16 != len(data): lines = lines + 1 for i in range(lines): d = tuple(data[16 * i:16 * i + 16]) hex = map(lambda x: "%02X" % ord(x), d) text = map(lambda x: (len(repr(x)) > 3 and '.') or x, d) log.msg(' '.join(hex) + ' ' * 3 * (16 - len(d)) + ''.join(text)) log.msg('')
def logPacketData(data): lines = len(data)/16 if lines*16 != len(data): lines=lines+1 for i in range(lines): d = tuple(data[16*i:16*i+16]) hex = map(lambda x: "%02X"%ord(x),d) text = map(lambda x: (len(repr(x))>3 and '.') or x, d) log.msg(' '.join(hex)+ ' '*3*(16-len(d)) +''.join(text)) log.msg('')
def lineReceived(self, line): if not self.queries: log.msg("Unexpected server response: %r" % (line, )) else: d, _, _ = self.queries.pop(0) self.parseResponse(d, line) if self.queries: self.sendLine('%d, %d' % (self.queries[0][1], self.queries[0][2]))
def __getattr__(self, name): """ A getattr method to cause a class to be refreshed. """ if name == '__del__': raise AttributeError("Without this, Python segfaults.") updateInstance(self) log.msg("(rebuilding stale %s instance (%s))" % (reflect.qual(self.__class__), name)) result = getattr(self, name) return result
def doStart(self): """Make sure startProtocol is called. This will be called by makeConnection(), users should not call it. """ if not self.numPorts: if self.noisy: log.msg("Starting protocol %s" % self) self.startProtocol() self.numPorts = self.numPorts + 1
def doStart(self): """Make sure startFactory is called. Users should not call this function themselves! """ if not self.numPorts: if self.noisy: log.msg("Starting factory %r" % self) self.startFactory() self.numPorts = self.numPorts + 1
def oscar_Cookie(self, data): snac = readSNAC(data[1]) if self.icq: i = snac[5].find("\000") snac[5] = snac[5][i:] tlvs = readTLVs(snac[5]) if tlvs.has_key(6): self.cookie = tlvs[6] server, port = string.split(tlvs[5], ":") d = self.connectToBOS(server, int(port)) d.addErrback( lambda x: log.msg("Connection Failed! Reason: %s" % x)) if self.deferred: d.chainDeferred(self.deferred) self.disconnect() elif tlvs.has_key(8): errorcode = tlvs[8] errorurl = tlvs[4] if errorcode == '\000\030': error = "You are attempting to sign on again too soon. Please try again later." elif errorcode == '\000\005': error = "Invalid Username or Password." else: error = repr(errorcode) self.error(error, errorurl) else: log.msg('hmm, weird tlvs for %s cookie packet' % str(self)) log.msg(tlvs) log.msg('snac') log.msg(str(snac)) return "None"
def oscar_Cookie(self,data): snac=readSNAC(data[1]) if self.icq: i=snac[5].find("\000") snac[5]=snac[5][i:] tlvs=readTLVs(snac[5]) if tlvs.has_key(6): self.cookie=tlvs[6] server,port=string.split(tlvs[5],":") d = self.connectToBOS(server, int(port)) d.addErrback(lambda x: log.msg("Connection Failed! Reason: %s" % x)) if self.deferred: d.chainDeferred(self.deferred) self.disconnect() elif tlvs.has_key(8): errorcode=tlvs[8] errorurl=tlvs[4] if errorcode=='\000\030': error="You are attempting to sign on again too soon. Please try again later." elif errorcode=='\000\005': error="Invalid Username or Password." else: error=repr(errorcode) self.error(error,errorurl) else: log.msg('hmm, weird tlvs for %s cookie packet' % str(self)) log.msg(tlvs) log.msg('snac') log.msg(str(snac)) return "None"
def versionUpgrade(self): """(internal) Do a version upgrade. """ bases = _aybabtu(self.__class__) # put the bases in order so superclasses' persistenceVersion methods # will be called first. bases.reverse() bases.append(self.__class__) # don't forget me!! # first let's look for old-skool versioned's if self.__dict__.has_key("persistenceVersion"): # Hacky heuristic: if more than one class subclasses Versioned, # we'll assume that the higher version number wins for the older # class, so we'll consider the attribute the version of the older # class. There are obviously possibly times when this will # eventually be an incorrect assumption, but hopefully old-school # persistenceVersion stuff won't make it that far into multiple # classes inheriting from Versioned. pver = self.__dict__['persistenceVersion'] del self.__dict__['persistenceVersion'] highestVersion = 0 highestBase = None for base in bases: if not base.__dict__.has_key('persistenceVersion'): continue if base.persistenceVersion > highestVersion: highestBase = base highestVersion = base.persistenceVersion if highestBase: self.__dict__['%s.persistenceVersion' % reflect.qual(highestBase)] = pver for base in bases: # ugly hack, but it's what the user expects, really if (Versioned not in base.__bases__ and not base.__dict__.has_key('persistenceVersion')): continue currentVers = base.persistenceVersion pverName = '%s.persistenceVersion' % reflect.qual(base) persistVers = (self.__dict__.get(pverName) or 0) if persistVers: del self.__dict__[pverName] assert persistVers <= currentVers, "Sorry, can't go backwards in time." while persistVers < currentVers: persistVers = persistVers + 1 method = base.__dict__.get('upgradeToVersion%s' % persistVers, None) if method: log.msg("Upgrading %s (of %s @ %s) to version %s" % (reflect.qual(base), reflect.qual( self.__class__), id(self), persistVers)) method(self) else: log.msg('Warning: cannot upgrade %s to version %s' % (base, persistVers))
def unjelly(self, ao): try: l = [None] self.unjellyInto(l, 0, ao) for callable, v in self.afterUnjelly: callable(v[0]) return l[0] except: log.msg("Error jellying object! Stacktrace follows::") log.msg(string.join(map(repr, self.stack), "\n")) raise
def doStop(self): """Make sure stopProtocol is called. This will be called by the port, users should not call it. """ assert self.numPorts > 0 self.numPorts = self.numPorts - 1 self.transport = None if not self.numPorts: if self.noisy: log.msg("Stopping protocol %s" % self) self.stopProtocol()
def sendMessage(self, destURL, message): """Send a message. @param destURL: C{URL}. This should be a *physical* URL, not a logical one. @param message: The message to send. """ if destURL.transport not in ("udp", None): raise RuntimeError, "only UDP currently supported" if self.debug: log.msg("Sending %r to %r" % (message.toString(), destURL)) self.transport.write(message.toString(), (destURL.host, destURL.port or self.PORT))
def datagramReceived(self, data, addr): self.parser.dataReceived(data) self.parser.dataDone() for m in self.messages: self._fixupNAT(m, addr) if self.debug: log.msg("Received %r from %r" % (m.toString(), addr)) if isinstance(m, Request): self.handle_request(m, addr) else: self.handle_response(m, addr) self.messages[:] = []
def run(self, installSignalHandlers=True): """ Start the reactor. """ self._postQueue = Queue.Queue() if not hasattr(self, "wxapp"): log.msg("registerWxApp() was not called on reactor, " "registering my own wxApp instance.") self.registerWxApp(wxPySimpleApp()) # start select() thread: self.interleave(self._runInMainThread, installSignalHandlers=installSignalHandlers) if installSignalHandlers: self.callLater(0, self._installSignalHandlersAgain) # add cleanup events: self.addSystemEventTrigger("after", "shutdown", self._stopWx) self.addSystemEventTrigger("after", "shutdown", lambda: self._postQueue.put(None)) # On Mac OS X, work around wx bug by starting timer to ensure # wxCallAfter calls are always processed. We don't wake up as # often as we could since that uses too much CPU. if runtime.platform.isMacOSX(): t = ProcessEventsTimer(self.wxapp) t.Start(2) # wake up every 2ms self.wxapp.MainLoop() wxapp = self.wxapp del self.wxapp if not self._stopping: # wx event loop exited without reactor.stop() being # called. At this point events from select() thread will # be added to _postQueue, but some may still be waiting # unprocessed in wx, thus the ProcessPendingEvents() # below. self.stop() wxapp.ProcessPendingEvents() # deal with any queued wxCallAfters while 1: try: f = self._postQueue.get(timeout=0.01) except Queue.Empty: continue else: if f is None: break try: f() except: log.err()
def dataReceived(self,data): # if isinstance(self, ChatService): # logPacketData(data) self.buf=self.buf+data flap=self.readFlap() while flap: func=getattr(self,"oscar_%s"%self.state,None) if not func: log.msg("no func for state: %s" % self.state) state=func(flap) if state: self.state=state flap=self.readFlap()
def __del__(self): """ Print tracebacks and die. If the *last* (and I do mean *last*) callback leaves me in an error state, print a traceback (if said errback is a L{Failure}). """ if self.failResult is not None: log.msg("Unhandled error in Deferred:", isError=True) debugInfo = self._getDebugTracebacks() if debugInfo != '': log.msg("(debug: " + debugInfo + ")", isError=True) log.err(self.failResult)
def buildProtocol(self, addr): if self.connectionCount == 0: if self.readLimit is not None: self.checkReadBandwidth() if self.writeLimit is not None: self.checkWriteBandwidth() if self.connectionCount < self.maxConnectionCount: self.connectionCount += 1 return WrappingFactory.buildProtocol(self, addr) else: log.msg("Max connection count reached!") return None
def dataReceived(self, data): # if isinstance(self, ChatService): # logPacketData(data) self.buf = self.buf + data flap = self.readFlap() while flap: func = getattr(self, "oscar_%s" % self.state, None) if not func: log.msg("no func for state: %s" % self.state) state = func(flap) if state: self.state = state flap = self.readFlap()