diff options
author | Daniel Friesel <derf@finalrewind.org> | 2020-08-28 23:09:38 +0200 |
---|---|---|
committer | Daniel Friesel <derf@finalrewind.org> | 2020-08-28 23:09:38 +0200 |
commit | e43916d7d1409e4031d56ee1704456bef55eeb1d (patch) | |
tree | 839a5a27874f5cdd77104f4b3bb4da7a84aca788 | |
parent | bfea10205a9fd4cb02cd6c94d2d94baaefaed278 (diff) |
Fix segfault when closing a window in multi-window reload mode
Issue:
* start feh --multiwindow --reload 5
* close a window with "x"
* wait up to 5 seconds
* segfault
The issue was caused by the closed window's reload timer still being active
even after the winwidget was free'd.
-rw-r--r-- | src/timers.c | 33 | ||||
-rw-r--r-- | src/timers.h | 2 | ||||
-rw-r--r-- | src/winwidget.c | 4 |
3 files changed, 37 insertions, 2 deletions
diff --git a/src/timers.c b/src/timers.c index 4bdd64e..b2cdbc7 100644 --- a/src/timers.c +++ b/src/timers.c @@ -58,7 +58,37 @@ double feh_get_time(void) return((double) timev.tv_sec + (((double) timev.tv_usec) / 1000000)); } -void feh_remove_timer(char *name) +void feh_remove_timer_by_data(void *data) +{ + fehtimer ft, ptr, pptr; + + D(("removing timer for %p\n", data)); + pptr = NULL; + ptr = first_timer; + while (ptr) { + D(("Stepping through event list\n")); + ft = ptr; + if (ft->data == data) { + D(("Found it. Removing\n")); + if (pptr) + pptr->next = ft->next; + else + first_timer = ft->next; + if (ft->next) + ft->next->in += ft->in; + if (ft->name) + free(ft->name); + if (ft) + free(ft); + return; + } + pptr = ptr; + ptr = ptr->next; + } + return; +} + +static void feh_remove_timer(char *name) { fehtimer ft, ptr, pptr; @@ -88,6 +118,7 @@ void feh_remove_timer(char *name) return; } + void feh_add_timer(void (*func) (void *data), void *data, double in, char *name) { fehtimer ft, ptr, pptr; diff --git a/src/timers.h b/src/timers.h index a4243ca..e95d9b5 100644 --- a/src/timers.h +++ b/src/timers.h @@ -37,7 +37,7 @@ struct __fehtimer { void feh_handle_timer(void); double feh_get_time(void); -void feh_remove_timer(char *name); +void feh_remove_timer_by_data(void *data); void feh_add_timer(void (*func) (void *data), void *data, double in, char *name); void feh_add_unique_timer(void (*func) (void *data), void *data, double in); diff --git a/src/winwidget.c b/src/winwidget.c index 6ff90ed..bfd987d 100644 --- a/src/winwidget.c +++ b/src/winwidget.c @@ -29,6 +29,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "winwidget.h" #include "options.h" #include "events.h" +#include "timers.h" #ifdef HAVE_INOTIFY #include <sys/inotify.h> @@ -673,6 +674,9 @@ void winwidget_destroy(winwidget winwid) #ifdef HAVE_INOTIFY winwidget_inotify_remove(winwid); #endif + if (opt.reload > 0 && opt.multiwindow) { + feh_remove_timer_by_data(winwid); + } winwidget_destroy_xwin(winwid); if (winwid->name) free(winwid->name); |