summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorroot <root>2007-11-25 09:24:37 +0000
committerroot <root>2007-11-25 09:24:37 +0000
commiteb49c237c48682f5087a1a7774a6c977e48a39ad (patch)
tree2367056981da61eb9a7e1f8f32020e6fd22b8fc1
parentb1fc178708ff84f921128bcdcad385e87f6f825f (diff)
stopping idle/check/prepare watchers caused data corruptionrel-1_3
-rw-r--r--ev.c33
1 files changed, 29 insertions, 4 deletions
diff --git a/ev.c b/ev.c
index 1e008e5..4cb9467 100644
--- a/ev.c
+++ b/ev.c
@@ -1076,6 +1076,8 @@ call_pending (EV_P)
if (expect_true (p->w))
{
+ assert (("non-pending watcher on pending list", p->w->pending));
+
p->w->pending = 0;
EV_CB_INVOKE (p->w, p->events);
}
@@ -1191,7 +1193,15 @@ time_update (EV_P)
{
ev_tstamp odiff = rtmn_diff;
- for (i = 4; --i; ) /* loop a few times, before making important decisions */
+ /* loop a few times, before making important decisions.
+ * on the choice of "4": one iteration isn't enough,
+ * in case we get preempted during the calls to
+ * ev_time and get_clock. a second call is almost guarenteed
+ * to succeed in that case, though. and looping a few more times
+ * doesn't hurt either as we only do this on time-jumps or
+ * in the unlikely event of getting preempted here.
+ */
+ for (i = 4; --i; )
{
rtmn_diff = ev_rt_now - mn_now;
@@ -1553,7 +1563,12 @@ ev_idle_stop (EV_P_ ev_idle *w)
if (expect_false (!ev_is_active (w)))
return;
- idles [((W)w)->active - 1] = idles [--idlecnt];
+ {
+ int active = ((W)w)->active;
+ idles [active - 1] = idles [--idlecnt];
+ ((W)idles [active - 1])->active = active;
+ }
+
ev_stop (EV_A_ (W)w);
}
@@ -1575,7 +1590,12 @@ ev_prepare_stop (EV_P_ ev_prepare *w)
if (expect_false (!ev_is_active (w)))
return;
- prepares [((W)w)->active - 1] = prepares [--preparecnt];
+ {
+ int active = ((W)w)->active;
+ prepares [active - 1] = prepares [--preparecnt];
+ ((W)prepares [active - 1])->active = active;
+ }
+
ev_stop (EV_A_ (W)w);
}
@@ -1597,7 +1617,12 @@ ev_check_stop (EV_P_ ev_check *w)
if (expect_false (!ev_is_active (w)))
return;
- checks [((W)w)->active - 1] = checks [--checkcnt];
+ {
+ int active = ((W)w)->active;
+ checks [active - 1] = checks [--checkcnt];
+ ((W)checks [active - 1])->active = active;
+ }
+
ev_stop (EV_A_ (W)w);
}