From c73aab039e232e7b57ad7d8518c052ad5654d8bd Mon Sep 17 00:00:00 2001
From: Birte Kristina Friesel <derf@finalrewind.org>
Date: Mon, 2 Oct 2023 04:15:59 +0200
Subject: move signal-unsafe functions out of signal handlers

A signal interrupts the blocking function calls in the main iteration, so
there is really no need to do (unsafe) heavy lifting in the signal handler.

Closes #705
---
 src/main.c    | 34 ++++++++++++++++++++++++++++++++++
 src/signals.c | 22 ++--------------------
 src/signals.h |  1 +
 3 files changed, 37 insertions(+), 20 deletions(-)

diff --git a/src/main.c b/src/main.c
index 6f52778..78ee616 100644
--- a/src/main.c
+++ b/src/main.c
@@ -107,6 +107,28 @@ int main(int argc, char **argv)
 	return(sig_exit);
 }
 
+static void feh_process_signal(void)
+{
+	winwidget winwid = winwidget_get_first_window_of_type(WIN_TYPE_SLIDESHOW);
+	int i;
+	int signo = sig_received;
+	sig_received = 0;
+
+	if (winwid) {
+		if (filelist_len > 1) {
+			if (signo == SIGUSR1)
+				slideshow_change_image(winwid, SLIDE_NEXT, 1);
+			else if (signo == SIGUSR2)
+				slideshow_change_image(winwid, SLIDE_PREV, 1);
+		} else {
+			feh_reload_image(winwid, 0, 0);
+		}
+	} else if (opt.multiwindow) {
+		for (i = window_num - 1; i >= 0; i--)
+			feh_reload_image(windows[i], 0, 0);
+	}
+}
+
 /* Return 0 to stop iterating, 1 if ok to continue. */
 int feh_main_iteration(int block)
 {
@@ -124,6 +146,10 @@ int feh_main_iteration(int block)
 	if (window_num == 0 || sig_exit != 0)
 		return(0);
 
+	if (sig_received) {
+		feh_process_signal();
+	}
+
 	if (first) {
 		/* Only need to set these up the first time */
 		xfd = ConnectionNumber(disp);
@@ -156,6 +182,10 @@ int feh_main_iteration(int block)
 
 		if (window_num == 0 || sig_exit != 0)
 			return(0);
+
+		if (sig_received) {
+			feh_process_signal();
+		}
 	}
 	XFlush(disp);
 
@@ -249,6 +279,10 @@ int feh_main_iteration(int block)
 	if (window_num == 0 || sig_exit != 0)
 		return(0);
 
+	if (sig_received) {
+		feh_process_signal();
+	}
+
 	return(1);
 }
 
diff --git a/src/signals.c b/src/signals.c
index dc8786f..5a64883 100644
--- a/src/signals.c
+++ b/src/signals.c
@@ -29,6 +29,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "options.h"
 
 void feh_handle_signal(int);
+volatile int sig_received = 0;
 volatile int sig_exit = 0;
 
 void setup_signal_handlers(void)
@@ -71,9 +72,6 @@ void setup_signal_handlers(void)
 
 void feh_handle_signal(int signo)
 {
-	winwidget winwid;
-	int i;
-
 	switch (signo) {
 		case SIGALRM:
 			if (childpid)
@@ -92,21 +90,5 @@ void feh_handle_signal(int signo)
 			return;
 	}
 
-	winwid = winwidget_get_first_window_of_type(WIN_TYPE_SLIDESHOW);
-
-	if (winwid) {
-		if (filelist_len > 1) {
-			if (signo == SIGUSR1)
-				slideshow_change_image(winwid, SLIDE_NEXT, 1);
-			else if (signo == SIGUSR2)
-				slideshow_change_image(winwid, SLIDE_PREV, 1);
-		} else {
-			feh_reload_image(winwid, 0, 0);
-		}
-	} else if (opt.multiwindow) {
-		for (i = window_num - 1; i >= 0; i--)
-			feh_reload_image(windows[i], 0, 0);
-	}
-
-	return;
+	sig_received = signo;
 }
diff --git a/src/signals.h b/src/signals.h
index 56e9ce6..505a071 100644
--- a/src/signals.h
+++ b/src/signals.h
@@ -28,4 +28,5 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 void setup_signal_handlers(void);
 extern volatile int sig_exit;
+extern volatile int sig_received;
 #endif
-- 
cgit v1.2.3