ril.cpp中watch_table,timer_list和pending_list的分析
来源:互联网 发布:java 日历选择控件 编辑:程序博客网 时间:2024/06/08 20:15
在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_setreadFds里面的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 timeoutstimer_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;}
- ril.cpp中watch_table,timer_list和pending_list的分析
- ril.cpp中用到的RecordStream类分析
- Linux内核中timer_list定时器的使用
- eventloop(ril.cpp)函数中定义的管道的作用(Android)
- 内核定时器 timer_list 分析
- 内核定时器 timer_list 分析
- ril.cpp中的strndup16to8和strdup8to16和readString16Inplace
- ril.cpp解析
- 如何分析c和cpp的声明
- timer_list
- timer_list
- timer_list
- Android RIl模块的结构分析
- ril层的所有代码分析
- ril层的所有代码分析
- Android RIL架构分析——(1)本地库实现[c/cpp部分]
- Android RIL架构分析——(1)本地库实现[c/cpp部分]
- Android RIL架构分析——(1)本地库实现[c/cpp部分]
- 学C/C++都能做什么?
- Windows8硬件配置要求
- NSScrollView指定滚动条移动的位置
- 通过SDE服务直连Oracle数据库的配置
- Erlang 学习:关于rebar 和 自带debugger 小记录
- ril.cpp中watch_table,timer_list和pending_list的分析
- 在Windows7 64bit Home版下安装android sdk后,无法启动SDK Manager的解决方法之一
- Android layout_weight属性
- MFC消息映射机制
- Hibernate的检索方式(一)
- 江西移动BOSS异地联机热备份应用--案例
- c#——转义符"\""
- Linux crontab 自动定时执行命令学习
- LinkedHashMap 的介绍