Date: Wed, 9 Feb 2005 11:46:36 -0800 From: Payment Online <snacktime2@gmail.com> To: FreeBSD Questions <freebsd-questions@freebsd.org> Subject: Thread/Signal problem with threaded python app on 5.3 Message-ID: <21fe04a805020911461b293cf8@mail.gmail.com>
next in thread | raw e-mail | index | archive | help
I have a client/server application written in python/twisted and on freebsd 5.3 the server won't shut down correctly with SIGINT or SIGTERM, instead requiring a SIGKILL. The twist is that if I send the server a signal, it will shut down on the next request from the client. In that case it shuts down immediately when the client connects and closes the connection before it's fully established. The server will also shut down correctly if it hasn't yet accepted any connections from a client. This is on freebsd 5.3-release-p2 with python 2.4 and twisted both installed from ports. I am using the default libpthreads and python is compiled to use threads. I tested it on Debian (sarge) and the signals work fine. It's like there is some sort of event loop that isn't working correctly. Freebsd is obviously getting the signal, but it doesn't act on it until another request comes in from the client. Also for those that aren't familiar with twisted this application opens a thread for every request. Below is some simple code that will run if you have twisted. Sorry I don't have a more simple test case, but I'm fairly new to python (and threads), and writing something from scratch would take a while. Server (save server to test.tac and start with twistd -noy test.tac) --------------------------------------------------- from twisted.application import service,internet from twisted.internet.protocol import Protocol, Factory from twisted.internet import defer, reactor from twisted.python import threadable from twisted.internet import threads from twisted.python import log threadable.init(1) import sys class ProcessTransaction: def Do(self,data): return 'Done' ### Protocol Implementation class OT(Protocol): def dataReceived(self, data): """As soon as any data is received, process it in a thread.""" reactor.callLater(0, self.Start,data) def PrintData(self,data): self.transport.write("%s\r\n" % data) self.transport.loseConnection() def Start(self,data): c = ProcessTransaction() d = threads.deferToThread(c.Do,data) d.addCallback(self.PrintData) d.addErrback(log.err) application = service.Application("otransact") OTService = service.IServiceCollection(application) OTfactory = Factory() OTfactory.protocol = OT OTServer = internet.TCPServer(8000, OTfactory) OTServer.setServiceParent(OTService) Client (just run as python test.py) -------------------------------------------------------------- import sys import time from twisted.internet.protocol import ClientFactory from twisted.protocols.basic import LineReceiver from twisted.internet import reactor class EchoClient(LineReceiver): end="GoodBye" def connectionMade(self): self.sendLine("Testing") def connectionLost(self, reason): print 'connection lost (protocol)' reactor.stop() def lineReceived(self, line): print "receive:", line self.transport.loseConnection() class EchoClientFactory(ClientFactory): protocol = EchoClient def clientConnectionFailed(self, connector, reason): print 'connection failed:', reason.getErrorMessage() reactor.stop() def clientConnectionLost(self, connector, reason): print 'connection lost:', reason.getErrorMessage() reactor.stop() def main(): factory = EchoClientFactory() reactor.connectTCP('localhost', 8000, factory) reactor.run() if __name__ == '__main__': main()
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?21fe04a805020911461b293cf8>