--- deliantra/server/server/evthread.C 2008/04/03 09:31:33 1.3 +++ deliantra/server/server/evthread.C 2008/04/06 16:13:23 1.4 @@ -28,13 +28,15 @@ #define TICK_CYCLES 4 -// the ticker runs TICK_CYCLES times as fast as the main server tick -static ev_periodic cede_watcher; // the tick watcher is activated every TICK_CYCLES ev_async tick_watcher; - EV_ATOMIC_T coroapi::cede_pending; +// the ticker runs TICK_CYCLES times as fast as the main server tick +static ev_periodic cede_watcher; + +///////////////////////////////////////////////////////////////////////////// + // it is a bit silly to have to use a mutex, but contention // is basically non-existant, favouring good mutex implementations. static SMUTEX (evthread_mutex); @@ -61,7 +63,7 @@ next_tick = w->at + TICK / TICK_CYCLES * (TICK_CYCLES - 1); SMUTEX_UNLOCK (evthread_mutex); - ev_async_send (EV_DEFAULT, &tick_watcher); + ev_async_send (EV_DEFAULT_UC, &tick_watcher); } coroapi::cede_pending = 1; @@ -73,26 +75,78 @@ cfperl_tick (); } -static void * -evthread_proc (void *arg) +///////////////////////////////////////////////////////////////////////////// + +static ev_async async_watcher; +static ev_io aio1_watcher; +static ev_idle aio2_watcher; +static EV_ATOMIC_T aio_pending; + +static void +aio2_cb (EV_P_ ev_idle *w, int revents) { - loop = ev_loop_new (0); + CALL_BEGIN (0); + CALL_CALL ("IO::AIO::poll_cb", G_SCALAR); - ev_periodic_init (&cede_watcher, cede_cb, 0, TICK / TICK_CYCLES, 0); - ev_periodic_start (loop, &cede_watcher); + if (count > 0 && TOPi > 0) + ev_idle_start (EV_A, w); + else + ev_idle_stop (EV_A, w); + + CALL_END; +} + +static void +async_cb (EV_P_ ev_async *w, int revents) +{ + aio2_cb (EV_A, &aio2_watcher, 0); +} + +static void +aio1_cb (EV_P_ ev_io *w, int revents) +{ + char dummy; + + if (read (w->fd, &dummy, 1) > 0) + { + ev_async_send (EV_DEFAULT_UC, &async_watcher); + coroapi::cede_pending = 1; + } +} +///////////////////////////////////////////////////////////////////////////// + +static void * +evthread_proc (void *arg) +{ ev_loop (loop, 0); return 0; } -void evthread_start () +void evthread_start (int aiofd) { I_EV_API ("evthread"); + // main loop ev_async_init (&tick_watcher, tick_cb); ev_set_priority (&tick_watcher, 1); - ev_async_start (EV_DEFAULT, &tick_watcher); + ev_async_start (EV_DEFAULT_UC, &tick_watcher); + + ev_async_init (&async_watcher, async_cb); + ev_set_priority (&async_watcher, 1); + ev_async_start (EV_DEFAULT_UC, &async_watcher); + + ev_idle_init (&aio2_watcher, aio2_cb); + + // secondary loop + loop = ev_loop_new (0); + + ev_periodic_init (&cede_watcher, cede_cb, 0, TICK / TICK_CYCLES, 0); + ev_periodic_start (loop, &cede_watcher); + + ev_io_init (&aio1_watcher, aio1_cb, aiofd, EV_READ); + ev_io_start (loop, &aio1_watcher); evthread.start (evthread_proc); }