[Zodb-checkins] CVS: StandaloneZODB/ZEO - trigger.py:1.3.4.2
Jeremy Hylton
jeremy@zope.com
Tue, 15 Jan 2002 12:22:11 -0500
Update of /cvs-repository/StandaloneZODB/ZEO
In directory cvs.zope.org:/tmp/cvs-serv473
Modified Files:
Tag: Standby-branch
trigger.py
Log Message:
Fix trigger close/__del__.
The close() mechanism for an asyncore file_dispatcher is not safe to
call multiple times. It's calling os.close() on a file descriptor
(int). Guido observed that if you call close() twice, you could be in
trouble: 1) First close() call closes FD 6. 2) Another bit of code
opens a new file, getting FD 6. 3) Second close() call closes FD 6.
Waah! FD 6 is some other file.
The workaround attempt here is to define a close() method on a trigger
that only closes the file descriptors the first time.
Also, make sure that both file descriptors are closed. The previous
version only closed the read-end of the pipe.
=== StandaloneZODB/ZEO/trigger.py 1.3.4.1 => 1.3.4.2 ===
# INFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE.
-
# This module is a simplified version of the select_trigger module
# from Sam Rushing's Medusa server.
-
import asyncore
-#import asynchat
import os
import socket
@@ -60,10 +57,20 @@
asyncore.file_dispatcher.__init__ (self, r)
self.lock = thread.allocate_lock()
self.thunks = []
+ self._closed = None
- def __del__(self):
- os.close(self._fds[0])
- os.close(self._fds[1])
+ # Override the asyncore close() method, because it seems that
+ # it would only close the r file descriptor and not w. The
+ # constructor calls file_dispactcher.__init__ and passes r,
+ # which would get stored in a file_wrapper and get closed by
+ # the default close. But that would leave w open...
+
+ def close(self):
+ if self._closed is None:
+ self._closed = 1
+ self.del_channel()
+ for fd in self._fds:
+ os.close(fd)
def __repr__ (self):
return '<select-trigger (pipe) at %x>' % id(self)
@@ -78,7 +85,6 @@
pass
def pull_trigger (self, thunk=None):
- # print 'PULL_TRIGGER: ', len(self.thunks)
if thunk:
try:
self.lock.acquire()