[インデックス 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
であるかどうかをチェックし、それに応じて追加のデータを読み込むなどの処理を行うことが可能になります。
関連リンク
- Go CL 58900044: https://golang.org/cl/58900044
参考にした情報源リンク
- The "Go syscall ERROR_MORE_DATA os/fsnotify Windows" error: https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQEfM-D6u6PgmxyW_YnX12Bfm6RFgHCp3lVIJhe9-s4wBMQjeiZARs0wB6-KCxmkg5wLwAwsu4I86vCordKIsPwJoarvijijDqUgW9J4g84SmFPXjGYa0OMxf6RG0bEkVgeGOOW7SyGYBFVEGMCIXRWaL_YcMlBSdipb-MOd
fsnotify
library on GitHub: https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQFid41DN_JX9iiuxP_CatdleeGaJ6V3hoSPGLQBrJxJCnPc_vtOo-1-yxVk1eYIfVonA7cbSIwvsAB-QS2_EwvP7tVDoziASof17c37wHPosaYhackBTKnkvcZZMahEyQ==- Go
fsnotify
documentation: https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHg6m4C9IXBOfdc_oQDsaG-VmFKtk9PEJi6Po2r-d2j_1N39g6zXf-Hu8raj42qiHNevnaPwDkZmY8KhXCS8jGInZwEM-TfAOtweL00Ew2yz2FbLK1loYtX_oGJPa6w2PyX-1Bb5JJ8pme3 - Reddit discussion on
os/fsnotify
: https://vertexaisearch.cloud.google.com/grounding-api-redirect/AUZIYQHCiXsxL9zIPMlKkzW3k_7ZbSmT1mohs9_NycKiSjEQ7i6oTQBqnAd_74StY30Df-ZHx3kNCu3Bl3qSjODy7B2yuq_jjNDflRdQePNpEtqjImRziG9tlKz-WWH0vO5PM2G_bRkT3I0zoHy7JaDgG8qAIkarqq36nhtw2udJ74Chwk_jQ7jWD4U=