midp事件的存储和获取

//midp事件的存储和获取


// 类似消费者

// 获取MIDP事件,保存在pResult中;返回未处理的MIDP事件个数
static int
getPendingMIDPEvent(MidpEvent* pResult, int isolateId)
{
    // 获取Isolate对应的等待事件队列
    // 在MVM模式下,每个Isolate有1个等待事件队列
    // 在SVM模式下,有1个等待事件队列
    EventQueue* pEventQueue = getIsolateEventQueue(isolateId);

    // 队列中的事件个数为0时
    if (pEventQueue->numEvents == 0)
    {
        return -1;
    }

    // 队列中有事件时,取出队列当前尾部的这个事件
    *pResult = pEventQueue->events[pEventQueue->eventOut];

    // 取出事件后,对该队列位置元素值进行重新初始化
    /* Empty out the events so we do not free it when finalizing. */
    MIDP_EVENT_INITIALIZE(pEventQueue->events[pEventQueue->eventOut]);

    // 事件计数减1
    pEventQueue->numEvents--;
    // 取事件位置向后挪一个元素
    pEventQueue->eventOut++;
    // 循环队列,到达最大个数后,回到初始位置
    if (pEventQueue->eventOut == MAX_EVENTS)
    {
         /* This is a circular queue, so start back at zero. */
        pEventQueue->eventOut = 0;
    }

    // 返回队列当前的事件个数
    return pEventQueue->numEvents;
}



// 类似生产者
// 把MIDP事件保存到isolateId对应的事件队列中去
static void StoreMIDPEventInVmThreadImp(MidpEvent event, int isolateId)
{
    EventQueue* pEventQueue;
    JVMSPI_ThreadID thread;

    pEventQueue = getIsolateEventQueue(isolateId);

    midp_logThreadId("StoreMIDPEventInVmThread");

    // 临界区,加锁
    midp_waitAndLockEventQueue();

    // 事件队列未满,可继续存储事件
    if (pEventQueue->numEvents != MAX_EVENTS)
    {
        pEventQueue->events[pEventQueue->eventIn] = event;
        pEventQueue->eventIn++;
        if (pEventQueue->eventIn == MAX_EVENTS) {
            /* This is a circular queue, so start back at zero. */
            pEventQueue->eventIn = 0;
        }
      
        pEventQueue->numEvents++;

        if (pEventQueue->isMonitorBlocked)
        {    
            /*
            * The event monitor thread has been saved as the "special" thread
            * of this particular isolate in order to avoid having to search
            * the entire list of threads.
            */
            thread = SNI_GetSpecialThread(isolateId);
            
            /* check and align stack suspend/resume state */
            // midp_checkAndResume();
            
            if (thread != NULL)
            {    
                midp_thread_unblock(thread);
                pEventQueue->isMonitorBlocked = KNI_FALSE;
            }
            else
            {
                REPORT_CRIT(LC_CORE,
                    "StoreMIDPEventInVmThread: cannot find "
                    "native event monitor thread");
            }
        }
    }
    // 事件队列已满,此时发过来的事件将被丢弃!
    else
    {
        /*
        * Ignore the event; there is no space to store it.
        * IMPL NOTE: this should be fixed, or it should be a fatal error;
        * dropping an event can lead to a full system deadlock.
        */
        REPORT_CRIT1(LC_CORE,"**event queue %d full, dropping event",isolateId);
    }

    midp_unlockEventQueue();
}



你可能感兴趣的:(midp事件的存储和获取)