]> git.llucax.com Git - software/libev.git/blobdiff - ev.c
remember wether the fd was new or not
[software/libev.git] / ev.c
diff --git a/ev.c b/ev.c
index acde504b11cc52579943aafa3605525ea6a164d3..bd833e974ae02c545466a3795b97e118c253f055 100644 (file)
--- a/ev.c
+++ b/ev.c
@@ -478,7 +478,7 @@ ev_feed_event (EV_P_ void *w, int revents)
     }
 }
 
-void inline_size
+void inline_speed
 queue_events (EV_P_ W *events, int eventcnt, int type)
 {
   int i;
@@ -559,16 +559,17 @@ fd_reify (EV_P)
 }
 
 void inline_size
-fd_change (EV_P_ int fd)
+fd_change (EV_P_ int fd, int flags)
 {
-  if (expect_false (anfds [fd].reify))
-    return;
+  unsigned char reify = anfds [fd].reify;
+  anfds [fd].reify |= flags | 1;
 
-  anfds [fd].reify = 1;
-
-  ++fdchangecnt;
-  array_needsize (int, fdchanges, fdchangemax, fdchangecnt, EMPTY2);
-  fdchanges [fdchangecnt - 1] = fd;
+  if (expect_true (!reify))
+    {
+      ++fdchangecnt;
+      array_needsize (int, fdchanges, fdchangemax, fdchangecnt, EMPTY2);
+      fdchanges [fdchangecnt - 1] = fd;
+    }
 }
 
 void inline_speed
@@ -629,7 +630,7 @@ fd_rearm_all (EV_P)
     if (anfds [fd].events)
       {
         anfds [fd].events = 0;
-        fd_change (EV_A_ fd);
+        fd_change (EV_A_ fd, EV_IOFDSET);
       }
 }
 
@@ -640,16 +641,20 @@ upheap (WT *heap, int k)
 {
   WT w = heap [k];
 
-  while (k && heap [k >> 1]->at > w->at)
+  while (k)
     {
-      heap [k] = heap [k >> 1];
+      int p = (k - 1) >> 1;
+
+      if (heap [p]->at <= w->at)
+        break;
+
+      heap [k] = heap [p];
       ((W)heap [k])->active = k + 1;
-      k >>= 1;
+      k = p;
     }
 
   heap [k] = w;
   ((W)heap [k])->active = k + 1;
-
 }
 
 void inline_speed
@@ -657,19 +662,23 @@ downheap (WT *heap, int N, int k)
 {
   WT w = heap [k];
 
-  while (k < (N >> 1))
+  for (;;)
     {
-      int j = k << 1;
+      int c = (k << 1) + 1;
+
+      if (c >= N)
+        break;
 
-      if (j + 1 < N && heap [j]->at > heap [j + 1]->at)
-        ++j;
+      c += c + 1 < N && heap [c]->at > heap [c + 1]->at
+           ? 1 : 0;
 
-      if (w->at <= heap [j]->at)
+      if (w->at <= heap [c]->at)
         break;
 
-      heap [k] = heap [j];
+      heap [k] = heap [c];
       ((W)heap [k])->active = k + 1;
-      k = j;
+
+      k = c;
     }
 
   heap [k] = w;
@@ -786,7 +795,7 @@ siginit (EV_P)
 
 /*****************************************************************************/
 
-static ev_child *childs [EV_PID_HASHSIZE];
+static WL childs [EV_PID_HASHSIZE];
 
 #ifndef _WIN32
 
@@ -1208,7 +1217,7 @@ timers_reify (EV_P)
 {
   while (timercnt && ((WT)timers [0])->at <= mn_now)
     {
-      ev_timer *w = timers [0];
+      ev_timer *w = (ev_timer *)timers [0];
 
       /*assert (("inactive timer on timer heap detected", ev_is_active (w)));*/
 
@@ -1221,7 +1230,7 @@ timers_reify (EV_P)
           if (((WT)w)->at < mn_now)
             ((WT)w)->at = mn_now;
 
-          downheap ((WT *)timers, timercnt, 0);
+          downheap (timers, timercnt, 0);
         }
       else
         ev_timer_stop (EV_A_ w); /* nonrepeating: stop timer */
@@ -1236,7 +1245,7 @@ periodics_reify (EV_P)
 {
   while (periodiccnt && ((WT)periodics [0])->at <= ev_rt_now)
     {
-      ev_periodic *w = periodics [0];
+      ev_periodic *w = (ev_periodic *)periodics [0];
 
       /*assert (("inactive timer on periodic heap detected", ev_is_active (w)));*/
 
@@ -1245,14 +1254,14 @@ periodics_reify (EV_P)
         {
           ((WT)w)->at = w->reschedule_cb (w, ev_rt_now + TIME_EPSILON);
           assert (("ev_periodic reschedule callback returned time in the past", ((WT)w)->at > ev_rt_now));
-          downheap ((WT *)periodics, periodiccnt, 0);
+          downheap (periodics, periodiccnt, 0);
         }
       else if (w->interval)
         {
           ((WT)w)->at = w->offset + ceil ((ev_rt_now - w->offset) / w->interval) * w->interval;
           if (((WT)w)->at - ev_rt_now <= TIME_EPSILON) ((WT)w)->at += w->interval;
           assert (("ev_periodic timeout in the past detected while processing timers, negative interval?", ((WT)w)->at > ev_rt_now));
-          downheap ((WT *)periodics, periodiccnt, 0);
+          downheap (periodics, periodiccnt, 0);
         }
       else
         ev_periodic_stop (EV_A_ w); /* nonrepeating: stop timer */
@@ -1269,7 +1278,7 @@ periodics_reschedule (EV_P)
   /* adjust periodics after time jump */
   for (i = 0; i < periodiccnt; ++i)
     {
-      ev_periodic *w = periodics [i];
+      ev_periodic *w = (ev_periodic *)periodics [i];
 
       if (w->reschedule_cb)
         ((WT)w)->at = w->reschedule_cb (w, ev_rt_now);
@@ -1279,7 +1288,7 @@ periodics_reschedule (EV_P)
 
   /* now rebuild the heap */
   for (i = periodiccnt >> 1; i--; )
-    downheap ((WT *)periodics, periodiccnt, i);
+    downheap (periodics, periodiccnt, i);
 }
 #endif
 
@@ -1591,9 +1600,10 @@ ev_io_start (EV_P_ ev_io *w)
 
   ev_start (EV_A_ (W)w, 1);
   array_needsize (ANFD, anfds, anfdmax, fd + 1, anfds_init);
-  wlist_add ((WL *)&anfds[fd].head, (WL)w);
+  wlist_add (&anfds[fd].head, (WL)w);
 
-  fd_change (EV_A_ fd);
+  fd_change (EV_A_ fd, w->events & EV_IOFDSET);
+  w->events &= ~ EV_IOFDSET;
 }
 
 void noinline
@@ -1605,10 +1615,10 @@ ev_io_stop (EV_P_ ev_io *w)
 
   assert (("ev_io_start called with illegal fd (must stay constant after start!)", w->fd >= 0 && w->fd < anfdmax));
 
-  wlist_del ((WL *)&anfds[w->fd].head, (WL)w);
+  wlist_del (&anfds[w->fd].head, (WL)w);
   ev_stop (EV_A_ (W)w);
 
-  fd_change (EV_A_ w->fd);
+  fd_change (EV_A_ w->fd, 0);
 }
 
 void noinline
@@ -1622,9 +1632,9 @@ ev_timer_start (EV_P_ ev_timer *w)
   assert (("ev_timer_start called with negative timer repeat value", w->repeat >= 0.));
 
   ev_start (EV_A_ (W)w, ++timercnt);
-  array_needsize (ev_timer *, timers, timermax, timercnt, EMPTY2);
-  timers [timercnt - 1] = w;
-  upheap ((WT *)timers, timercnt - 1);
+  array_needsize (WT, timers, timermax, timercnt, EMPTY2);
+  timers [timercnt - 1] = (WT)w;
+  upheap (timers, timercnt - 1);
 
   /*assert (("internal timer heap corruption", timers [((W)w)->active - 1] == w));*/
 }
@@ -1636,7 +1646,7 @@ ev_timer_stop (EV_P_ ev_timer *w)
   if (expect_false (!ev_is_active (w)))
     return;
 
-  assert (("internal timer heap corruption", timers [((W)w)->active - 1] == w));
+  assert (("internal timer heap corruption", timers [((W)w)->active - 1] == (WT)w));
 
   {
     int active = ((W)w)->active;
@@ -1644,7 +1654,7 @@ ev_timer_stop (EV_P_ ev_timer *w)
     if (expect_true (--active < --timercnt))
       {
         timers [active] = timers [timercnt];
-        adjustheap ((WT *)timers, timercnt, active);
+        adjustheap (timers, timercnt, active);
       }
   }
 
@@ -1661,7 +1671,7 @@ ev_timer_again (EV_P_ ev_timer *w)
       if (w->repeat)
         {
           ((WT)w)->at = mn_now + w->repeat;
-          adjustheap ((WT *)timers, timercnt, ((W)w)->active - 1);
+          adjustheap (timers, timercnt, ((W)w)->active - 1);
         }
       else
         ev_timer_stop (EV_A_ w);
@@ -1692,9 +1702,9 @@ ev_periodic_start (EV_P_ ev_periodic *w)
     ((WT)w)->at = w->offset;
 
   ev_start (EV_A_ (W)w, ++periodiccnt);
-  array_needsize (ev_periodic *, periodics, periodicmax, periodiccnt, EMPTY2);
-  periodics [periodiccnt - 1] = w;
-  upheap ((WT *)periodics, periodiccnt - 1);
+  array_needsize (WT, periodics, periodicmax, periodiccnt, EMPTY2);
+  periodics [periodiccnt - 1] = (WT)w;
+  upheap (periodics, periodiccnt - 1);
 
   /*assert (("internal periodic heap corruption", periodics [((W)w)->active - 1] == w));*/
 }
@@ -1706,7 +1716,7 @@ ev_periodic_stop (EV_P_ ev_periodic *w)
   if (expect_false (!ev_is_active (w)))
     return;
 
-  assert (("internal periodic heap corruption", periodics [((W)w)->active - 1] == w));
+  assert (("internal periodic heap corruption", periodics [((W)w)->active - 1] == (WT)w));
 
   {
     int active = ((W)w)->active;
@@ -1714,7 +1724,7 @@ ev_periodic_stop (EV_P_ ev_periodic *w)
     if (expect_true (--active < --periodiccnt))
       {
         periodics [active] = periodics [periodiccnt];
-        adjustheap ((WT *)periodics, periodiccnt, active);
+        adjustheap (periodics, periodiccnt, active);
       }
   }
 
@@ -1745,9 +1755,22 @@ ev_signal_start (EV_P_ ev_signal *w)
 
   assert (("ev_signal_start called with illegal signal number", w->signum > 0));
 
+  {
+#ifndef _WIN32
+    sigset_t full, prev;
+    sigfillset (&full);
+    sigprocmask (SIG_SETMASK, &full, &prev);
+#endif
+
+    array_needsize (ANSIG, signals, signalmax, w->signum, signals_init);
+
+#ifndef _WIN32
+    sigprocmask (SIG_SETMASK, &prev, 0);
+#endif
+  }
+
   ev_start (EV_A_ (W)w, 1);
-  array_needsize (ANSIG, signals, signalmax, w->signum, signals_init);
-  wlist_add ((WL *)&signals [w->signum - 1].head, (WL)w);
+  wlist_add (&signals [w->signum - 1].head, (WL)w);
 
   if (!((WL)w)->next)
     {
@@ -1770,7 +1793,7 @@ ev_signal_stop (EV_P_ ev_signal *w)
   if (expect_false (!ev_is_active (w)))
     return;
 
-  wlist_del ((WL *)&signals [w->signum - 1].head, (WL)w);
+  wlist_del (&signals [w->signum - 1].head, (WL)w);
   ev_stop (EV_A_ (W)w);
 
   if (!signals [w->signum - 1].head)
@@ -1787,7 +1810,7 @@ ev_child_start (EV_P_ ev_child *w)
     return;
 
   ev_start (EV_A_ (W)w, 1);
-  wlist_add ((WL *)&childs [w->pid & (EV_PID_HASHSIZE - 1)], (WL)w);
+  wlist_add (&childs [w->pid & (EV_PID_HASHSIZE - 1)], (WL)w);
 }
 
 void
@@ -1797,7 +1820,7 @@ ev_child_stop (EV_P_ ev_child *w)
   if (expect_false (!ev_is_active (w)))
     return;
 
-  wlist_del ((WL *)&childs [w->pid & (EV_PID_HASHSIZE - 1)], (WL)w);
+  wlist_del (&childs [w->pid & (EV_PID_HASHSIZE - 1)], (WL)w);
   ev_stop (EV_A_ (W)w);
 }