From 3a1c09a0923565d34fbd7cc97a4351cce7dfc388 Mon Sep 17 00:00:00 2001 From: MrS0m30n3 Date: Tue, 30 Jun 2015 01:58:19 +0300 Subject: [PATCH] Add synchronization lock to the log manager --- youtube_dl_gui/downloaders.py | 14 ++++++------- youtube_dl_gui/downloadmanager.py | 35 +++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/youtube_dl_gui/downloaders.py b/youtube_dl_gui/downloaders.py index e7fb11f..40483e0 100644 --- a/youtube_dl_gui/downloaders.py +++ b/youtube_dl_gui/downloaders.py @@ -34,8 +34,8 @@ class YoutubeDLDownloader(object): data_hook (function): Optional callback function to retrieve download process data. - log_manager (logmanager.LogManager): Object responsible for writing - errors to the log. + log_data (function): Optional callback function to write data to + the log file. Note: For available data keys check self._data under __init__(). @@ -61,10 +61,10 @@ class YoutubeDLDownloader(object): FILESIZE_ABORT = 4 WARNING = 5 - def __init__(self, youtubedl_path, data_hook=None, log_manager=None): + def __init__(self, youtubedl_path, data_hook=None, log_data=None): self.youtubedl_path = youtubedl_path - self.log_manager = log_manager self.data_hook = data_hook + self.log_data = log_data self._return_code = 0 self._proc = None @@ -200,9 +200,9 @@ class YoutubeDLDownloader(object): self._data[key] = data[key] def _log(self, data): - """Log data using log_manager. """ - if self.log_manager is not None: - self.log_manager.log(data) + """Log data using the callback function. """ + if self.log_data is not None: + self.log_data(data) def _hook_data(self): """Pass self._data back to the data_hook. """ diff --git a/youtube_dl_gui/downloadmanager.py b/youtube_dl_gui/downloadmanager.py index f7bb881..5e7d9a8 100644 --- a/youtube_dl_gui/downloadmanager.py +++ b/youtube_dl_gui/downloadmanager.py @@ -23,7 +23,11 @@ from __future__ import unicode_literals import time import os.path -from threading import Thread + +from threading import ( + Thread, + Lock +) from wx import CallAfter from wx.lib.pubsub import setuparg1 @@ -72,7 +76,9 @@ class DownloadManager(Thread): self._successful = 0 self._running = True - wparams = (opt_manager, self._youtubedl_path(), log_manager) + # Init the custom workers thread pool + log_lock = None if log_manager is None else Lock() + wparams = (opt_manager, self._youtubedl_path(), log_manager, log_lock) self._workers = [Worker(*wparams) for i in xrange(opt_manager.options['workers_number'])] self.start() @@ -210,15 +216,21 @@ class Worker(Thread): log_manager (logmanager.LogManager): Check DownloadManager description. + log_lock (threading.Lock): Synchronization lock for the log_manager. + If the log_manager is set (not None) then the caller has to make + sure that the log_lock is also set. + """ WAIT_TIME = 0.1 - def __init__(self, opt_manager, youtubedl, log_manager=None): + def __init__(self, opt_manager, youtubedl, log_manager=None, log_lock=None): super(Worker, self).__init__() self.opt_manager = opt_manager + self.log_manager = log_manager + self.log_lock = log_lock - self._downloader = YoutubeDLDownloader(youtubedl, self._data_hook, log_manager) + self._downloader = YoutubeDLDownloader(youtubedl, self._data_hook, self._log_data) self._options_parser = OptionsParser() self._running = True self._url = None @@ -273,6 +285,21 @@ class Worker(Thread): """Return the number of successful downloads for current worker. """ return self._successful + def _log_data(self, data): + """Callback method for self._downloader. + + This method is used to write the given data in a synchronized way + to the log file using the self.log_manager and the self.log_lock. + + Args: + data (string): String to write to the log file. + + """ + if self.log_manager is not None: + self.log_lock.acquire() + self.log_manager.log(data) + self.log_lock.release() + def _data_hook(self, data): """Callback method to be used with the YoutubeDLDownloader object.