[Zodb-checkins] CVS: ZODB3/zdaemon - zdrun.py:1.13
Guido van Rossum
guido@python.org
Mon, 27 Jan 2003 11:21:45 -0500
Update of /cvs-repository/ZODB3/zdaemon
In directory cvs.zope.org:/tmp/cvs-serv22196
Modified Files:
zdrun.py
Log Message:
Restructure opensocket() to implement decent race avoidance. It's not
perfect (depends on a sleep(1) in an extreme case) but I think this is
now safe enough.
Also changed the message logged by checkopen() not to end in a
newline.
=== ZODB3/zdaemon/zdrun.py 1.12 => 1.13 ===
--- ZODB3/zdaemon/zdrun.py:1.12 Mon Jan 27 10:13:17 2003
+++ ZODB3/zdaemon/zdrun.py Mon Jan 27 11:21:42 2003
@@ -244,21 +244,39 @@
commandsocket = None
def opensocket(self):
- self.checkopen()
+ sockname = self.options.sockname
+ tempname = "%s.%d" % (sockname, os.getpid())
+ self.unlink_quietly(tempname)
+ while 1:
+ sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ try:
+ sock.bind(tempname)
+ os.chmod(tempname, 0700)
+ try:
+ os.link(tempname, sockname)
+ break
+ except os.error:
+ # Lock contention, or stale socket.
+ self.checkopen()
+ # Stale socket -- delete, sleep, and try again.
+ msg = "Unlinking stale socket %s; sleep 1" % sockname
+ sys.stderr.write(msg + "\n")
+ warn(msg)
+ self.unlink_quietly(sockname)
+ sock.close()
+ time.sleep(1)
+ continue
+ finally:
+ self.unlink_quietly(tempname)
+ sock.listen(1)
+ sock.setblocking(0)
+ self.mastersocket = sock
+
+ def unlink_quietly(self, filename):
try:
- os.unlink(self.options.sockname)
+ os.unlink(filename)
except os.error:
pass
- self.mastersocket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
- oldumask = None
- try:
- oldumask = os.umask(077)
- self.mastersocket.bind(self.options.sockname)
- finally:
- if oldumask is not None:
- os.umask(oldumask)
- self.mastersocket.listen(1)
- self.mastersocket.setblocking(0)
def checkopen(self):
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
@@ -270,11 +288,11 @@
except socket.error:
pass
else:
- if not data.endswith("\n"):
- data += "\n"
+ while data.endswith("\n"):
+ data = data[:-1]
msg = ("Another zrdun is already up using socket %r:\n%s" %
(self.options.sockname, data))
- sys.stderr.write(msg)
+ sys.stderr.write(msg + "\n")
critical(msg)
sys.exit(1)