[patch] Re: [ZODB-Dev] ZEO server leaks FDs.

Anthony Baxter Anthony Baxter <anthony@interlink.com.au>
Wed, 17 Oct 2001 16:24:27 +1000


Ok, the problem is the pipe() FDs in ZEO/trigger.py - they're never
closed. The following patch fixes this (albeit in a fairly brutal way).
I'd be curious if there's a better way to fix this - I'm not sure I 
grok asyncore that well, and it's possible that it should be something
else's job to close the FDs.

I'll whack this in the ZEO Tracker, too.

Index: StorageServer.py
===================================================================
RCS file: /export/00/cvsroot/Zope/lib/python/ZEO/StorageServer.py,v
retrieving revision 1.3
diff -u -r1.3 StorageServer.py
--- StorageServer.py	2001/09/27 05:32:27	1.3
+++ StorageServer.py	2001/10/17 06:21:08
@@ -253,6 +253,7 @@
         self.__server.unregister_connection(self, self.__storage_id)
         self.__closed=1
         SizedMessageAsyncConnection.close(self)
+        self._pack_trigger.pipeclose()
         LOG('ZEO Server', INFO, 'Close %s' % id(self))
 
     def message_input(self, message,
Index: trigger.py
===================================================================
RCS file: /export/00/cvsroot/Zope/lib/python/ZEO/trigger.py,v
retrieving revision 1.2
diff -u -r1.2 trigger.py
--- trigger.py	2001/09/27 05:32:27	1.2
+++ trigger.py	2001/10/17 06:21:08
@@ -132,9 +132,11 @@
         def __init__ (self):
             r, w = os.pipe()
             self.trigger = w
+            self.other_trigger = r # for closing, later
             asyncore.file_dispatcher.__init__ (self, r)
             self.lock = thread.allocate_lock()
             self.thunks = []
+            self.closed = 0
 
         def __repr__ (self):
             return '<select-trigger (pipe) at %x>' % id(self)
@@ -172,6 +174,17 @@
                 self.thunks = []
             finally:
                 self.lock.release()
+
+        def pipeclose(self):
+            " pipes must be explicitly closed! "
+            self.del_channel()
+            os.close(self.trigger)
+            os.close(self.other_trigger)
+            self.closed = 1
+
+        def __del__(self):
+            if not self.closed:
+                self.pipeclose()
 
 else:
 


>>> Anthony Baxter wrote
> Using ZEO 1.0b4, Python2.1 (no cyclic GC), Solaris 2.7:
> 
> bourbon% lsof -p 13244  | grep FIFO | wc -l
>      13
> bash-2.04$ telnet bourbon 18076
> Trying 192.168.133.24...
> Connected to bourbon.lax2.ekorp.com.
> Escape character is '^]'.
> ^]
> telnet> cl
> Connection closed.
> bourbon% lsof -p 13244  | grep FIFO | wc -l
>      15
> 
> This is very, very bad.
> 
> Looking for the bug now. It's leaking pipes - e.g.
> python2.1 13244 ekitzope   20u  FIFO 0x300031e8f80      0t0 4079043 PIPE->0x3
00031e9060
> python2.1 13244 ekitzope   21u  FIFO 0x300031e9060      0t0 4079043 PIPE->0x3
00031e8f80
> After not very much of this, you run out of filedescriptors.
> 
> 
> Anthony
> 
> _______________________________________________
> For more information about ZODB, see the ZODB Wiki:
> http://www.zope.org/Wikis/ZODB/
> 
> ZODB-Dev mailing list  -  ZODB-Dev@zope.org
> http://lists.zope.org/mailman/listinfo/zodb-dev
> 

-- 
Anthony Baxter     <anthony@interlink.com.au>   
It's never too late to have a happy childhood.