当前位置:首页 > Android中RIL层详细分析与总结
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
用read()得方法去唤醒fd,把可执行得弹出来,ril_event 去复位定时器,把缓冲区清空
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- /**
* A write on the wakeup fd is done just to pop us out of select()
* We empty the buffer here and then ril_event will reset the timers on the * way back down */
static void processWakeupCallback(int fd, short flags, void *param) {
char buff[16]; int ret;
LOGD(\ LOGV(\ /* empty our wakeup socket out */ do {
ret = read(s_fdWakeupRead, &buff, sizeof(buff)); } while (ret > 0 || (ret < 0 && errno == EINTR)); }
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
rilEventAddWakeup的作用是:作为ril_event_add(ev);和triggerEvLoop();入口函数,真正的把数据数组 watch_table[i] = ev上去,等待selcet轮询,最后写入
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
static void rilEventAddWakeup(struct ril_event *ev) {
ril_event_add(ev); triggerEvLoop(); }
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // Add event to watch list
void ril_event_add(struct ril_event * ev)
{
LOGD(\ dlog(\ MUTEX_ACQUIRE();
for (int i = 0; i < MAX_FD_EVLL) { //1:
watch_table[i] = ev;//把上面ril_event_add函数添加的事件_wakeupfd_event结构体添加到这个数组来 ev->index = i;
dlog(\ dump_event(ev);
//2:
FD_SET(ev->fd, &readFds);//把上面数组,放到readFds来 if (ev->fd >= nfds) nfds = ev->fd+1; dlog(\ break;ENTS; i++) { if (watch_table[i] == NU } }
MUTEX_RELEASE();
dlog(\}
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
就是上面管道读完,收到数据后,再通过写端,写到对应的数组去(readFs)
static void triggerEvLoop() {
int ret;
LOGD(\ if (!pthread_equal(pthread_self(), s_tid_dispatch)) { /* trigger event loop to wakeup. No reason to do this, * if we're in the event loop thread */ do {
ret = write (s_fdWakeupWrite, \ } while (ret < 0 && errno == EINTR); } }
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
上面工作一做完,说明通过pipe机制已经把数据读到,并放入数组,而数组且放在readFs队列中,等待ril_event_loop()函数t轮询
下面为ril_event_loop()开始轮询的整个过程:
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void ril_event_loop()
{ int n; fd_set rfds; struct timeval tv; struct timeval * ptv;
LOGD(\ for (;;) {//死循环的轮询
// make local copy of read fd_set
LOGD(\
memcpy(&rfds, &readFds, sizeof(fd_set));把上面通过管道机制读到得数据,换个名字,放到rfds
去
if (-1 == calcNextTimeout(&tv)) {// 获取超时参数,若失败则返回-1。 // no pending timers; block indefinitely
dlog(\ ptv = NULL;
} else {// 获取成功,则使用该值。
dlog(\ ptv = &tv; }
printReadies(&rfds);
LOGD(\ LOGI(\ //初始化到这里结束。
n = select(nfds, &rfds, NULL, NULL, ptv);//等待
fd唤醒,通过selcet多路I/o复用
机制去唤醒管道来的数据
LOGD(\ LOGI(\ printReadies(&rfds);
dlog(\ if (n < 0) {
if (errno == EINTR) continue;
LOGE(\ // bail? return; }
LOGD(\processTimeouts();--\ // Check for timeouts
processTimeouts();// 处理定时消息 ,处理ril_event_init ->pending_list // Check for read-ready
LOGD(\
processReadReadies(&rfds, n); // 处理侦听消息 ,处理ril_event_init ->watch_list // Fire away
LOGD(\ firePending(); // 处理挂起消息
LOGD(\ } }
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
static void processTimeouts()
{
LOGD(\LOGI(\
dlog(\ MUTEX_ACQUIRE();
struct timeval now;
struct ril_event * tev = timer_list.next; struct ril_event * next; getNow(&now);//获取当前时间
// walk list, see if now >= ev->timeout for any events
dlog(\
while ((tev != &timer_list) && (timercmp(&now, &tev->timeout, >))) {// 查找所有当前时间点以前的消息 // Timer expired
dlog(\ next = tev->next;
removeFromList(tev);//从定时消息队列中移除,就是已经做完的内容 addToList(tev, &pending_list); // 添加至挂起列表(pending_list)中 tev = next; }
MUTEX_RELEASE();
dlog(\}
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
static void addToList(struct ril_event * ev, struct ril_event * list) {
LOGD(\ ev->next = list; ev->prev = list->prev; ev->prev->next = ev; list->prev = ev; dump_event(ev); }
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
static void processReadReadies(fd_set * rfds, int n) {
LOGD(\LOGI(\
dlog(\ MUTEX_ACQUIRE();
for (int i = 0; (i < MAX_FD_EVENTS) && (n > 0); i++) { // 此处判断描述符是否在当前循环的等待列表中。 struct ril_event * rev = watch_table[i]; if (rev != NULL && FD_ISSET(rev->fd, rfds)) {
addToList(rev, &pending_list);// 添加至挂起列表(pending_list)中
if (rev->persist == false) { // 会判断ril_event的persist参数,以决定是否从watch_list移除该消息。 removeWatch(rev, i); } n--;
共分享92篇相关文档