From 4fc3fbec33557c4fc3ee9b700a9a0a7700f04948 Mon Sep 17 00:00:00 2001 From: Paul Fisher Date: Mon, 11 Jan 2016 11:26:30 -0800 Subject: [PATCH] lock domain socket and remove on last arbiter exit --- gunicorn/sock.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/gunicorn/sock.py b/gunicorn/sock.py index 4de972854..fdb5ae752 100644 --- a/gunicorn/sock.py +++ b/gunicorn/sock.py @@ -4,6 +4,7 @@ # See the NOTICE for more information. import errno +import fcntl import os import socket import stat @@ -105,6 +106,8 @@ def __init__(self, addr, conf, log, fd=None): raise ValueError("%r is not a socket" % addr) self.parent = os.getpid() super(UnixSocket, self).__init__(addr, conf, log, fd=fd) + # each arbiter grabs a shared lock on the unix socket. + fcntl.lockf(self.sock, fcntl.LOCK_SH | fcntl.LOCK_NB) def __str__(self): return "unix:%s" % self.cfg_addr @@ -117,9 +120,17 @@ def bind(self, sock): def close(self): - super(UnixSocket, self).close() if self.parent == os.getpid(): - os.unlink(self.cfg_addr) + # attempt to acquire an exclusive lock on the unix socket. + # if we're the only arbiter running, the lock will succeed, and + # we can safely rm the socket. + try: + fcntl.lockf(self.sock, fcntl.LOCK_EX | fcntl.LOCK_NB) + except: + pass + else: + os.unlink(self.cfg_addr) + super(UnixSocket, self).close() def _sock_type(addr):