Androidを支える技術<II>輪読会 5.2.4
日付:2024/3/15
章:5.2.4
調査者:iNoma.icon
章のまとめ
どんな内容が書かれているか?
runSelectLoop()メソッド処理概要
ZygoteInitクラスのmain()メソッドを概観すると、大きく4つの処理をしているのだった
preload()で共有したいクラスを全てロード
SystemServerプロセスを起動
runSelectLoop()でソケットを待ち、メッセージを処理
MethodAndArgsCallerがthrowされたらcatchして引数のメソッドを呼ぶ
コード概要
code:runSelectLoop.java
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
// selectで待つソケットのディスクリプタの配列
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
// Zygoteのクライアントとのコネクションの配列
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
// ❶sServerSocketはinit.rcで作った"zygote"というファイル名のソケット
fds.add(sServerSocket.getFileDescriptor());
peers.add(null);
// 無限ループ。ネットワークの例外と子プロセスのthrowを除き、
// このループから出ることはない
while (true) {
int index;
// ❷ソケットをselectで待つ
index = selectReadable(fds);
if (index < 0) {
throw new RuntimeException("Error in select()");
} else if (index == 0) {
// ❸index==0は最初に登録したsServerSocket。
// この時はacceptを呼び、
ZygoteConnection newPeer = new ZygoteConnection(sServerSocket.accept(), abiList);
peers.add(newPeer);
// 得られたソケットをfdsに追加
fds.add(newPeer.getFileDescriptor());
} else {
// ❹indexが0より大きい場合。
// 0より大きいソケットとは、上の❸でacceptして得られたソケット。
// つまり、ZygoteConnectionに対応したソケットがselectで返ってきたということ。
// このソケットからやってくるメッセージを対応するZygoteConnectionに
// 処理させてソケットを閉じる
boolean done;
done = peers.get(index).runOnce();
if (done) {
peers.remove(index);
fds.remove(index);
}
}
}
}
何をやっているか?
ループの中で、、
fds(ファイルディスクリプタセット)の配列の0番目にzygoteのソケットを登録
selectReadable()によってfdsのソケットを監視
監視対象がread可能になるまで待機
read可能なソケットを見つけたらそのインデックスが返ってくる
index==0のとき
新規クライアントからの接続要求を示す
accept()によって通信用のソケットを得て、fdsの1番目以降に追加
iNoma.iconどういうこと??
p56のコラムを参照
サーバーソケットのlisten()とaccept()の話
通信が確立され、実際に通信するまで複数の異なるソケットを使う
接続を待つために使うソケット(listenに渡すソケット)
通信に使うソケット(accept()によって得られるソケット)
ZygoteConnectionクラスのインスタンスをpeersに追加
index>0のとき
クライアントからのデータが届いたことを示す
ソケットに対応したZygoteConnectionのrunOnce()を呼び出す
一番やりたいことはこれ
内部(詳しくは5.2.5)
プロセスをfork
指定されたuidにsetuid()
指定されたクラスをロードしてmain()メソッドを実行
runOnce()が終了したら、このソケットをselect()の監視対象から外す
応用
code:sample.kt
質疑応答