Sockets for IPC on OS X should use the calibre temp dir rather than a dedicated temp dir from the multiprocessing module

This commit is contained in:
Kovid Goyal 2016-02-03 20:17:52 +05:30
parent 8c7d5e99a4
commit c1cc8332f2

View File

@ -6,7 +6,7 @@ __license__ = 'GPL v3'
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>' __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import sys, os, cPickle, time, tempfile, errno import sys, os, cPickle, time, tempfile, errno, itertools
from math import ceil from math import ceil
from threading import Thread, RLock from threading import Thread, RLock
from Queue import Queue, Empty from Queue import Queue, Empty
@ -84,7 +84,7 @@ class ConnectedWorker(Thread):
class CriticalError(Exception): class CriticalError(Exception):
pass pass
_name_counter = 0 _name_counter = itertools.count()
if islinux: if islinux:
import fcntl import fcntl
@ -121,11 +121,9 @@ if islinux:
def create_listener(authkey, backlog=4): def create_listener(authkey, backlog=4):
# Use abstract named sockets on linux to avoid creating unnecessary temp files # Use abstract named sockets on linux to avoid creating unnecessary temp files
global _name_counter
prefix = u'\0calibre-ipc-listener-%d-%%d' % os.getpid() prefix = u'\0calibre-ipc-listener-%d-%%d' % os.getpid()
while True: while True:
_name_counter += 1 address = (prefix % next(_name_counter)).encode('ascii')
address = (prefix % _name_counter).encode('ascii')
try: try:
l = LinuxListener(address=address, authkey=authkey, backlog=backlog) l = LinuxListener(address=address, authkey=authkey, backlog=backlog)
return address, l return address, l
@ -133,13 +131,42 @@ if islinux:
if err.errno == errno.EADDRINUSE: if err.errno == errno.EADDRINUSE:
continue continue
raise raise
else: elif iswindows:
def create_listener(authkey, backlog=4): def create_listener(authkey, backlog=4):
address = arbitrary_address('AF_PIPE' if iswindows else 'AF_UNIX') address = arbitrary_address('AF_PIPE')
if iswindows and address[1] == ':': if address[1] == ':':
address = address[2:] address = address[2:]
listener = Listener(address=address, authkey=authkey, backlog=backlog) return address, Listener(address=address, authkey=authkey, backlog=backlog)
return address, listener else:
def create_listener(authkey, backlog=4):
prefix = os.path.join(base_dir(), 'ipc-socket-%d-%%d' % os.getpid())
max_tries = 20
while max_tries > 0:
max_tries -= 1
address = prefix % next(_name_counter)
if not isinstance(address, bytes):
address = address.encode('utf-8') # multiprocessing needs bytes in python 2
try:
return address, Listener(address=address, authkey=authkey, backlog=backlog)
except EnvironmentError as err:
if max_tries < 1:
raise
if err.errno == errno.ENOENT:
# Some OS X machines have software that deletes temp
# files/dirs after prolonged inactivity. See for
# example, https://bugs.launchpad.net/bugs/1541356
try:
os.makedirs(os.path.dirname(prefix))
except EnvironmentError as e:
if e.errno != errno.EEXIST:
raise
continue
if err.errno != errno.EADDRINUSE:
raise
class Server(Thread): class Server(Thread):