예제 #1
0
    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);
            }
        }
    }
예제 #2
0
파일: fbFiber.cpp 프로젝트: cwyiu/fibjs
    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);
        }
    }
예제 #3
0
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);
}

}
예제 #4
0
void _timerThread::post(AsyncEvent *p)
{
    s_acSleep.put(p);
    s_timer.m_sem.Post();
}
예제 #5
0
파일: fbFiber.cpp 프로젝트: cwyiu/fibjs
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);
}

}
예제 #6
0
파일: fbFiber.cpp 프로젝트: cwyiu/fibjs
void AsyncEvent::sleep(int ms)
{
    m_v = ms;
    s_acSleep.put(this);
}