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); | 
