virtual void Run() { now = v8::base::OS::TimeCurrentMillis(); while (1) { AsyncEvent *p; std::multimap<double, AsyncEvent *>::iterator e; wait(); now = v8::base::OS::TimeCurrentMillis(); while (1) { p = s_acSleep.get(); if (p == NULL) break; s_tms.insert(std::make_pair(now + p->result(), p)); } while (1) { e = s_tms.begin(); if (e == s_tms.end()) break; if (e->first > now) break; e->second->apost(0); s_tms.erase(e); } } }
static void PASCAL Timer(unsigned int uTimerID, unsigned int uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) { AsyncEvent *p; double tm; std::multimap<double, AsyncEvent *>::iterator e; while (1) { p = s_acSleep.get(); if (p == NULL) break; tm = s_time + s_now + p->result(); s_tms.insert(std::make_pair(tm, p)); } atom_xchg(&s_now, (int)(v8::internal::OS::TimeCurrentMillis() - s_time)); while (1) { e = s_tms.begin(); if (e == s_tms.end()) break; if (e->first > s_time + s_now) break; e->second->apost(0); s_tms.erase(e); } }
namespace exlib { exlib::lockfree<AsyncEvent> s_acSleep; std::multimap<double, AsyncEvent *> s_tms; Fiber *Fiber::Current() { Service *pService = Service::getFiberService(); if (pService) return pService->m_running; return NULL; } void Fiber::yield() { Service *pService = Service::getFiberService(); if (pService) pService->yield(); } void Fiber::destroy() { #ifdef WIN32 VirtualFree(this, 0, MEM_RELEASE); #else free(this); #endif } static class _timerThread: public OSThread { public: _timerThread() { start(); } OSSemaphore m_sem; double now; void wait() { std::multimap<double, AsyncEvent *>::iterator e; e = s_tms.begin(); if (e != s_tms.end()) m_sem.TimedWait((int32_t)(e->first - now)); else m_sem.Wait(); } virtual void Run() { now = v8::base::OS::TimeCurrentMillis(); while (1) { AsyncEvent *p; std::multimap<double, AsyncEvent *>::iterator e; wait(); now = v8::base::OS::TimeCurrentMillis(); while (1) { p = s_acSleep.get(); if (p == NULL) break; s_tms.insert(std::make_pair(now + p->result(), p)); } while (1) { e = s_tms.begin(); if (e == s_tms.end()) break; if (e->first > now) break; e->second->apost(0); s_tms.erase(e); } } } static void post(AsyncEvent *p); } s_timer; void _timerThread::post(AsyncEvent *p) { s_acSleep.put(p); s_timer.m_sem.Post(); } void AsyncEvent::sleep(int ms) { m_v = ms; _timerThread::post(this); } void Fiber::sleep(int ms) { if (Service::hasService()) { if (ms <= 0) yield(); else { AsyncEvent as; as.sleep(ms); as.wait(); } } else OSThread::Sleep(ms); } }
void _timerThread::post(AsyncEvent *p) { s_acSleep.put(p); s_timer.m_sem.Post(); }
namespace exlib { Fiber *Fiber::Current() { Service *pService = Service::getFiberService(); if (pService) return pService->m_running; return NULL; } void Fiber::yield() { Service *pService = Service::getFiberService(); if (pService) pService->yield(); } void Fiber::destroy() { free(this); } exlib::lockfree<AsyncEvent> s_acSleep; std::multimap<double, AsyncEvent *> s_tms; static double s_time; static int s_now; #ifndef _WIN32 #define PASCAL #define DWORD_PTR unsigned long* #else static int s_nTimer; #endif double FastCurrentMillis() { return s_time + s_now; } static class _timerThread: public OSThread { public: _timerThread() { time_t timer; time(&timer); s_time = (double)timer * 1000; s_now = 0; start(); } #ifdef _WIN32 ~_timerThread() { timeKillEvent(s_nTimer); } #endif static void PASCAL Timer(unsigned int uTimerID, unsigned int uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) { AsyncEvent *p; double tm; std::multimap<double, AsyncEvent *>::iterator e; while (1) { p = s_acSleep.get(); if (p == NULL) break; tm = s_time + s_now + p->result(); s_tms.insert(std::make_pair(tm, p)); } atom_xchg(&s_now, (int)(v8::internal::OS::TimeCurrentMillis() - s_time)); while (1) { e = s_tms.begin(); if (e == s_tms.end()) break; if (e->first > s_time + s_now) break; e->second->apost(0); s_tms.erase(e); } } virtual void Run() { #ifdef _WIN32 TIMECAPS tc; timeGetDevCaps(&tc, sizeof(TIMECAPS)); if (tc.wPeriodMin < 1) tc.wPeriodMin = 1; timeBeginPeriod(tc.wPeriodMin); s_nTimer = timeSetEvent(tc.wPeriodMin, tc.wPeriodMin, Timer, 0, TIME_PERIODIC); MSG msg; while (GetMessage(&msg, 0, 0, 0)); #else while (1) { Sleep(1); Timer(0, 0, NULL, NULL, NULL); } #endif } } s_timer; void AsyncEvent::sleep(int ms) { m_v = ms; s_acSleep.put(this); } void Fiber::sleep(int ms) { if (Service::hasService()) { if (ms <= 0) yield(); else { AsyncEvent as; as.sleep(ms); as.wait(); } } else OSThread::Sleep(ms); } }
void AsyncEvent::sleep(int ms) { m_v = ms; s_acSleep.put(this); }