From 5305b6a3a858e035cafc883f57713a495509c4bd Mon Sep 17 00:00:00 2001 From: Bas Stottelaar Date: Sat, 20 Sep 2014 13:03:49 +0200 Subject: [PATCH] Check for permission errors in queues and defer queue initialization until use. Fixes #1897. --- headphones/logger.py | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/headphones/logger.py b/headphones/logger.py index 3c384643..9a6bc6ec 100644 --- a/headphones/logger.py +++ b/headphones/logger.py @@ -24,6 +24,7 @@ import headphones import threading import traceback import logging +import errno import sys import os @@ -35,8 +36,8 @@ MAX_FILES = 5 # Headphones logger logger = logging.getLogger("headphones") -# Global queue of multiprocessing logging -queue = multiprocessing.Queue() +# Global queue for multiprocessing logging +queue = None class LogListHandler(logging.Handler): """ @@ -56,13 +57,33 @@ def listener(): To be used in a with statement in the main process, for multiprocessing. """ - queue_listener = QueueListener(queue, *logger.handlers) + global queue - try: - queue_listener.start() + # Initialize queue if not already done + if queue is None: + try: + queue = multiprocessing.Queue() + except IOError as e: + queue = False + + # Some machines don't have access to /dev/shm. See + # http://stackoverflow.com/questions/2009278 for more information. + if e.errno == errno.EACCES: + logger.warning("Multiprocess logging disabled, because " + "current user cannot map shared memory. You won't see any" \ + "logging generated by the worker processed.") + + # Multiprocess logging may be disabled. + if not queue: yield - finally: - queue_listener.stop() + else: + queue_listener = QueueListener(queue, *logger.handlers) + + try: + queue_listener.start() + yield + finally: + queue_listener.stop() def initMultiprocessing(): """ @@ -71,6 +92,11 @@ def initMultiprocessing(): completely. """ + # Multiprocess logging may be disabled. + if not queue: + return + + # Remove all handlers and add the Queue handler as the only one. for handler in logger.handlers[:]: logger.removeHandler(handler)