在Android 的ril.cpp中文名可以看到关乎RIL初始化流程第一个--建立基于event队列的消息循环,可以接受上层发来的的请求。
该流程的主要函数RIL_startEventLoop().
该函数主要创建一个以eventlopp为入口的dispatch线程。下面是该函数的代码:
extern "C" void
RIL_startEventLoop(void) {
int ret;
pthread_attr_t attr;
/* spin up eventLoop thread and wait for it to get started */
s_started = 0;
pthread_mutex_lock(&s_startupMutex);
pthread_attr_init (&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
ret = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);
while (s_started == 0) {
pthread_cond_wait(&s_startupCond, &s_startupMutex);
}
pthread_mutex_unlock(&s_startupMutex);
if (ret < 0) {
LOGE("Failed to create dispatch thread errno:%d", errno);
return;
}
}
pthread_mutex_lock(&s_startupMutex)与pthread_mutex_unlock(&s_startupMutex)之间是线程的创建,加锁与解锁是为了多线程的冲突。
pthread_attr_init (&attr)与 pthread_create()为线程的创建,在创建时 pthread库会自动地为线程设定栈大小,我们通常不用明显地指定。当发生了内存分配不足时,就必须我们自已动手来指定栈大小。这里我们可以看到eventLoop的入口。
在创建之前初始化线程,我们可以利用pthread_attr_getstacksize来得到默认分配大小,注意到必须先调用pthread_attr_init初始化函数,才能得到正确的值,否则得到的值是不正确的。 其中用pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)来使线程达到detach状态。
这里就是dispatch线程的创建过程。
开始分析Android源代码中的RIL部分。
又上图,以及其他相关资料,我得知在Android中有一个叫rild的守护进程。我猜测此进程与电话的拨打接听有莫大关系。
而且在Android系统中存在这么一个rild的可执行文件,源代码中的"hardware/ril/rild"目录下有rild.c的文件 ,且在rild.c中,我们找到了main函数,即我们已经找到了rild守护进程的程序入口啦~
自赞一个先~
开始分析rild守护进程的代码。
在代码开始部分,有一些关于参数解析的片段,暂时先撇开一边,先讲一下rild守护进程的关于RIL的一些重要流程:
main()
{//省略n行
RIL_startEventLoop();
//省略n行
}
从名字上看就应该觉得这应该是一个起点——"startEventLoop"——一个开始进入时间循环的一点,让我们跟踪进去看看^_^
在"rild.c"中有这么一行:extern void RIL_startEventLoop();
说明RIL_startEventLoop函数的代码还在别处,经查找,发现是在这里:
"hardware\ril\libril"目录下的Ril.cpp文件中。
Get it~
在Ril.cpp中的RIL_startEventLoop中有这么一行:
ret = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);
看来Android是在这里开辟一个线程来执行eventLoop循环,
这个eventLoop函数也在这个文件里(Ril.cpp)。
eventLoop中,主要执行了:
ril_event_init();
ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,
processWakeupCallback, NULL);
ril_event_add (&s_wakeupfd_event);
ril_event_loop();
由函数名可猜测:
ril_event_set使用了新建一个ril事件的,
而ril_event_add 将该新事件添加进某执行队列中。
最后,在循环ril_event_loop中进行一个轮询,捕获事件,进而完成事件处理。
经过对ril_event_set和ril_event_add的代码阅读,证实了之前的两点猜测,
(ril_event_set和ril_event_add以及ril_event_loop函数代码在"hardware\ril\libril"目录下的ril_event.cpp中)
新事件加入了一个叫watch_table的数组中。
而 ril_event_loop则调用了一个select函数,目前还在分析该函数中~~(猜测是unix类系统的系统调用,暂时先放过)
重新从eventloop的流程开始分析起:
首先,是那个ril_event_init函数。ril_event_init函数在Ril_event.cpp("hardware\ril\libril"),Ril_event.cpp中有一个timer_list的ril_event结构体,这个结构体充当待处理的事件队列(I guest)
而ril_event_init就是在做事件队列的初始化工作(通过init_list(&timer_list),当然还有另外还初始化了pending_list)
然后,就是ril_event_set一个事件结构s_wakeupfd_event
接着,就是ril_event_add该s_wakeupfd_event结构体添加到Ril_event.cpp的watch_table数组中。
最后就是执行ril_event_loop循环了。