法楽日記

デジタル散策記&マインド探訪記

FreeBSD 11.1R: kern_socket() と falloc()

FreeBSD 11.1R の kern_socket() と kern_socketpair() は、file 構造体と file descriptor を allocate してもらうために falloc() を呼び出しています。

falloc() は sys/sys/filedesc.h で定義されているマクロ関数で、falloc_caps() の呼び出しに置換されています。falloc_caps() は sys/kern/kern_descrip.c で定義されています。

また kern_accept4() は、file 構造体と file descriptor を allocate してもらうために falloc_caps() を呼び出しています。

以下、file 構造体の reference count についてです。いつもすぐに忘れるので、備忘録として記録します。file 構造体の reference counter のメンバー名は f_count です。

falloc_caps() により allocate された file 構造体の f_count の値は 2 となっています。falloc_caps() は、まず falloc_noinstall() を呼び出して file 構造体を allocate しますが、その際に f_count の値は 1 となります。次に finstall() を呼び出して file descriptor を割り当てる際に、fhold() が呼び出されて f_count の値は 2 になります。エラーがなければ file 構造体はこのまま返されるため、正常時の f_count の値は 2 です。

f_count の値を 2 にする理由は、おそらく、filedesc 構造体から参照されていることによる reference count が 1、そして falloc_caps() を呼び出した関数内から参照されていることによる reference count が 1 で、合計 2 となっているものと思います。

そのため kern_socket() と kern_socketpair() と kern_accept4() は、関数終了時に fdrop() を呼び出して、file 構造体の f_count の値を 1 に戻しています。

なお、kern_socket() と kern_socketpair() と kern_accept4() は sys/kern/uipc_syscalls.c で定義されています。また、file 構造体は sys/sys/file.h で、filedesc 構造体は sys/sys/filedesc.h で、定義されています。fhold() と fdrop() は sys/sys/file.h で定義されたマクロ関数です。