成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Hi3516的SAMGR--系統服務框架子系統-client EP的注冊

系統
本篇給大家分析wms_server進程后繼的啟動步驟和注冊EP的流程,從DEFAULT_Initialize(ServiceImpl *impl) 函數入口開始。

[[409617]]

想了解更多內容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術社區

https://harmonyos.51cto.com

我們接著前文《Hi3516的SAMGR--系統服務框架子系統-6-系統服務的啟動》,繼續分析wms_server進程后繼的啟動步驟和注冊EP的流程,從DEFAULT_Initialize(ServiceImpl *impl) 函數入口開始。

從前文可以知道,wms_server進程啟動了三個service:Broadcast、WMS和IMS,Broadcast服務有一個feature:“Provider and subscriber”,另外兩個服務,沒有feature。每個service都有自己的消息隊列,都會收到InitRequest消息,通過HandleInitRequest()函數,service會帶著自己的feature跑一遍DEFAULT_Initialize(serviceImpl)函數。

  1. //foundation/distributedschedule/samgr_lite/samgr/source/service.c 

DEFAULT_Initialize()內,很明顯可以分為以下四步的:

針對service跑前兩步

  1. [4-1] impl->service->Initialize(impl->service, id) 

這一步會調用service自己生命周期的 Initialize() 函數來做初始化。

  1. [4-2] SAMGR_RegisterServiceApi(serviceName, NULL, &id, impl->defaultApi) 

這一步輕量系統執行空函數,沒有實際動作;小型系統執行remote_register.c 中定義的函數,注意參數。

針對service所有的feature,for循環讓每個feature都執行一遍[4-3]和[4-4]兩步,service沒有feature,就不用執行這兩步:

  1. [4-3] feature->feature->OnInitialize(feature->feature, impl->service, id) 

這一步會調用feature自己生命周期的 OnInitialize() 函數來做初始化。

  1. [4-4] SAMGR_RegisterServiceApi(serviceName, featureName, &id, feature->iUnknown) 

這一步調用的API與第2步調用的是同一個API,但是注意參數的變化,特別是第四個參數。

  1. //foundation/distributedschedule/samgr_lite/samgr_client/source/remote_register.c 

我們詳細看一下SAMGR_RegisterServiceApi()的工作,它內部,也很明顯可以分為以下三步的:

  1. [3-1] InitializeRegistry() 

每一個進程,都有一個全局的RemoteRegister g_remoteRegister,本進程的所有services中,第一個跑到這里的service會去初始化這個 g_remoteRegister,主要是創建互斥信號量、創建一個空的Vector clients、創建本進程的通信終端endpoint。以后的service/feature再跑進這一步時,基本上都會因為已經存在endpoint了而就此退出(特定條件下會清空本 g_remoteRegister,重新生成,這里先不管)。

我們先把關注的重點放在創建 EP上。

  1. //foundation/distributedschedule/samgr_lite/samgr_endpoint/source/endpoint.c 

所有進程都會通過SAMGR_CreateEndpoint("ipc client", NULL) 創建一個名為"ipc client"的EP,只有管理者會創建名為"samgr"的EP,這個后面講。

SAMGR_CreateEndpoint()內會初始化如下一些參數(沒列出來的先略去):

  1. endpoint->context = OpenLiteIpc(LITEIPC_DEFAULT_MAP_SIZE);   
  2.  
  3.  endpoint->boss   = NULL
  4.  
  5.  endpoint->routers = VECTOR_Make((VECTOR_Key)GetIServerProxy, (VECTOR_Compare)CompareIServerProxy); 
  6.  
  7.  endpoint->name  = name;  
  8.  
  9.  endpoint->identity.handle = (uint32_t)INVALID_INDEX; 
  10.  
  11.  endpoint->identity.token  = (uint32_t)INVALID_INDEX;    
  12.  
  13.  endpoint->identity.cookie = (uint32_t)INVALID_INDEX; 
  14.  
  15.  endpoint->registerEP = RegisterRemoteEndpoint; 

context = OpenLiteIpc() 打開本進程這一端的IPC通信通道,獲取上下文,相當于拿到了開啟通道一端大門的鑰匙,要能夠進行IPC通信,需要另一端的大門也打開才行。

boss:本EP的專用于IPC通信的線程的handle,還沒創建線程,目前是NULL;

endpoint->routers:這里先創建一個空的向量,配置向量的key和compare函數。本進程內所有的service/feature中,符合條件的service/feature才能添加到這個向量中,成為這個routers Vector中的一個element,也就是內部的通信節點,這樣才能對外部進程提供服務和接口。在具體的IPC通信時,會通過下面的endpoint->identity.token來確認是哪個element提供服務。

name: 就是"ipc client"字符串,作用不大;

endpoint->identity.handle:是本EP向管理者注冊自己后,管理者為本EP返回的一個handle,非常重要,目前還沒有向管理者注冊自己,所以是INVALID_INDEX,這個INVALID_INDEX是特定的值[5],為什么是5,后面再講。

endpoint->identity.token:具體的IPC通信中才會用到,用來標記本次IPC通信中,需要endpoint->routers 向量中的具體哪個element提供服務或接口。

endpoint->registerEP:是函數指針,指向本EP向管理者注冊自己的函數,因為是"ipc client" EP,所以注冊函數是RegisterRemoteEndpoint(),要是"samgr" EP,注冊函數就會是RegisterSamgrEndpoint()。

  1. [3-2] SAMGR_AddRouter(g_remoteRegister.endpoint, &saName, identity, iUnknown) 

在上一步創建好的EP內,把“符合條件”的service和/或feature作為本EP內部的一個通信節點(router)添加到endpoint->routers向量里面去,進行管理。

“符合條件”的條件,有幾個,關鍵的兩個如下:

條件1:IUnknown *proxy 不能為NULL

service/feature對外提供的接口不能為空,為空也就意味著外部進程沒法使用service/feature提供的服務了,也就沒必要加到endpoint->routers向量里去了。

這個條件可以過濾掉很多service,比如Broadcast服務,它在Init時,只通過RegisterService()注冊了服務,并沒有注冊defaultApi,并且它自己也是有feature的,所以它的serviceImpl->defaultApi是NULL:

Hi3516的SAMGR--系統服務框架子系統-8-client EP的注冊-鴻蒙HarmonyOS技術社區

而向WMS服務(IMS服務也如此),在Init時注冊了default feature API,同時它自己也沒有feature,所以它的serviceImpl->defaultApi不是NULL,而是指向了WMSService 結構體內部的IUnknown接口對象,以此向外部進程提供功能。

Hi3516的SAMGR--系統服務框架子系統-8-client EP的注冊-鴻蒙HarmonyOS技術社區

條件2:SERVER_PROXY_VER 要匹配 0x80

上一個條件的defaultApi不為NULL,指向了service/feature結構體內部的IUnknown接口對象,而這個接口對象的版本ver,要滿足條件(匹配SERVER_PROXY_VER,即0x80),才能將其添加到endpoint->routers向量里,去對外部進程提供服務。

Hi3516的SAMGR--系統服務框架子系統-8-client EP的注冊-鴻蒙HarmonyOS技術社區

都滿足條件了,還要在endpoint->routers向量里先查找一下,確認當前接口proxy是否已經在向量表里了,已經在了的話,就不能重復添加。

當前接口proxy沒在向量表里,那就可以創建一個router對象,將提供proxy接口的service/feature、identity、serverProxy等相關信息配置好,將router對象(指針)添加到endpoint->routers向量里。

添加router成功后,會調用 Listen(endpoint):

Hi3516的SAMGR--系統服務框架子系統-8-client EP的注冊-鴻蒙HarmonyOS技術社區

第一句,boss 不為NULL 就return掉,意味著,第一個添加到endpoint->routers向量里的router添加成功后,就進來創建boss線程,專門用于本進程的對外IPC通信,后面再添加router成功時,因為boss線程已經在對外IPC通信了,所以不需要重復創建boss線程。

創建的boss線程,跑Receive()入口,具體做什么事情,我們稍后再講。

  1. [3-3] SAMGR_ProcPolicy(g_remoteRegister.endpoint, &saName, token) 

能跑到這一步來,也是要首先滿足兩個條件:

1. 上一步的router成功添加到endpoint->routers向量里,拿到了有效的token,這個token就是router在向量的位置,也就是endpoint->routers->data[token]是一個指針,指向添加成功的router;

2. 本進程的g_remoteRegister.endpoint->running 標記要為TRUE,這意味著管理者那端的IPC通道也打開了,本進程EP已經完成了向管理者注冊,拿到了本EP中SvcIdentity identity關鍵的handle,本進程可以開始對外提供服務了。

兩個條件都滿足后,這里就是要向管理者注冊feature并且獲取這個feature的訪問權限策略信息,并保存在router的policyNum/policy 字段內。看上去這個函數的作用與RegisterRemoteFeatures()的作用差不多。

接下來,我們看一下boss線程的Receive()入口函數,都做了些什么事情。我把它分成4個階段來理解:

[4-1] 第一階段,向管理者知名EP注冊本EP,獲取本EP的身份信息中的handle。這步需要管理者g_server跑起來,知名EP打開IPC通道,這里才能通過IPC注冊本EP,在知名EP還沒跑起來之前,本進程EP的這一階段會跑如下的循環:

Hi3516的SAMGR--系統服務框架子系統-8-client EP的注冊-鴻蒙HarmonyOS技術社區

registerEP是上面創建EP時配置的EP注冊函數,對"ipc client" EP,注冊函數是RegisterRemoteEndpoint()。

進入RegisterRemoteEndpoint()里面看一下,又是一個while循環,循環內會發送IPC信息,向知名EP samgr注冊本EP,知名EP的信息直接硬編碼寫成:

  1. SvcIdentity samgr = {SAMGR_HANDLE, SAMGR_TOKEN, SAMGR_COOKIE}; //{0, 0, 0} 

這就是所謂的“知名”了。

這個內部循環,注冊成功就拿到了SvcIdentity *identity中的handle,注冊不成功(主要原因是知名EP還沒開始工作),就會sleep(5s)再重新嘗試。

內外兩層循環合在一起,相當于在60s內嘗試注冊9次,正常情況下只要知名EP跑起來了,就肯定能注冊成功的。

注冊成功,或者一分鐘內注冊不成功,就會進入下面的第二階段。

[4-2] 第二階段,注冊成功,就拿到了知名EP返回來的SvcIdentity identity.handle。

一分鐘內注冊不成功,直接就exit (-ret),意味著本進程要退出了,它的父進程(用戶態根進程)Init應該就會收到SIGTERM或SIGCHLD信號,Init進程根據 /etc/init.cfg 的配置,來決定是重啟單個進程,還是重啟整個系統,后面的事情就另說了。

[4-3] 第三階段,注冊成功,就可以繼續往下跑了,EP的狀態endpoint->running = TRUE; 標記置起來。

因為知名EP也會跑Receive() 的這些流程,但知名EP不需要跑[4-3]的RegisterRemoteFeatures(endpoint) 這一步,所以通過[4-1]獲取的endpoint->identity.handle來判斷是否是知名EP的handle,是知名EP的話,就跳過,不是的話,就調用RegisterRemoteFeatures(endpoint)來把本EP的features(也就是本EP的routers向量中的所有element)全部注冊到知名EP里去。

注冊的過程也比較簡單,就是遍歷EP->routers向量,把router在向量中的位置序號填寫到SvcIdentity identity.token,本EP的handle填寫到SvcIdentity identity.handle,連同本router的其它相關信息一并,通過IPC消息發給知名EP,并且由知名EP返回注冊成功和訪問權限策略信息,再次填寫回本EP對應的router里。

[4-4] 第四階段,接下來就StartLoop(),本EP的boss線程進入監聽IPC通信消息的狀態,如果別的進程有IPC消息發送到本EP的handle,boss線程就可以監聽到,然后調用Dispatch()函數來處理該消息。

到這里為止,系統服務的啟動和注冊就完成了,我們通過log來確認一遍上述過程。

附件log是系統用戶態進程啟動到系統穩定的log,開始是shell/apphilogcat先啟動,接著是bundle_daemon/sa_server/sensor_service這三個依賴關系相對簡單的服務啟動,它們的啟動流程也會完全符合上面的幾個步驟的,但我們還是接著前文,繼續往下分析wms_server進程的啟動。

Hi3516的SAMGR--系統服務框架子系統-8-client EP的注冊-鴻蒙HarmonyOS技術社區

上圖是wms_server進程依賴的service/feature的Init,以及main函數的[5-1]這步。接著我們跳過一大段media_server的啟動log。

Hi3516的SAMGR--系統服務框架子系統-8-client EP的注冊-鴻蒙HarmonyOS技術社區

上圖是wms_server進程啟動的[5-2]/[5-3]給service創建線程和消息隊列,開始監聽進程內部的多線程通信,這些都是前文解釋過了的。

Hi3516的SAMGR--系統服務框架子系統-8-client EP的注冊-鴻蒙HarmonyOS技術社區

上圖開始進入broadcast 服務的DEFAULT_Initialize()的流程,很明顯可以看出對應著上面分析的四個步驟。

但是SAMGR_RegisterServiceApi()內的三個步驟,只跑了前兩步,因為service和feature的SAMGR_AddRouter()這一步都是NG了,沒有router添加成功,自然就不跑第三步了,也就是說本進程中,broadcast service和feature,不對外部進程提供服務和接口。跑完這里,我打印出了當前進程的g_remoteRegister(注意{}內的地址,不同進程的g_remoteRegister的地址是不一樣的)全局變量的信息,見 DbgParse_g_remote{0x225922c8},可見還是和初始化狀態一樣的。

Hi3516的SAMGR--系統服務框架子系統-8-client EP的注冊-鴻蒙HarmonyOS技術社區

上圖開始進入WMS服務的DEFAULT_Initialize()的流程,很明顯可以看出對應著上面分析的前兩個步驟,因為“RegFeatureApi(NO Feature)”,所以就沒有后面兩步了。

因為defaultApi不為NULL,并且QueryInterface的結果(版本匹配)也是OK的,所以SAMGR_AddRouter OK,第一個router被添加到了EP里面,所以開始Listen的流程。

為當前EP{0x2247cd00}創建專門用于對外IPC通信的boss監聽線程,并開始執行Receive()入口函數的[4-1],開始兩層循環嘗試向知名EP注冊本EP,但是由于知名EP還沒有啟動,所以會得到:

  1. “[ERR][hm_liteipc] LiteIpcIoctl(IPC_SEND_RECV_MSG) ServiceManager not set!” 

這個時候的EP狀態如下:

Hi3516的SAMGR--系統服務框架子系統-8-client EP的注冊-鴻蒙HarmonyOS技術社區

有了一個router,但是handle還是 -1,需要等待,一直等到非常后面,如下圖,才會繼續執行[4-2]/[4-3],注冊EP成功并拿到handle為16,然后執行[4-4]StartLoop:

Hi3516的SAMGR--系統服務框架子系統-8-client EP的注冊-鴻蒙HarmonyOS技術社區
Hi3516的SAMGR--系統服務框架子系統-8-client EP的注冊-鴻蒙HarmonyOS技術社區

上圖是IMS服務的DEFAULT_Initialize()的流程,與WMS的類似,也可以看出因為沒有feature,只跑了前兩個步驟。因為本EP已經有boss線程在跑了,所以這里直接Listen boss線程就可以返回了。

此時的EP狀態如下圖,兩個router可以對外提供服務,handle需要等待注冊EP成功才會拿到 16 這個值。

Hi3516的SAMGR--系統服務框架子系統-8-client EP的注冊-鴻蒙HarmonyOS技術社區

接著就是下面的兩步,

  1. [wms.cpp] main[5-4]: GetInstance()->Run() 
  2.  
  3. [wms.cpp] main[5-5]: while(1) 

等EP拿到handle后,進程wms_server就可以順利對外提供服務了。

想了解更多內容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術社區

https://harmonyos.51cto.com

 

責任編輯:jianghua 來源: 鴻蒙社區
相關推薦

2021-07-08 16:16:59

鴻蒙HarmonyOS應用

2021-07-05 09:35:36

鴻蒙HarmonyOS應用

2021-07-12 09:50:39

鴻蒙HarmonyOS應用

2021-06-03 14:21:44

鴻蒙HarmonyOS應用

2021-06-10 09:25:39

鴻蒙HarmonyOS應用

2021-06-18 10:02:10

鴻蒙HarmonyOS應用

2021-06-18 15:23:59

鴻蒙HarmonyOS應用

2022-04-15 14:45:49

Hi3516系統類型燒錄鴻蒙

2021-04-09 09:45:21

鴻蒙HarmonyOS應用

2021-03-29 15:36:46

鴻蒙HarmonyOS應用

2021-07-09 14:20:23

鴻蒙HarmonyOS應用

2021-07-21 09:58:50

鴻蒙HarmonyOS應用

2022-02-16 16:01:02

Hi3516開發板鴻蒙

2021-11-09 15:28:41

鴻蒙HarmonyOS應用

2021-03-16 09:49:16

鴻蒙HarmonyOS應用

2021-05-25 14:47:43

鴻蒙HarmonyOS應用

2021-10-09 10:12:39

鴻蒙HarmonyOS應用

2022-03-14 15:26:59

Hi3516Ark子系統鴻蒙

2021-07-19 15:34:05

鴻蒙HarmonyOS應用

2021-12-03 09:50:39

鴻蒙HarmonyOS應用
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 超碰97免费 | 亚洲精品一区二区三区蜜桃久 | 亚洲精品国产第一综合99久久 | 亚洲视频精品 | 国产精品中文字幕在线 | 国产成人精品a视频一区www | 久草在线中文888 | 精品国产一区二区三区久久狼黑人 | 国产一区二区三区四区五区加勒比 | 欧美free性| 亚洲欧美在线视频 | 欧美极品一区二区 | 久草在线 | 一区二区三区四区电影视频在线观看 | 一区二区三区不卡视频 | 欧美激情国产精品 | 午夜电影福利 | 久久lu| 视频在线观看一区 | 欧美一区二区在线观看 | 二区在线视频 | 成年人在线视频 | 免费在线成人 | 91偷拍精品一区二区三区 | 91精品国产综合久久久久久丝袜 | 欧美一二三四成人免费视频 | 欧美在线视频一区 | 亚州无限乱码 | 久久久久久国产 | 精品欧美一区二区在线观看视频 | 国产日屁 | 成人福利网站 | 国际精品久久 | 成人欧美一区二区三区视频xxx | 日本一区二区不卡视频 | 日韩欧美在线观看 | 99久久99久久精品国产片果冰 | 欧美 日韩 中文 | 2021狠狠天天天 | eeuss国产一区二区三区四区 | 一级大片网站 |