diff --git a/src/calibre/gui2/main.py b/src/calibre/gui2/main.py index f88238d44f..6956f14204 100644 --- a/src/calibre/gui2/main.py +++ b/src/calibre/gui2/main.py @@ -365,7 +365,7 @@ def cant_start(msg=_('If you are sure it is not running')+', ', else: where += _('lower right region of the screen.') if what is None: - if iswindows: + if iswindows or islinux: what = _('try rebooting your computer.') else: what = _('try deleting the file')+': '+ gui_socket_address() @@ -436,7 +436,7 @@ def main(args=sys.argv): try: listener = Listener(address=gui_socket_address()) except socket.error: - if iswindows: + if iswindows or islinux: cant_start() if os.path.exists(gui_socket_address()): os.remove(gui_socket_address()) diff --git a/src/calibre/utils/ipc/__init__.py b/src/calibre/utils/ipc/__init__.py index 54c10b5058..9735478a40 100644 --- a/src/calibre/utils/ipc/__init__.py +++ b/src/calibre/utils/ipc/__init__.py @@ -9,7 +9,7 @@ __docformat__ = 'restructuredtext en' import os, errno from threading import Thread -from calibre.constants import iswindows, get_windows_username +from calibre.constants import iswindows, get_windows_username, islinux ADDRESS = None @@ -37,12 +37,15 @@ def gui_socket_address(): if user: ADDRESS += '-' + user[:100] + 'x' else: - from tempfile import gettempdir - tmp = gettempdir() user = os.environ.get('USER', '') if not user: user = os.path.basename(os.path.expanduser('~')) - ADDRESS = os.path.join(tmp, user+'-calibre-gui.socket') + if islinux: + ADDRESS = (u'\0%s-calibre-gui.socket' % user).encode('ascii') + else: + from tempfile import gettempdir + tmp = gettempdir() + ADDRESS = os.path.join(tmp, user+'-calibre-gui.socket') return ADDRESS class RC(Thread): diff --git a/src/calibre/utils/ipc/server.py b/src/calibre/utils/ipc/server.py index fbbe411f84..20a2b0ed64 100644 --- a/src/calibre/utils/ipc/server.py +++ b/src/calibre/utils/ipc/server.py @@ -6,7 +6,7 @@ __license__ = 'GPL v3' __copyright__ = '2009, Kovid Goyal ' __docformat__ = 'restructuredtext en' -import sys, os, cPickle, time, tempfile +import sys, os, cPickle, time, tempfile, errno from math import ceil from threading import Thread, RLock from Queue import Queue, Empty @@ -18,7 +18,7 @@ from calibre.utils.ipc import eintr_retry_call from calibre.utils.ipc.launch import Worker from calibre.utils.ipc.worker import PARALLEL_FUNCS from calibre import detect_ncpus as cpu_count -from calibre.constants import iswindows, DEBUG +from calibre.constants import iswindows, DEBUG, islinux from calibre.ptempfile import base_dir _counter = 0 @@ -84,6 +84,22 @@ class ConnectedWorker(Thread): class CriticalError(Exception): pass +_name_counter = 0 + +def create_linux_listener(authkey, backlog=4): + # Use abstract named sockets on linux to avoid creating unnecessary temp files + global _name_counter + prefix = u'\0calibre-ipc-listener-%d-%%d' % os.getpid() + while True: + _name_counter += 1 + address = (prefix % _name_counter).encode('ascii') + try: + return address, Listener(address=address, authkey=authkey, backlog=backlog) + except EnvironmentError as err: + if err.errno == errno.EADDRINUSE: + continue + raise + class Server(Thread): def __init__(self, notify_on_job_done=lambda x: x, pool_size=None, @@ -99,11 +115,13 @@ class Server(Thread): self.pool_size = limit if pool_size is None else pool_size self.notify_on_job_done = notify_on_job_done self.auth_key = os.urandom(32) - self.address = arbitrary_address('AF_PIPE' if iswindows else 'AF_UNIX') - if iswindows and self.address[1] == ':': - self.address = self.address[2:] - self.listener = Listener(address=self.address, - authkey=self.auth_key, backlog=4) + if islinux: + self.address, self.listener = create_linux_listener(self.auth_key, backlog=4) + else: + self.address = arbitrary_address('AF_PIPE' if iswindows else 'AF_UNIX') + if iswindows and self.address[1] == ':': + self.address = self.address[2:] + self.listener = Listener(address=self.address, authkey=self.auth_key, backlog=4) self.add_jobs_queue, self.changed_jobs_queue = Queue(), Queue() self.kill_queue = Queue() self.waiting_jobs = [] @@ -162,7 +180,6 @@ class Server(Thread): w = self.launch_worker(gui=gui, redirect_output=redirect_output) w.start_job(job) - def run(self): while True: try: @@ -280,8 +297,6 @@ class Server(Thread): pos += delta return ans - - def close(self): try: self.add_jobs_queue.put(None)