Threaded server

Giampaolo Rodola' gnewsg at gmail.com
Sun Jan 13 22:38:47 EST 2008


Hi,
I'm trying to run an asynchronous FTP server I wrote into a thread for
being able to run a test suite against it.
The code below is the threaded FTP server code I'm using:


--- snippet ---
class FTPd(threading.Thread):

    def __init__(self):
        self.active = False
        threading.Thread.__init__(self)

    def start(self, flag=None):
        assert not self.active
        self.flag = flag
        threading.Thread.start(self)

    def run(self):
        assert not self.active
        ftpd = ftpserver.FTPServer(address, ftp_handler)
        if self.flag:
            self.flag.set()
        self.active = True
        while self.active:
            ftpd.server_forever(timeout=1, count=1)
        ftpd.close()

    def stop(self):
        assert self.active
        self.active = False

flag = threading.Event()
ftpd = FTPd()
ftpd.start(flag)
flag.wait()  # wait for it to start
unittest.main() # run the test suite
ftpd.stop()
--- /snippet ---


Sometimes I get a strange error when all the tests have finished, the
server is stopped and Python is exiting:

----------------------------------------------------------------------
Ran 50 tests in 1.515s

OK
Exception exceptions.TypeError: "'NoneType' object is not callable" in
<bound me
thod FTPHandler.__del__ of <pyftpdlib.ftpserver.FTPHandler connected
127.0.0.1:2
249 at 0xa4b080>> ignored
Exception exceptions.TypeError: "'NoneType' object is not callable" in
<bound me
thod FTPServer.__del__ of <pyftpdlib.ftpserver.FTPServer listening
127.0.0.1:543
21 at 0x9e1a30>> ignored


I sincerely don't know why that happens but it's likely because I'm
not using threads properly.
My concern is that this could be caused by a sort of race condition
(e.g. Python tries to exit when ftpd.close call is not yet completed).

I tried to put a lock in the close() method for waiting the run()
method to be completed before returning but I didn't solve the
problem.
Another information, in case it could be useful, is that this seems to
happen with Python 2.3 only.
By using 2.4 and Python 2.5 I have no problems.

In such cases which is the right way for doing things?
Using setDaemon(True)?
Could someone point me in the right direction?
I've always used the asynchronous approach and dealing with threads is
a real pain for me.


Thanks in advance.

-- Giampaolo



More information about the Python-list mailing list