要約
- Windows Sockets 1.1は、Windowsの開発者にBerkeley型のTCP/IPインターフェースを提供したが、Berkeleyのブロッキング動作を16ビットWindowsへそのまま移すことはできなかった。
- ブロック中のWinsock呼び出しもWindowsのメッセージを配信し続ける必要があった。協調型のデスクトップは応答を保てた一方、入れ子呼び出し、再入、バッファーの寿命には厳しい制限が生じた。
ソケット呼び出しはネットワークを隠すはずだった
ソケットは、基盤となるネットワークスタックのベンダーを意識せずにデータを送受信できる、安定した手段をアプリケーションに与える。Windowsの開発者が望んだのは、その利点だった。同時に、すでにUnixのTCP/IPプログラミングで標準的だったBerkeleyのソケットモデルを出発点にしたかった。
Windows Socketsプロジェクトは、1991年10月10日にサンノゼで開かれたInterop ’91のBirds of a Featherセッションから始まった。1.1仕様にはその後の経緯が記されている。委員会が設けられ、メールで議論が続き、JSBとNetManageの提案を大きく取り入れた草案が作られ、12月にはMicrosoft主催の会合が開かれ、その後も作業部会が文書を練った。これはグループで作ったインターフェースであり、単一ベンダーが押し付けたTCP/IPプロトコルではない。
1.0は、ネットワークソフトウェアの供給者とアプリケーション開発者が共通の約束に沿って実装やプログラムを作り始められるよう公開された。1993年1月20日付の1.1は、1.0を実装した複数企業の経験を踏まえ、明確化と小さな修正を加えた。この順序が重要だ。次の版の文面を固める前に、仕様はすでにコードとの照合を受けていた。
仕様は、Unixのプログラマーにとって親しみやすく、ソースコードの移植を簡単にするためBerkeleyのソケットモデルを採用した。対象はInternetプロトコルスイートで、TCPのストリームソケットとUDPのデータグラムソケットを定義した。1.1があらゆるネットワークを標準化したかのようには装わなかった。この境界は有用だった。開発者には見慣れたインターフェースを渡し、その下にあるすべてのシステムが同じように動くとは約束しなかった。
そこへrecvと16ビットのデスクトップが出会う
難所はプログラムが待つときに現れる。ブロッキング型のrecvは、データが届くか、処理が別の形で解決するまで戻らない。プリエンプティブ・スケジューリングを行うOSなら、プロセスの待ち時間に別の仕事を実行できる。Windows Sockets 1.1は、16ビットWindowsがその方式だとは想定できなかった。
Microsoftの文書は、その回避策を細かく説明している。ブロッキング操作がすぐに完了しない場合、サービスプロバイダーは操作を開始し、ループに入る。Windowsのメッセージを配信し、ソケット呼び出しが完了したかを調べ、また繰り返す。ネットワーク読み取りが保留中でも、メッセージ駆動型のアプリケーションはウィンドウの処理を続けられた。
この仕組みで16ビットのプログラムがプリエンプティブなプロセスに変わったわけではない。プログラマーが単なる待ち時間だと思いかねない呼び出しに、Windowsのメッセージ配信を挟み込んだ。待ちの最中に届いたメッセージによって、アプリケーションが別のWinsock呼び出しを試みることもある。1.1はその入れ子を禁じた。一つのタスクが保留できるWinsock関数呼び出しは一つだけで、さらに入れ子にした呼び出しはWSAEINPROGRESSで失敗した。
APIには二つの小さな逃げ道もあった。WSAIsBlockingは呼び出しがブロック中かを調べ、WSACancelBlockingCallは取り消すための関数だった。複数のドキュメントウィンドウを使うような複雑なアプリケーションでは、WSASetBlockingHookを設定して標準のメッセージ配信処理を置き換えられた。制御権はアプリケーションに渡る。その分、メッセージ処理の正しさもアプリケーション側の仕事になった。
インターフェースは仕事を移した。消したわけではない
ノンブロッキングや非同期の呼び出しなら、ブロッキングフックの再入問題は避けられる。代わりに別の責任が生まれる。操作がバッファーなどのメモリーオブジェクトへのポインターを保持するなら、完了するまでアプリケーションがそのオブジェクトを有効なまま保たなければならない。ネットワークライブラリーが代わりに寿命を決めることはできなかった。
見慣れたAPIと移植可能なプログラムの間には、小さいが重要な隙間がある。関数名がそろえば、移植を始める費用は下げられる。だが、ホストのスケジューリング方式、メッセージループ、メモリーの寿命までは消えない。Microsoftは後に、BSDのソースコードを移植しやすくするためのヘッダーファイルを記録した。Winsock 2がWinsock2.hを導入した後も、旧アプリケーションとの互換性のためWinsock.hの宣言は残された。互換性そのものが、引き継いで保守するソフトウェアになった。
1.1の境界はインターフェースと、そこで定義したTCP/IPソケットの種類に引かれた。実装は各ベンダーが用意し、待ち方、取り消し方、メッセージの配信、メモリーの保護はアプリケーション開発者が選んだ。共通仕様はそれらの部品をつなぎやすくした。責任を互いに置き換えられるものにはしなかった。
目を引く設計上の判断は、WindowsがBerkeleyをコピーしたことではない。作業部会は、移植を魅力的にするだけのBerkeleyの語彙を残しつつ、WindowsがUnixのふりをできない場所を文書にした。メッセージループは領収書だった。オープンなインターフェースが一つの費用を下げ、次の費用がどこへ落ちたかをはっきり示した。
出典
会員向け解説
プロフィールの詳細
適切な会員レベルでログインすると、解説全文と出典メモをご覧いただけます。
ストラテジックサークル限定
Strategic Circle
すべての読者に公開されています。参加してログインすると プロフィール解説 を閲覧できます。
Strategic Circle に参加Leadership Alliance 会員限定
Leadership Alliance
対象となる IP 資産の所有者・管理者向けです。ログインすると Leadership Alliance の解説を閲覧できます。
Leadership Alliance に参加





