diff --git a/src/calibre/gui2/ui.py b/src/calibre/gui2/ui.py index cc2975e7a7..4667431d96 100644 --- a/src/calibre/gui2/ui.py +++ b/src/calibre/gui2/ui.py @@ -579,6 +579,9 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, # {{{ except KeyboardInterrupt: pass time.sleep(2) + if mb is not None: + mb.flush() + QApplication.processEvents() self.hide_windows() return True diff --git a/src/calibre/library/caches.py b/src/calibre/library/caches.py index 0c3904532e..e18f514239 100644 --- a/src/calibre/library/caches.py +++ b/src/calibre/library/caches.py @@ -40,12 +40,14 @@ class MetadataBackup(Thread): # {{{ self.get_metadata_for_dump = FunctionDispatcher(db.get_metadata_for_dump) self.clear_dirtied = FunctionDispatcher(db.clear_dirtied) self.set_dirtied = FunctionDispatcher(db.dirtied) + self.in_limbo = None def stop(self): self.keep_running = False def run(self): while self.keep_running: + self.in_limbo = None try: time.sleep(0.5) # Limit to two per second id_ = self.db.dirtied_queue.get(True, 1.45) @@ -72,6 +74,7 @@ class MetadataBackup(Thread): # {{{ if mi is None: continue + self.in_limbo = id_ # Give the GUI thread a chance to do something. Python threads don't # have priorities, so this thread would naturally keep the processor @@ -99,6 +102,14 @@ class MetadataBackup(Thread): # {{{ 'again, giving up') continue + def flush(self): + 'Used during shutdown to ensure that a dirtied book is not missed' + if self.in_limbo is not None: + try: + self.set_dirtied([self.in_limbo]) + except: + traceback.print_exc() + def write(self, path, raw): with open(path, 'wb') as f: f.write(raw)