Blame 0035-macOS-Fix-a-regression-that-could-cause-a-crash-on-e.patch

5f720ea
From 012ab78ac30ed61070500b35082cef3c220e19e3 Mon Sep 17 00:00:00 2001
5f720ea
From: Kovid Goyal <kovid@kovidgoyal.net>
5f720ea
Date: Tue, 6 Aug 2019 11:46:15 +0530
5f720ea
Subject: [PATCH 35/71] macOS: Fix a regression that could cause a crash on
5f720ea
 exit if any books were deleted while calibre was running. Fixes #1839044
5f720ea
 [calibre crash when deleting
5f720ea
 ebook](https://bugs.launchpad.net/calibre/+bug/1839044)
5f720ea
5f720ea
---
5f720ea
 src/calibre/db/delete_service.py  |  3 +++
5f720ea
 src/calibre/utils/cocoa.m         | 29 ++++++++++++++---------------
5f720ea
 src/calibre/utils/cocoa_wrapper.c |  8 ++++++++
5f720ea
 3 files changed, 25 insertions(+), 15 deletions(-)
5f720ea
5f720ea
diff --git a/src/calibre/db/delete_service.py b/src/calibre/db/delete_service.py
5f720ea
index 15d48358d1..4a10e8ca59 100644
5f720ea
--- a/src/calibre/db/delete_service.py
5f720ea
+++ b/src/calibre/db/delete_service.py
5f720ea
@@ -8,6 +8,7 @@ __copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
5f720ea
 import os, tempfile, shutil, errno, time, atexit
5f720ea
 from threading import Thread
5f720ea
 
5f720ea
+from calibre.constants import isosx, plugins
5f720ea
 from calibre.ptempfile import remove_dir
5f720ea
 from calibre.utils.filenames import remove_dir_if_empty
5f720ea
 from calibre.utils.recycle_bin import delete_tree, delete_file
5f720ea
@@ -33,6 +34,8 @@ class DeleteService(Thread):
5f720ea
     def __init__(self):
5f720ea
         Thread.__init__(self)
5f720ea
         self.requests = Queue()
5f720ea
+        if isosx:
5f720ea
+            plugins['cocoa'][0].enable_cocoa_multithreading()
5f720ea
 
5f720ea
     def shutdown(self, timeout=20):
5f720ea
         self.requests.put(None)
5f720ea
diff --git a/src/calibre/utils/cocoa.m b/src/calibre/utils/cocoa.m
5f720ea
index 7b7f098ef8..ed228bed3c 100644
5f720ea
--- a/src/calibre/utils/cocoa.m
5f720ea
+++ b/src/calibre/utils/cocoa.m
5f720ea
@@ -9,18 +9,21 @@
5f720ea
 #include <Cocoa/Cocoa.h>
5f720ea
 #include <string.h>
5f720ea
 
5f720ea
+void
5f720ea
+activate_cocoa_multithreading(void) {
5f720ea
+	if (![NSThread isMultiThreaded]) [[NSThread new] start];
5f720ea
+}
5f720ea
+
5f720ea
 const char*
5f720ea
 cocoa_send2trash(const char *utf8_path) {
5f720ea
-	NSString *path = [[NSString alloc] initWithUTF8String:utf8_path];
5f720ea
-	NSURL *url = [NSURL fileURLWithPath:path];
5f720ea
+	@autoreleasepool {
5f720ea
 	const char *ret = NULL;
5f720ea
 	NSError* ns_error = nil;
5f720ea
-	if (![[NSFileManager defaultManager] trashItemAtURL:url resultingItemURL:nil error:&ns_error]) {
5f720ea
+	if (![[NSFileManager defaultManager] trashItemAtURL:[NSURL fileURLWithPath:@(utf8_path)] resultingItemURL:nil error:&ns_error]) {
5f720ea
 		ret = strdup([[ns_error localizedDescription] UTF8String]);
5f720ea
 	}
5f720ea
-	[url release];
5f720ea
-	[path release];
5f720ea
 	return ret;
5f720ea
+	}
5f720ea
 }
5f720ea
 
5f720ea
 
5f720ea
@@ -32,35 +35,31 @@ extern void macos_notification_callback(const char*);
5f720ea
 
5f720ea
 void
5f720ea
 cocoa_send_notification(const char *identifier, const char *title, const char *subtitle, const char *informativeText, const char* path_to_image) {
5f720ea
+	@autoreleasepool {
5f720ea
     NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter];
5f720ea
     if (!center) {return;}
5f720ea
     if (!center.delegate) center.delegate = [[NotificationDelegate alloc] init];
5f720ea
     NSUserNotification *n = [NSUserNotification new];
5f720ea
     NSImage *img = nil;
5f720ea
     if (path_to_image) {
5f720ea
-        NSString *p = [NSString stringWithUTF8String:path_to_image];
5f720ea
-        NSURL *url = [NSURL fileURLWithPath:p];
5f720ea
-        img = [[NSImage alloc] initWithContentsOfURL:url];
5f720ea
-        [url release]; [p release];
5f720ea
+		img = [[NSImage alloc] initWithContentsOfURL:[NSURL fileURLWithPath:@(path_to_image)]];
5f720ea
         if (img) {
5f720ea
             [n setValue:img forKey:@"_identityImage"];
5f720ea
             [n setValue:@(false) forKey:@"_identityImageHasBorder"];
5f720ea
         }
5f720ea
-        [img release];
5f720ea
+		[img release];
5f720ea
     }
5f720ea
 #define SET(x) { \
5f720ea
     if (x) { \
5f720ea
-        NSString *t = [NSString stringWithUTF8String:x]; \
5f720ea
-        n.x = t; \
5f720ea
-        [t release]; \
5f720ea
+        n.x = @(x); \
5f720ea
     }}
5f720ea
     SET(title); SET(subtitle); SET(informativeText);
5f720ea
 #undef SET
5f720ea
     if (identifier) {
5f720ea
-        n.userInfo = @{@"user_id": [NSString stringWithUTF8String:identifier]};
5f720ea
+        n.userInfo = @{@"user_id": @(identifier)};
5f720ea
     }
5f720ea
     [center deliverNotification:n];
5f720ea
-
5f720ea
+	}
5f720ea
 }
5f720ea
 
5f720ea
 @implementation NotificationDelegate
5f720ea
diff --git a/src/calibre/utils/cocoa_wrapper.c b/src/calibre/utils/cocoa_wrapper.c
5f720ea
index b16242a902..5f68e313e1 100644
5f720ea
--- a/src/calibre/utils/cocoa_wrapper.c
5f720ea
+++ b/src/calibre/utils/cocoa_wrapper.c
5f720ea
@@ -10,6 +10,7 @@
5f720ea
 extern double cocoa_cursor_blink_time(void);
5f720ea
 extern void cocoa_send_notification(const char *identitifer, const char *title, const char *subtitle, const char *informativeText, const char* path_to_image);
5f720ea
 extern const char* cocoa_send2trash(const char *utf8_path);
5f720ea
+extern void activate_cocoa_multithreading(void);
5f720ea
 
5f720ea
 static PyObject *notification_activated_callback = NULL;
5f720ea
 
5f720ea
@@ -63,8 +64,15 @@ send2trash(PyObject *self, PyObject *args) {
5f720ea
 	Py_RETURN_NONE;
5f720ea
 }
5f720ea
 
5f720ea
+static PyObject*
5f720ea
+enable_cocoa_multithreading(PyObject *self, PyObject *args) {
5f720ea
+	activate_cocoa_multithreading();
5f720ea
+	Py_RETURN_NONE;
5f720ea
+}
5f720ea
+
5f720ea
 static PyMethodDef module_methods[] = {
5f720ea
     {"cursor_blink_time", (PyCFunction)cursor_blink_time, METH_NOARGS, ""},
5f720ea
+    {"enable_cocoa_multithreading", (PyCFunction)enable_cocoa_multithreading, METH_NOARGS, ""},
5f720ea
     {"set_notification_activated_callback", (PyCFunction)set_notification_activated_callback, METH_O, ""},
5f720ea
     {"send_notification", (PyCFunction)send_notification, METH_VARARGS, ""},
5f720ea
     {"send2trash", (PyCFunction)send2trash, METH_VARARGS, ""},