[インデックス 11249] ファイルの概要
このコミットは、Go言語のnet
パッケージにおけるPlan 9オペレーティングシステム向けのネットワークソケット実装に関する修正です。具体的には、以下のファイルが変更されています。
src/pkg/net/iprawsock_plan9.go
: IP生ソケットのPlan 9実装src/pkg/net/ipsock_plan9.go
: IPソケットのPlan 9実装src/pkg/net/tcpsock_plan9.go
: TCPソケットのPlan 9実装src/pkg/net/udpsock_plan9.go
: UDPソケットのPlan 9実装src/pkg/net/unixsock_plan9.go
: UnixドメインソケットのPlan 9実装src/pkg/net/unixsock_posix.go
: UnixドメインソケットのPOSIX実装(関連する変更)
これらのファイルは、Goの標準ライブラリnet
パッケージの一部であり、Plan 9環境下でのネットワーク通信機能を提供します。
コミット
commit b58b5ba997ad5ab5b6419a575cb5829a45097fa6
Author: Mikio Hara <mikioh.mikioh@gmail.com>
Date: Thu Jan 19 12:25:37 2012 +0900
net: fix plan9 build
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5554058
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/b58b5ba997ad5ab5b6419a575cb5829a45097fa6
元コミット内容
net: fix plan9 build
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5554058
変更の背景
このコミットの主な背景は、Go言語のnet
パッケージにおけるタイムアウト処理のAPI変更と、それに対応するPlan 9ビルドの修正です。Goのnet
パッケージでは、以前はSetTimeout
, SetReadTimeout
, SetWriteTimeout
といったメソッドが提供されていましたが、これらは後にSetDeadline
, SetReadDeadline
, SetWriteDeadline
というより汎用的なAPIに置き換えられました。
SetTimeout
系のメソッドは、相対的な時間(例: 「今から5秒後」)でタイムアウトを設定するものでしたが、SetDeadline
系のメソッドは、絶対的な時刻(例: 「2025年7月10日12時00分00秒」)でタイムアウトを設定します。この変更は、タイムアウト処理をより柔軟かつ正確に制御できるようにするためのものでした。
Plan 9は、Go言語が初期からサポートしているオペレーティングシステムの一つであり、そのネットワークスタックは他のOSとは異なる特性を持っています。そのため、net
パッケージのAPI変更があった際には、Plan 9固有の実装もそれに合わせて更新する必要がありました。このコミットは、SetTimeout
からSetDeadline
へのAPI変更に伴い、Plan 9向けのネットワークソケット実装が正しくビルドされ、機能するように修正することを目的としています。
前提知識の解説
Go言語のnet
パッケージ
Go言語のnet
パッケージは、ネットワークI/Oプリミティブを提供します。TCP/IP、UDP、Unixドメインソケットなど、様々なネットワークプロトコルを扱うためのインターフェースや実装が含まれています。
net.Conn
インターフェース
net.Conn
は、ネットワーク接続を表すGoのインターフェースです。以下の主要なメソッドを定義しています。
Read(b []byte) (n int, err error)
: データを読み込みます。Write(b []byte) (n int, err error)
: データを書き込みます。Close() error
: 接続を閉じます。LocalAddr() Addr
: ローカルネットワークアドレスを返します。RemoteAddr() Addr
: リモートネットワークアドレスを返します。SetDeadline(t time.Time) error
: 読み書き両方の操作のデッドラインを設定します。SetReadDeadline(t time.Time) error
: 読み込み操作のデッドラインを設定します。SetWriteDeadline(t time.Time) error
: 書き込み操作のデッドラインを設定します。
SetTimeout
vs SetDeadline
-
SetTimeout(nsec int64) error
(旧API):- 引数
nsec
はナノ秒単位の相対時間で、その時間内に操作が完了しない場合にタイムアウトエラーを発生させます。 - このAPIは、Go 1.0のリリース後に非推奨となり、最終的に削除されました。
- 引数
-
SetDeadline(t time.Time) error
(新API):- 引数
t
はtime.Time
型で、操作が完了しなければならない絶対時刻を指定します。 time.Time{}
(ゼロ値)を渡すと、デッドラインが無効になり、タイムアウトしなくなります。SetReadDeadline
とSetWriteDeadline
は、それぞれ読み込みと書き込みに特化したデッドラインを設定します。
- 引数
SetDeadline
が導入された背景には、相対時間でのタイムアウト設定が、複数の操作にまたがる場合に累積的なタイムアウト計算を複雑にするという問題がありました。絶対時刻でデッドラインを設定することで、より直感的で正確なタイムアウト管理が可能になります。
os.EPLAN9
os.EPLAN9
は、Plan 9オペレーティングシステム固有のエラーを表すGoのエラー定数です。Plan 9では、一部のPOSIX互換の機能がサポートされていないか、異なるセマンティクスを持つ場合があります。このコミットでは、SetDeadline
系のメソッドがPlan 9環境では実際には機能しない(または実装されていない)ため、os.EPLAN9
を返すことで、その制約を明示しています。これは、Plan 9のネットワークスタックがタイムアウトの概念を直接サポートしていないためと考えられます。
Plan 9
Plan 9 from Bell Labsは、ベル研究所で開発された分散オペレーティングシステムです。Unixの後継として設計され、"Everything is a file"という哲学に基づいています。ネットワークリソースを含むすべてのリソースがファイルシステムとして表現され、アクセスされます。Go言語は、Plan 9の思想に影響を受けており、初期からPlan 9への移植性が重視されていました。
技術的詳細
このコミットの技術的詳細は、Goのnet
パッケージにおけるタイムアウトAPIの変更(SetTimeout
からSetDeadline
への移行)を、Plan 9固有のネットワークソケット実装に適用することに集約されます。
Goのnet.Conn
インターフェースは、ネットワーク接続の抽象化を提供し、その一部としてタイムアウト設定のためのメソッドを含んでいます。Goの進化の過程で、タイムアウトの概念が相対時間から絶対時刻へと変更されました。これは、より堅牢で予測可能なタイムアウト動作を実現するためです。
具体的には、以下の変更が行われています。
-
SetTimeout
系のメソッドの削除:IPConn
,plan9Conn
,TCPConn
,UDPConn
,UnixConn
といったPlan 9向けのコネクション型から、SetTimeout
,SetReadTimeout
,SetWriteTimeout
メソッドが削除されました。これらのメソッドは、Goの標準ライブラリ全体で非推奨となり、最終的に削除される方向性であったため、Plan 9の実装もそれに追従しました。 -
SetDeadline
系のメソッドの追加: 削除されたSetTimeout
系のメソッドの代わりに、SetDeadline
,SetReadDeadline
,SetWriteDeadline
メソッドが追加されました。これらのメソッドは、net.Conn
インターフェースの新しい要件を満たすために導入されました。 -
Plan 9固有のタイムアウト実装: Plan 9のネットワークスタックは、一般的なOS(Linux, Windows, macOSなど)とは異なり、ソケットレベルでの読み書きタイムアウトを直接サポートしていない場合があります。そのため、追加された
SetDeadline
系のメソッドは、すべてos.EPLAN9
エラーを返します。これは、Plan 9環境ではこれらのタイムアウト機能が利用できないことを明示するものです。これにより、GoのコードがPlan 9でビルドされた際に、タイムアウト設定が意図通りに機能しないことを開発者に伝えます。 -
time
パッケージのインポート:SetDeadline
系のメソッドはtime.Time
型を引数に取るため、関連するファイル(iprawsock_plan9.go
,ipsock_plan9.go
,tcpsock_plan9.go
,udpsock_plan9.go
,unixsock_plan9.go
)に"time"
パッケージのインポートが追加されました。 -
ドキュメントの更新:
IPConn
のWriteToIP
メソッドのコメントが、古いSetTimeout
とSetWriteTimeout
への参照から、新しいSetDeadline
とSetWriteDeadline
への参照に更新されました。これにより、APIの変更がドキュメントにも反映されています。
この変更は、Goのnet
パッケージのAPI統一性を保ちつつ、Plan 9という特定の環境における制約を適切にハンドリングするための重要なステップです。
コアとなるコードの変更箇所
このコミットでは、主に以下のファイルでSetTimeout
系のメソッドが削除され、SetDeadline
系のメソッドが追加されています。
-
src/pkg/net/iprawsock_plan9.go
:SetTimeout
,SetReadTimeout
,SetWriteTimeout
メソッドが削除されました。SetDeadline
,SetReadDeadline
,SetWriteDeadline
メソッドが追加され、すべてos.EPLAN9
を返します。"time"
パッケージがインポートされました。WriteToIP
のコメントが更新されました。
-
src/pkg/net/ipsock_plan9.go
:plan9Conn
型からSetTimeout
,SetReadTimeout
,SetWriteTimeout
メソッドが削除されました。plan9Conn
型にSetDeadline
,SetReadDeadline
,SetWriteDeadline
メソッドが追加され、すべてos.EPLAN9
を返します。"time"
パッケージがインポートされました。
-
src/pkg/net/tcpsock_plan9.go
:TCPConn
型にSetDeadline
,SetReadDeadline
,SetWriteDeadline
メソッドが追加され、すべてos.EPLAN9
を返します。"time"
パッケージがインポートされました。
-
src/pkg/net/udpsock_plan9.go
:UDPConn
型にSetDeadline
,SetReadDeadline
,SetWriteDeadline
メソッドが追加され、すべてos.EPLAN9
を返します。"time"
パッケージがインポートされました。ReadFromUDP
とWriteToUDP
のコメントが更新されました。
-
src/pkg/net/unixsock_plan9.go
:UnixConn
型からSetTimeout
,SetReadTimeout
,SetWriteTimeout
メソッドが削除されました。UnixConn
型にSetDeadline
,SetReadDeadline
,SetWriteDeadline
メソッドが追加され、すべてos.EPLAN9
を返します。"time"
パッケージがインポートされました。
-
src/pkg/net/unixsock_posix.go
:UnixListener
のSetDeadline
メソッドのコメントが、SetTimeout
からSetDeadline
への変更を反映するように更新されました。
コアとなるコードの解説
ここでは、src/pkg/net/iprawsock_plan9.go
の変更を例に、コアとなるコードの解説を行います。他のファイルでも同様のパターンで変更が適用されています。
変更前 (src/pkg/net/iprawsock_plan9.go
の一部):
// SetTimeout implements the net.Conn SetTimeout method.
func (c *IPConn) SetTimeout(nsec int64) error {
return os.EPLAN9
}
// SetReadTimeout implements the net.Conn SetReadTimeout method.
func (c *IPConn) SetReadTimeout(nsec int64) error {
return os.EPLAN9
}
// SetWriteTimeout implements the net.Conn SetWriteTimeout method.
func (c *IPConn) SetWriteTimeout(nsec int64) error {
return os.EPLAN9
}
変更後 (src/pkg/net/iprawsock_plan9.go
の一部):
import (
"os"
"time" // 新しく追加されたインポート
)
// SetDeadline implements the net.Conn SetDeadline method.
func (c *IPConn) SetDeadline(t time.Time) error {
return os.EPLAN9
}
// SetReadDeadline implements the net.Conn SetReadDeadline method.
func (c *IPConn) SetReadDeadline(t time.Time) error {
return os.EPLAN9
}
// SetWriteDeadline implements the net.Conn SetWriteDeadline method.
func (c *IPConn) SetWriteDeadline(t time.Time) error {
return os.EPLAN9
}
解説:
-
import "time"
の追加:SetDeadline
系のメソッドはtime.Time
型の引数を取るため、time
パッケージが新しくインポートされています。これにより、time.Time
型がコード内で利用可能になります。 -
SetTimeout
系のメソッドの削除: 変更前のコードにあったSetTimeout
,SetReadTimeout
,SetWriteTimeout
の3つのメソッドが完全に削除されています。これは、Goのnet
パッケージ全体でこれらの相対時間ベースのタイムアウトAPIが非推奨となり、SetDeadline
系のAPIに置き換えられたためです。 -
SetDeadline
系のメソッドの追加: 削除されたメソッドの代わりに、SetDeadline
,SetReadDeadline
,SetWriteDeadline
の3つのメソッドがIPConn
型に追加されています。これらのメソッドはnet.Conn
インターフェースの新しい定義に準拠しています。 -
return os.EPLAN9
: 追加されたすべてのSetDeadline
系のメソッドは、return os.EPLAN9
という行を含んでいます。これは、Plan 9オペレーティングシステムでは、これらのタイムアウト機能がネイティブにサポートされていないか、Goのnet
パッケージが提供する抽象化レベルでは実装が困難であることを示しています。したがって、これらのメソッドが呼び出された場合、常にos.EPLAN9
エラーが返され、タイムアウト設定が適用されないことを呼び出し元に伝えます。これは、Plan 9環境におけるGoのネットワーク機能の限界を明確にするための重要な実装です。
この変更により、Goのnet
パッケージのAPIが統一され、Plan 9環境でも最新のAPI定義に準拠するようになりました。同時に、Plan 9の特性上、タイムアウト機能が利用できないという事実も透過的に扱われています。
関連リンク
- Go CL 5554058: https://golang.org/cl/5554058
参考にした情報源リンク
- Go
net
packageSetDeadline
vsSetTimeout
: https://stackoverflow.com/questions/23720027/go-net-package-setdeadline-vs-settimeout - Go
net
package documentation: https://pkg.go.dev/net - Go
time
package documentation: https://pkg.go.dev/time - Go
os
package documentation: https://pkg.go.dev/os - Plan 9 from Bell Labs: https://9p.io/plan9/