ril.cpp中watch_table,timer_list和pending_list的分析

在ril.cpp中定义了3个队列,分别是watch_table,timer_list和pending_list,他们里面都存放的是ril_event结构,他们的主要作用如下:

1. watch_table是一个指针数组,它里面存放的是靠多路复用来驱动的ril_event,起作用的是fd参数,使用ril_event_add朝里面添加event,使用ril_event_del来删除里面的event。

2. timer_list里面存放的是靠timer来驱动的event列表,使用ril_timer_add朝里面添加event。只有一个函数会调用ril_timer_add把event添加进来,那就是internalRequestTimedCallback这个函数,该函数又由RIL_requestTimedCallback来调用。在ril_event_loop里面,select多路复用的timeout时间就是当前timer_list里面最近一个将要超时的event的超时时间。

3. pending_list,是一个存储即将被执行的ril_event的列表(所谓即将执行,就是调用该event的callback函数),下面两个情况会把event添加到该列表:a: watch_table里面某一个event的fd里面有数据可读; b. timer_list里面某一个event已经timeout了。


void ril_event_loop()
{
    int n;
    fd_set rfds;
    struct timeval tv;
    struct timeval * ptv;


    for (;;) {

        /* make local copy of read fd_set
	readFds里面的fd都是watch_table里面的event的fd
	*/
        memcpy(&rfds, &readFds, sizeof(fd_set));

	/*计算select需要等待的时间,这个值是从timer_list里面的event计算出来的*/
        if (-1 == calcNextTimeout(&tv)) {
            // no pending timers; block indefinitely
            dlog("~~~~ no timers; blocking indefinitely ~~~~");
            ptv = NULL;
        } else {
            dlog("~~~~ blocking for %ds + %dus ~~~~", (int)tv.tv_sec, (int)tv.tv_usec);
            ptv = &tv;
        }
	/*多路复用,等待有数据可读,或者超时*/
        n = select(nfds, &rfds, NULL, NULL, ptv);
        dlog("~~~~ %d events fired ~~~~", n);
        if (n < 0) {
            if (errno == EINTR) continue;

            LOGE("ril_event: select error (%d)", errno);
            // bail?
            return;
        }

        /* Check for timeouts
	timer_event里面有event超时了,需要调用超时event的callback来执行相关操作,把这些event加入到pending_list里面*/
        processTimeouts();
        /* Check for read-ready
	处理watch_table里面的有数据可读的fd所在的event,将其放入到timer_list里面*/
        processReadReadies(&rfds, n);
        /* Fire away
	执行pending_list里面的event*/
        firePending();
    }
}


 
 
/*
取得最近马上要超时的一个event的超时时间离现在的微秒数,因为在timer_event列表
里面的event都是按照时间排序排列好的,所以我们只判断最前面一个event就行了。

返回的这个值就是ril_event_loop函数里面select的超时时间
*/
static int calcNextTimeout(struct timeval * tv)
{
    struct ril_event * tev = timer_list.next;
    struct timeval now;

    getNow(&now);

    // Sorted list, so calc based on first node
    if (tev == &timer_list) {
        // no pending timers
        return -1;
    }

    dlog("~~~~ now = %ds + %dus ~~~~", (int)now.tv_sec, (int)now.tv_usec);
    dlog("~~~~ next = %ds + %dus ~~~~",
            (int)tev->timeout.tv_sec, (int)tev->timeout.tv_usec);
    if (timercmp(&tev->timeout, &now, >)) {
        timersub(&tev->timeout, &now, tv);
    } else {
        // timer already expired.
        tv->tv_sec = tv->tv_usec = 0;
    }
    return 0;
}


你可能感兴趣的:(timer,list,struct,table,null,callback)