Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 18388] ファイルの概要

このコミットは、Go言語のsyscallパッケージにおいて、Windows環境でのファイルシステムイベント監視(os/fsnotifyに関連)に必要なエラーコードERROR_MORE_DATAを追加するものです。具体的には、src/pkg/syscall/ztypes_windows.goファイルに1行の追加が行われています。

コミット

syscall: add ERROR_MORE_DATA to Windows for os/fsnotify

LGTM=alex.brainman
R=golang-codereviews, alex.brainman
CC=dave, golang-codereviews
https://golang.org/cl/58900044

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/99a1e76291068d80d027aaba8f1b451f962f1da9

元コミット内容

commit 99a1e76291068d80d027aaba8f1b451f962f1da9
Author: Nathan John Youngman <nj@nathany.com>
Date:   Fri Jan 31 17:43:46 2014 +1100

    syscall: add ERROR_MORE_DATA to Windows for os/fsnotify
    
    LGTM=alex.brainman
    R=golang-codereviews, alex.brainman
    CC=dave, golang-codereviews
    https://golang.org/cl/58900044

変更の背景

この変更は、Go言語のos/fsnotifyパッケージ(またはその前身となる機能)がWindows上でファイルシステムイベントを監視する際に、特定のシナリオで発生するERROR_MORE_DATAというWindowsシステムエラーを適切に処理できるようにするために行われました。

Windowsのファイルシステムイベント監視APIであるReadDirectoryChangesWは、イベント情報をバッファに書き込みます。もしイベントの発生頻度が高く、バッファが一度に処理できる量を超えた場合、ERROR_MORE_DATAというエラーコードが返されます。これは、バッファが満杯になったが、まだ処理すべきデータが残っていることを示します。Goのsyscallパッケージがこのエラーコードを認識し、定数として定義することで、fsnotifyのような高レベルのライブラリがこの状況を検出し、適切に対応(例えば、バッファを再読み込みする、イベントが失われた可能性を考慮する、など)できるようになります。

当時、Goの標準ライブラリにos/fsnotifyパッケージを含める計画がありましたが、特にWindows実装の複雑さから延期されました。しかし、ファイルシステムイベント監視の機能自体は必要とされており、github.com/fsnotify/fsnotifyのような外部ライブラリが広く利用されています。このコミットは、そのようなライブラリがWindows上で堅牢に動作するための基盤を強化するものです。

前提知識の解説

syscallパッケージ

Go言語のsyscallパッケージは、オペレーティングシステム(OS)の低レベルな機能にアクセスするためのインターフェースを提供します。これには、ファイル操作、プロセス管理、ネットワーク通信、そしてシステムエラーコードの定義などが含まれます。GoプログラムがOS固有のAPIを直接呼び出す必要がある場合、このパッケージが利用されます。

Errno

Errnoは、syscallパッケージで定義されているエラーコードを表す型です。これは通常、OSが返す数値のエラーコードに対応します。例えば、ファイルが見つからない場合やアクセスが拒否された場合など、様々なシステムコールが失敗した際に特定のErrno値が返されます。GoプログラムはこれらのErrno値をチェックすることで、エラーの原因を特定し、適切なエラーハンドリングを行うことができます。

ERROR_MORE_DATA

ERROR_MORE_DATAは、Windows APIで定義されているシステムエラーコードの一つで、その値は234です。このエラーは、関数が呼び出し元に提供されたバッファにすべてのデータを収めることができなかったが、まだ利用可能なデータがあることを示します。つまり、バッファが小さすぎるか、またはデータがバッファの容量を超えて生成された場合に発生します。ファイルシステムイベント監視の文脈では、ReadDirectoryChangesW関数がイベントを収集するバッファが満杯になったことを意味します。

fsnotify (ファイルシステムイベント監視)

fsnotifyは、ファイルシステム上の変更(ファイルの作成、削除、変更、名前変更など)を監視するための機能です。アプリケーションが特定のディレクトリやファイルの変更をリアルタイムで検知し、それに応じて動作するために使用されます。例えば、設定ファイルの変更を検知してアプリケーションを再起動したり、ログファイルの更新を監視したりする際に利用されます。

Windowsでは、ReadDirectoryChangesWというAPI関数がこの機能を提供します。この関数は非同期的に動作し、指定されたディレクトリ内の変更を監視し、イベントが発生するとその情報をバッファに書き込みます。

技術的詳細

このコミットの技術的詳細の核心は、Windowsのファイルシステムイベント監視メカニズムとERROR_MORE_DATAエラーの関連性にあります。

WindowsのReadDirectoryChangesW関数は、指定されたディレクトリツリー内の変更を監視し、その変更に関する情報をFILE_NOTIFY_INFORMATION構造体の配列として出力バッファに書き込みます。この関数は、非同期I/O操作として実行されることが多く、完了ポート(IOCP)やイベントオブジェクトと組み合わせて使用されます。

問題となるのは、ファイルシステムイベントが非常に高速に発生した場合です。例えば、大量のファイルが短時間で作成、変更、削除されるようなシナリオです。このとき、ReadDirectoryChangesWがイベント情報を書き込むバッファが、次のイベントが発生する前に満杯になってしまう可能性があります。

ERROR_MORE_DATA(エラーコード234)は、まさにこの状況を示すためにWindowsによって返されます。これは、ReadDirectoryChangesWがバッファに書き込めるだけのイベント情報を書き込んだが、まだ処理すべきイベントがキューに残っていることを意味します。このエラーが発生した場合、アプリケーションは通常、バッファをクリアし、再度ReadDirectoryChangesWを呼び出して残りのイベントを取得しようとします。しかし、このエラーを適切に処理しないと、ファイルシステムイベントが失われる可能性があります。

GoのsyscallパッケージにERROR_MORE_DATAを定数として追加することで、Goプログラム(特にfsnotifyのようなライブラリ)は、Windowsが返すこの特定のエラーコードを明示的に認識し、それに基づいて適切なロジックを実装できるようになります。これにより、Windows上でのファイルシステムイベント監視の堅牢性と信頼性が向上し、イベントの取りこぼしを減らすことが期待されます。

コアとなるコードの変更箇所

--- a/src/pkg/syscall/ztypes_windows.go
+++ b/src/pkg/syscall/ztypes_windows.go
@@ -20,6 +20,7 @@ const (
 	ERROR_PROC_NOT_FOUND      Errno = 127
 	ERROR_ALREADY_EXISTS      Errno = 183
 	ERROR_ENVVAR_NOT_FOUND    Errno = 203
+\tERROR_MORE_DATA           Errno = 234
 	ERROR_OPERATION_ABORTED   Errno = 995
 	ERROR_IO_PENDING          Errno = 997
 	ERROR_NOT_FOUND           Errno = 1168

コアとなるコードの解説

変更はsrc/pkg/syscall/ztypes_windows.goファイルにあります。このファイルは、Windows固有のシステムコールに関連する型定義や定数を集めたものです。

追加された行は以下の通りです。

	ERROR_MORE_DATA           Errno = 234

これは、ERROR_MORE_DATAという名前の定数を定義し、その型をErrnoとし、値としてWindowsシステムエラーコードの234を割り当てています。

この定義により、Goプログラムはsyscall.ERROR_MORE_DATAというシンボリックな名前を使って、Windowsが返すエラーコード234を参照できるようになります。これにより、コードの可読性が向上し、マジックナンバー(直接的な数値)を使うことによるエラーや混乱を防ぐことができます。fsnotifyのようなライブラリは、ReadDirectoryChangesWの呼び出し結果として返されるエラーがsyscall.ERROR_MORE_DATAであるかどうかをチェックし、それに応じて追加のデータを読み込むなどの処理を行うことが可能になります。

関連リンク

参考にした情報源リンク