//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();
}