Commit Diff


commit - a693e9384f80e6e9a847bbbe4443fbdfa253e4dd
commit + bbed092f5c70b3e2b7cfb70f3a30ede124f75285
blob - d03a685f56550990d17251c2c64d53b1bed21825
blob + e45c42a57c6860a65e3e5f29e544e175c2cd33e1
--- ev.c
+++ ev.c
@@ -425,6 +425,7 @@ ev_loop(void)
 {
 	struct timespec	 elapsed, beg, end;
 	struct timeval	 tv, sub, *min;
+	struct evcb	 cb;
 	int		 n, msec;
 	size_t		 i;
 
@@ -456,9 +457,14 @@ ev_loop(void)
 		for (i = 0; i < base->ntimers && !ev_stop; /* nop */) {
 			timersub(&base->timers[i].tv, &tv, &sub);
 			if (sub.tv_sec <= 0) {
-				base->timers[i].cb.cb(-1, EV_TIMEOUT,
-				    base->timers[i].cb.udata);
+				/*
+				 * delete the timer before calling its
+				 * callback; protects from timer that
+				 * attempt to delete themselves.
+				 */
+				memcpy(&cb, &base->timers[i].cb, sizeof(cb));
 				cancel_timer(i);
+				cb.cb(-1, EV_TIMEOUT, cb.udata);
 				continue;
 			}