免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開(kāi)通VIP
淺析Android的RILD服務(wù)進(jìn)程的消息循環(huán)

淺析Android的RILD服務(wù)進(jìn)程的消息循環(huán)  

2012-01-11 15:36:27|  分類: Android開(kāi)發(fā) |  標(biāo)簽:android  消息   |字號(hào) 訂閱

Android中,RILD是RIL(Radio Interface Layer) Deamon的簡(jiǎn)稱。簡(jiǎn)單的說(shuō)它下面承接GSM/GPRS Modem(電話通信模塊),上面接電話應(yīng)用相關(guān)的Java庫(kù)(telephony internal)。telephony internal通過(guò)socket將請(qǐng)求發(fā)送給RILD的消息循環(huán),消息循環(huán)則將請(qǐng)求轉(zhuǎn)發(fā)給底層通信模塊(直接調(diào)用底層的庫(kù))來(lái)實(shí)現(xiàn)對(duì)通信模塊功能的調(diào) 用。反之,當(dāng)通信模塊有類似于來(lái)電的消息時(shí),也會(huì)通過(guò)RILD的回調(diào),將信息包裝成消息,發(fā)送到RILD的消息循環(huán)中去處理,最后再通過(guò)socket回送 給telephony internal,以便通知上層。整體結(jié)構(gòu)參見(jiàn)如下:


  • 概述 

        消息循環(huán)(ril_event_loop()函數(shù)內(nèi))位于單獨(dú)的線程中,用來(lái)處理三種消息,分別對(duì)應(yīng)三個(gè)不同的隊(duì)列,面對(duì)的是三種不同的需求:
        1.定時(shí)列表(timer_list): 此隊(duì)列中的消息主要用于處理一些延時(shí)的操作。比如:從飛信模式切換到通信模式(實(shí)際上就是打開(kāi)通信模塊)時(shí),若SIM卡未準(zhǔn)備好,那么需要延續(xù)一段時(shí)間再檢查是否準(zhǔn)備好,此時(shí)就要將消息扔至此隊(duì)列。
        2.偵聽(tīng)列表(watch_list): 此隊(duì)列中的消息一是作為socket的服務(wù)端,用來(lái)偵聽(tīng)客戶端的請(qǐng)求;另一個(gè)是作為本進(jìn)程的其它線程(如:檢查通信模塊來(lái)電消息的線程)傳遞過(guò)來(lái)的消息。
        3.掛起列表(pending_list): 之所以叫掛起,實(shí)際上指的是在處理上面兩中類型的消息時(shí),并不真正的處理消息體,而是將符合條件的消息丟到本隊(duì)列中。由于消息附帶處理函數(shù),所以在處理本隊(duì)列的消息時(shí),直接觸發(fā)即可。
        消息循環(huán)所要做的事就是先等待某個(gè)時(shí)間間隔(定時(shí)消息要求的)或者是客戶端(socket或通訊模塊的消息)的請(qǐng)求,然后再按次序處理上面三個(gè)對(duì)列中的消息。

        下面還是通過(guò)源代碼來(lái)分析消息循環(huán)的處理過(guò)程。

  • ril_event

        ril_event指代的是消息,它的數(shù)據(jù)結(jié)構(gòu)如下:

  1. struct ril_event *next; // 下一個(gè)消息   
  2. struct ril_event *prev; // 前一個(gè)消息   
  3. int fd; // 開(kāi)始我以為這里有可能是socket描述符或pipe描述符,但實(shí)際上它還被用作消息的回調(diào)函數(shù)的參數(shù)?   
  4. int index; // 偵聽(tīng)列表(watch_list)中的索引,偵聽(tīng)列表采用的數(shù)組而不是鏈表   
  5. bool persist; // 是否常駐偵聽(tīng)列表(watch_list)中。若常駐,則當(dāng)被轉(zhuǎn)到pending_list中時(shí),不刪除。   
  6. struct timeval timeout; // 超時(shí),這個(gè)為一個(gè)時(shí)間點(diǎn)。在處理定時(shí)消息時(shí),用于和當(dāng)前的時(shí)間比較,以確定是否處理該消息。   
  7. ril_event_cb func; // 回調(diào)。此消息對(duì)應(yīng)的處理函數(shù)。   
  8. void *param; // 回調(diào)參數(shù)。  
        三種消息列表的定義如下:
  1. static struct ril_event * watch_table[MAX_FD_EVENTS]; // 偵聽(tīng)列表   
  2. static struct ril_event timer_list; // 定時(shí)列表   
  3. static struct ril_event pending_list; // 掛起列表  
  • ril_event_init()

        初始化過(guò)程還是要從rild的main入口開(kāi)始分析起,位于文件hardware/ril/rild/rild.c。簡(jiǎn)單期間,只介紹本文相關(guān)的部分。 main()函數(shù)會(huì)調(diào)用函數(shù)RIL_register(),然后會(huì)調(diào)用RIL_startEventLoop()。 RIL_startEventLoop()中會(huì)創(chuàng)建線程eventLoop,這個(gè)實(shí)際上就是rild的消息循環(huán)所在的線程。

  1. ret = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);  
        eventLoop()首先會(huì)進(jìn)行初始化:
  1. ril_event_init();  
        然后,會(huì)通過(guò)pipe()函數(shù)創(chuàng)建管道。pipe()函數(shù)會(huì)創(chuàng)建一對(duì)文件描述符,一個(gè)用于讀,另一個(gè)用于寫。都被記錄在全局變量中。它實(shí)際上是用來(lái)發(fā)送定時(shí)消息的,后面會(huì)介紹。
  1. ret = pipe(filedes);  
  2. // ......   
  3. s_fdWakeupRead = filedes[0]; // 消息循環(huán)中偵聽(tīng)   
  4. s_fdWakeupWrite = filedes[1]; // 用于通知消息循環(huán)定義消息已發(fā)送  
        最后一步就是進(jìn)入消息循環(huán):
  1. // Only returns on error   
  2. ril_event_loop();  
  • ril_event_loop()

        ril_event_loop()中,每次循環(huán)都主要做三件事:
        1.初始化。主要是獲取要等待的描述符,以及獲取超時(shí)信息,以便能夠及時(shí)處理定時(shí)消息。
        2.等待。等待socket客戶端有新的消息,或一定的時(shí)間間隔,之后處理定時(shí)消息。
        3.依次處理三種類型的消息。
        下面分別敘述之。先是獲取要等待的描述符,這里為什么要這么做呢?我的理解是在添加新的消息時(shí),有可能會(huì)修改全局的描述符列表。也就是說(shuō),全局的描述符列表有可能在本次循環(huán)的處理過(guò)程中發(fā)生變化。

  1. // make local copy of read fd_set   
  2. memcpy(&rfds, &readFds, sizeof(fd_set));  
        接下來(lái),就是計(jì)算select()函數(shù)的超時(shí)參數(shù)。select的最后一個(gè)參數(shù)代表超時(shí)。若為NULL,則select死等;若為0,則select立即返回;若大于0,則限制了select最長(zhǎng)的等待時(shí)間。
  1. if (-1 == calcNextTimeout(&tv)) { // 獲取超時(shí)參數(shù),若失敗則返回-1。   
  2.     // no pending timers; block indefinitely   
  3.     dlog("~~~~ no timers; blocking indefinitely ~~~~");  
  4.     ptv = NULL;  
  5. else { // 獲取成功,則使用該值。   
  6.     dlog("~~~~ blocking for %ds + %dus ~~~~", (int)tv.tv_sec, (int)tv.tv_usec);  
  7.     ptv = &tv;  
  8. }  
        calcNextTimeout()函數(shù)先是判斷超時(shí)消息的列表是否為空,為空則返回-1;
  1. // Sorted list, so calc based on first node   
  2. if (tev == &timer_list) {  
  3.     // no pending timers   
  4.     return -1;  
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Android RIL結(jié)構(gòu)分析與移植
Android GSM驅(qū)動(dòng)模塊詳細(xì)分析
Android的電話功能介紹
android phone 模塊分析
ANDROID的APN設(shè)置
RIL
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服