[インデックス 11888] ファイルの概要
このコミットは、Go言語の標準ライブラリであるnet
パッケージにおけるWindowsビルドの不具合を修正するものです。具体的には、ファイルディスクリプタの参照カウント管理に関連するコードと、エラーハンドリングの一部が修正されています。
コミット
- コミットハッシュ:
8c4fecdcb9abdd7cc6b4b0e97fad936c87ddb4c0
- Author: Mikio Hara mikioh.mikioh@gmail.com
- Date: Tue Feb 14 14:57:57 2012 +0900
- コミットメッセージ:
net: fix windows build R=rsc, bradfitz CC=golang-dev https://golang.org/cl/5661055
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/8c4fecdcb9abdd7cc6b4b0e97fad936c87ddb4c0
元コミット内容
net: fix windows build
R=rsc, bradfitz
CC=golang-dev
https://golang.org/cl/5661055
変更の背景
このコミットは、Go言語のnet
パッケージがWindows環境で正しくビルドされない、または実行時に問題が発生する可能性があったため、その不具合を修正するために行われました。特に、ファイルディスクリプタ(netFD
)の参照カウント管理(incref
/decref
)の呼び出し方や、エラー返却値の型がWindows固有の挙動と合致していなかったことが原因と考えられます。
前提知識の解説
net
パッケージ: Go言語の標準ライブラリで、ネットワークI/O機能を提供します。TCP/UDP通信、HTTPクライアント/サーバーなどが含まれます。- ファイルディスクリプタ (File Descriptor, FD): オペレーティングシステムがファイルやソケットなどのI/Oリソースを識別するために使用する抽象的なハンドルです。Goの
net
パッケージでは、ネットワーク接続をnetFD
という構造体で抽象化し、その内部でOSのファイルディスクリプタを管理しています。 - 参照カウント (Reference Counting): オブジェクトがどれだけの場所から参照されているかを数えるメモリ管理の手法の一つです。参照カウントが0になると、そのオブジェクトは不要と判断され、解放されます。Go言語では主にガベージコレクションがメモリ管理に用いられますが、特定のOSリソース(ファイルディスクリプタなど)のライフサイクル管理には、参照カウントのようなメカニズムが用いられることがあります。
incref
とdecref
:incref
は参照カウントをインクリメント(増加)し、decref
はデクリメント(減少)する関数です。これにより、リソースが使用されている間は解放されないようにし、使用されなくなったら安全に解放できるようにします。pollserver
: Goのnet
パッケージ内部で、ノンブロッキングI/O操作を効率的に処理するためのポーリングメカニズムです。OSのI/O多重化機能(例: Linuxのepoll、WindowsのI/O Completion Ports)を抽象化し、複数のネットワーク操作を同時に監視・処理します。pollserver.Lock()
とpollserver.Unlock()
は、このポーリングメカニズムへのアクセスを同期するためのロックです。syscall.Sockaddr
: オペレーティングシステムのシステムコールで使用されるソケットアドレス構造体を抽象化したものです。nil
と0
: Go言語では、ポインタやインターフェースのゼロ値はnil
です。数値型(例:int
)のゼロ値は0
です。エラーを返す際に、ポインタ型の戻り値(例:*netFD
)に対してはnil
を、数値型に対しては0
を返すのが一般的です。
技術的詳細
このコミットは、主に以下の3つのファイルに対する変更を含んでいます。
-
src/pkg/net/fd.go
:netFD
構造体内のsysmu
とsysref
フィールドのコメント行のインデントが修正されました。これはコードの可読性向上のための整形変更であり、機能的な変更ではありません。netFD.Close()
メソッド内でpollserver.Lock()
のコメントが修正されました。これも整形変更です。
-
src/pkg/net/fd_windows.go
:errors
パッケージがインポートに追加されました。これは、netFD.accept()
メソッドでエラーを返す際にnil
を使用するために必要となります。netFD.accept()
メソッドの戻り値の型が変更されました。以前はエラー時に0
を返していましたが、*netFD
型の戻り値に対してはnil
を返すように修正されました。これはGoの慣習に沿った変更であり、特にWindows環境でのポインタの扱いに関連する問題を防ぐ可能性があります。
-
src/pkg/net/sendfile_windows.go
:sendFile
関数内でc.incref()
の呼び出しがc.incref(false)
に変更されました。incref
関数は引数としてブール値を取るように定義されており、この変更により正しい引数が渡されるようになりました。これにより、参照カウントの管理がWindows環境で正しく行われるようになります。
これらの変更は、Goのnet
パッケージがWindows上で安定して動作するための重要な修正です。特に、参照カウントの適切な管理と、Goの型システムに合わせたエラーハンドリングの修正が中心となっています。
コアとなるコードの変更箇所
src/pkg/net/fd.go
--- a/src/pkg/net/fd.go
+++ b/src/pkg/net/fd.go
@@ -18,9 +18,9 @@ import (
// Network file descriptor.
type netFD struct {
// locking/lifetime of sysfd
- sysmu sync.Mutex
- sysref int
-
+ sysmu sync.Mutex
+ sysref int
+
// must lock both sysmu and pollserver to write
// can lock either to read
closing bool
@@ -376,7 +376,7 @@ func (fd *netFD) decref() {
}
func (fd *netFD) Close() error {
- pollserver.Lock() // needed for both fd.incref(true) and pollserver.Evict
+ pollserver.Lock() // needed for both fd.incref(true) and pollserver.Evict
defer pollserver.Unlock()
if err := fd.incref(true); err != nil {
return err
src/pkg/net/fd_windows.go
--- a/src/pkg/net/fd_windows.go
+++ b/src/pkg/net/fd_windows.go
@@ -5,6 +5,7 @@
package net
import (
+ "errors"
"io"
"os"
"runtime"
@@ -518,7 +519,7 @@ func (o *acceptOp) Name() string {
func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (*netFD, error) {
if err := fd.incref(false); err != nil {
- return 0, err
+ return nil, err
}
defer fd.decref()
src/pkg/net/sendfile_windows.go
--- a/src/pkg/net/sendfile_windows.go
+++ b/src/pkg/net/sendfile_windows.go
@@ -50,7 +50,7 @@ func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) {
c.wio.Lock()
defer c.wio.Unlock()
- if err := c.incref(); err != nil {
+ if err := c.incref(false); err != nil {
return 0, err, true
}
defer c.decref()
コアとなるコードの解説
-
src/pkg/net/fd.go
の変更:netFD
構造体内のsysmu
とsysref
のコメントのインデントが修正されました。これはコードの整形であり、機能的な影響はありません。netFD.Close()
内のpollserver.Lock()
のコメントも同様に整形です。
-
src/pkg/net/fd_windows.go
の変更:import ("errors")
の追加:netFD.accept()
関数内でエラー時にnil
を返すために、errors
パッケージが必要になりました。return 0, err
からreturn nil, err
への変更:netFD.accept()
は*netFD
型のポインタを返すため、エラー時にはポインタのゼロ値であるnil
を返すのがGoの慣習です。以前の0
は数値のゼロ値であり、型が合致しない可能性がありました。この修正により、型安全性が向上し、Windows環境での潜在的なバグが修正されます。
-
src/pkg/net/sendfile_windows.go
の変更:c.incref()
からc.incref(false)
への変更:incref
関数は引数としてブール値を受け取るように定義されています。以前の呼び出しでは引数が不足しており、コンパイルエラーや予期せぬ動作を引き起こす可能性がありました。false
を明示的に渡すことで、incref
の正しい使用法に準拠し、参照カウントの管理が適切に行われるようになります。これは特にWindows環境でのsendfile
操作の安定性に寄与します。
これらの変更は、Goのnet
パッケージがWindows環境でより堅牢に動作するための、細かではあるが重要な修正です。
関連リンク
- Go CL 5661055: https://golang.org/cl/5661055
参考にした情報源リンク
- Web search results for "Go net package incref decref 2012":
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFkqoNqV0QdTnryrejf43Nzz49b5NTkf11stIBw5Ka7hH1GTjizV2UysftvDlV-FCTv0set1v3ABi-28flfifRNpNGy5sK2mFnz004shJClBdPUaECuAiNxb2oaT8Gj_RUK-bYARCumnIbI-MCc5sbVX0lc3_UqIuFx1-I0GAOPF3YPY8Bevy9XB-AiF7iaUfZzqjxRz1HR59csGPhZUteT5uC5_W6MGA==
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQGmCscW1hgdT4JaBckjss0eAWGsD2-9nGDRtVXmquT_q0N_ZOe-SBAv--vPKoSqOHn5R_fJ41cVfDyfmk4YA_SJccl7dl9S5SWGczu3DEypkO9boFWJK0nBXKOyJv5rulo8Vubi4o9Wt1uNor9_ZGJ9KgBzHh8E-_7JLw9NAloPXZlX-UYlosmBCyAboIltuaOQwQOyIgs=
- https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHvrJheMJD4Vb150P1HXa-OZ_2IKUktJfFpfka_gI7HVRjXCaLTIg6_3KmCVxbuywCjd9fF83bSXKRFU-NGNEe7pMPTrQudycy0JCd04Zq6feinYGaOnVIP4ch9Q02XCL6cqieDjQfo