# define EV_USE_PORT 0
#endif
+#ifndef EV_PID_HASHSIZE
+# if EV_MINIMAL
+# define EV_PID_HASHSIZE 1
+# else
+# define EV_PID_HASHSIZE 16
+# endif
+#endif
+
/**/
#ifndef CLOCK_MONOTONIC
#define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */
#define MAX_BLOCKTIME 59.743 /* never wait longer than this time (to detect time jumps) */
-#define PID_HASHSIZE 16 /* size of pid hash table, must be power of two */
/*#define CLEANUP_INTERVAL (MAX_BLOCKTIME * 5.) /* how often to try to free memory and re-check fds */
#ifdef EV_H
}
}
-static void *(*alloc)(void *ptr, long size);
+static void *(*alloc)(void *ptr, size_t size) = realloc;
void
-ev_set_allocator (void *(*cb)(void *ptr, long size))
+ev_set_allocator (void *(*cb)(void *ptr, size_t size))
{
alloc = cb;
}
-static void *
-ev_realloc (void *ptr, long size)
+inline_speed void *
+ev_realloc (void *ptr, size_t size)
{
- ptr = alloc ? alloc (ptr, size) : realloc (ptr, size);
+ ptr = alloc (ptr, size);
if (!ptr && size)
{
- fprintf (stderr, "libev: cannot allocate %ld bytes, aborting.", size);
+ fprintf (stderr, "libev: cannot allocate %ld bytes, aborting.", (long)size);
abort ();
}
/*****************************************************************************/
-static ev_child *childs [PID_HASHSIZE];
+static ev_child *childs [EV_PID_HASHSIZE];
#ifndef _WIN32
{
ev_child *w;
- for (w = (ev_child *)childs [chain & (PID_HASHSIZE - 1)]; w; w = (ev_child *)((WL)w)->next)
+ for (w = (ev_child *)childs [chain & (EV_PID_HASHSIZE - 1)]; w; w = (ev_child *)((WL)w)->next)
if (w->pid == pid || !w->pid)
{
ev_priority (w) = ev_priority (sw); /* need to do it *now* */
ev_feed_event (EV_A_ (W)sw, EV_SIGNAL);
child_reap (EV_A_ sw, pid, pid, status);
- child_reap (EV_A_ sw, 0, pid, status); /* this might trigger a watcher twice, but feed_event catches that */
+ if (EV_PID_HASHSIZE > 1)
+ child_reap (EV_A_ sw, 0, pid, status); /* this might trigger a watcher twice, but feed_event catches that */
}
#endif
return backend;
}
-static void
+static void noinline
loop_init (EV_P_ unsigned int flags)
{
if (!backend)
}
}
-static void
+static void noinline
loop_destroy (EV_P)
{
int i;
backend = 0;
}
-static void
+void inline_size
loop_fork (EV_P)
{
#if EV_USE_PORT
if (expect_true (p->w))
{
- assert (("non-pending watcher on pending list", p->w->pending));
+ /*assert (("non-pending watcher on pending list", p->w->pending));*/
p->w->pending = 0;
EV_CB_INVOKE (p->w, p->events);
{
ev_timer *w = timers [0];
- assert (("inactive timer on timer heap detected", ev_is_active (w)));
+ /*assert (("inactive timer on timer heap detected", ev_is_active (w)));*/
/* first reschedule or stop timer */
if (w->repeat)
{
ev_periodic *w = periodics [0];
- assert (("inactive timer on periodic heap detected", ev_is_active (w)));
+ /*assert (("inactive timer on periodic heap detected", ev_is_active (w)));*/
/* first reschedule or stop timer */
if (w->reschedule_cb)
while (activecnt)
{
+ /* we might have forked, so reify kernel state if necessary */
+ #if EV_FORK_ENABLE
+ if (expect_false (postfork))
+ if (forkcnt)
+ {
+ queue_events (EV_A_ (W *)forks, forkcnt, EV_FORK);
+ call_pending (EV_A);
+ }
+ #endif
+
/* queue check watchers (and execute them) */
if (expect_false (preparecnt))
{
timers [timercnt - 1] = w;
upheap ((WT *)timers, timercnt - 1);
- assert (("internal timer heap corruption", timers [((W)w)->active - 1] == w));
+ /*assert (("internal timer heap corruption", timers [((W)w)->active - 1] == w));*/
}
void
assert (("internal timer heap corruption", timers [((W)w)->active - 1] == w));
- if (expect_true (((W)w)->active < timercnt--))
- {
- timers [((W)w)->active - 1] = timers [timercnt];
- adjustheap ((WT *)timers, timercnt, ((W)w)->active - 1);
- }
+ {
+ int active = ((W)w)->active;
+
+ if (expect_true (--active < --timercnt))
+ {
+ timers [active] = timers [timercnt];
+ adjustheap ((WT *)timers, timercnt, active);
+ }
+ }
((WT)w)->at -= mn_now;
periodics [periodiccnt - 1] = w;
upheap ((WT *)periodics, periodiccnt - 1);
- assert (("internal periodic heap corruption", periodics [((W)w)->active - 1] == w));
+ /*assert (("internal periodic heap corruption", periodics [((W)w)->active - 1] == w));*/
}
void
assert (("internal periodic heap corruption", periodics [((W)w)->active - 1] == w));
- if (expect_true (((W)w)->active < periodiccnt--))
- {
- periodics [((W)w)->active - 1] = periodics [periodiccnt];
- adjustheap ((WT *)periodics, periodiccnt, ((W)w)->active - 1);
- }
+ {
+ int active = ((W)w)->active;
+
+ if (expect_true (--active < --periodiccnt))
+ {
+ periodics [active] = periodics [periodiccnt];
+ adjustheap ((WT *)periodics, periodiccnt, active);
+ }
+ }
ev_stop (EV_A_ (W)w);
}
return;
ev_start (EV_A_ (W)w, 1);
- wlist_add ((WL *)&childs [w->pid & (PID_HASHSIZE - 1)], (WL)w);
+ wlist_add ((WL *)&childs [w->pid & (EV_PID_HASHSIZE - 1)], (WL)w);
}
void
if (expect_false (!ev_is_active (w)))
return;
- wlist_del ((WL *)&childs [w->pid & (PID_HASHSIZE - 1)], (WL)w);
+ wlist_del ((WL *)&childs [w->pid & (EV_PID_HASHSIZE - 1)], (WL)w);
ev_stop (EV_A_ (W)w);
}
}
#endif
+#if EV_FORK_ENABLE
+void
+ev_fork_start (EV_P_ ev_fork *w)
+{
+ if (expect_false (ev_is_active (w)))
+ return;
+
+ ev_start (EV_A_ (W)w, ++forkcnt);
+ array_needsize (ev_fork *, forks, forkmax, forkcnt, EMPTY2);
+ forks [forkcnt - 1] = w;
+}
+
+void
+ev_fork_stop (EV_P_ ev_fork *w)
+{
+ ev_clear_pending (EV_A_ (W)w);
+ if (expect_false (!ev_is_active (w)))
+ return;
+
+ {
+ int active = ((W)w)->active;
+ forks [active - 1] = forks [--forkcnt];
+ ((W)forks [active - 1])->active = active;
+ }
+
+ ev_stop (EV_A_ (W)w);
+}
+#endif
+
/*****************************************************************************/
struct ev_once