+.\" Copyright (C) 2008 Michael Kerrisk <mtk.manpages@gmail.com>
+.\" starting from a version by Davide Libenzi <davidel@xmailserver.org>
+.\"
+.\" This program is free software; you can redistribute it and/or modify
+.\" it under the terms of the GNU General Public License as published by
+.\" the Free Software Foundation; either version 2 of the License, or
+.\" (at your option) any later version.
+.\"
+.\" This program is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program; if not, write to the Free Software
+.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+.\" MA 02111-1307 USA
+.\"
+.\" 2008-10-10, mtk: describe eventfd2(), and EFD_NONBLOCK and EFD_CLOEXEC
+.\"
+.\"*******************************************************************
+.\"
+.\" This file was generated with po4a. Translate the source file.
+.\"
+.\"*******************************************************************
+.TH EVENTFD 2 2010\-08\-30 Linux "Linux Programmer's Manual"
+.SH 名前
+eventfd \- イベント通知用のファイルディスクリプタを生成する
+.SH 書式
+\fB#include <sys/eventfd.h>\fP
+.sp
+\fBint eventfd(unsigned int \fP\fIinitval\fP\fB, int \fP\fIflags\fP\fB);\fP
+.SH 説明
+\fBeventfd\fP() は "eventfd オブジェクト" を生成する。 eventfd
+オブジェクトはユーザ空間アプリケーションがイベント待ち受け/通知用の 仕組みとして使うことができる。また、カーネルがユーザ空間アプリケーションに
+イベントを通知するためにも使うことができる。 このオブジェクトには、unsigned の 64 ビット整数 (\fIuint64_t\fP)
+型のカウンタが含まれており、このカウンタはカーネルにより管理される。 このカウンタは \fIinitval\fP 引き数で指定された値で初期化される。
+
+以下の値のいくつかをビット単位の論理和 (OR) で指定することで、
+\fBeventfd\fP() の振舞いを変更することができる。
+.TP
+\fBEFD_CLOEXEC\fP (Linux 2.6.27 以降)
+新しいファイルディスクリプタに対して close\-on\-exec (\fBFD_CLOEXEC\fP) フラグをセットする。
+このフラグが役に立つ理由については、 \fBopen\fP(2) の \fBO_CLOEXEC\fP フラグの説明を参照のこと。
+.TP
+\fBEFD_NONBLOCK\fP (Linux 2.6.27 以降)
+新しく生成されるオープンファイル記述 (open file description) の \fBO_NONBLOCK\fP
+ファイルステータスフラグをセットする。 このフラグを使うことで、 \fBO_NONBLOCK\fP をセットするために \fBfcntl\fP(2)
+を追加で呼び出す必要がなくなる。
+.TP
+\fBEFD_SEMAPHORE\fP (Linux 2.6.30 以降)
+新しいファイルディスクリプタからの読み出しにおいて、セマフォ風の動作を行う。
+下記参照。
+.PP
+バージョン 2.6.26 以前の Linux では、 \fIflags\fP 引き数は未使用であり、0 を指定しなければならない。
+
+\fBeventfd\fP() は eventfd オブジェクトを参照するのに使用できる新しいファイルディスクリプタ
+を返す。返されたファイルディスクリプタに対しては以下の操作を実行できる。
+.TP
+\fBread\fP(2)
+\fBread\fP(2) は成功すると、8 バイトの整数を返す。
+渡されたバッファの大きさが 8 バイト未満の場合、
+\fBread\fP(2) はエラー \fBEINVAL\fP で失敗する。
+.IP
+\fBread\fP(2) が返す値は、ホストバイトオーダ、つまり
+そのホストマシンにおける整数の通常のバイトオーダである。
+.IP
+\fBread\fP(2) の動作は、 eventfd カウンタの現在の値が 0 以外であるかと、
+eventfd ファイルディスクリプタを作成する際に \fBEFD_SEMAPHORE\fP フラグが
+指定されたか、により変化する。
+.RS
+.IP * 3
+\fBEFD_SEMAPHORE\fP が指定されておらず、eventfd カウンタが 0 以外の値
+の場合、 \fBread\fP(2) はカウンタ値を格納した 8 バイトの値を返し、
+カウンタ値は 0 にリセットされる。
+.IP *
+\fBEFD_SEMAPHORE\fP が指定されていて eventfd カウンタが 0 以外の値の場合、
+\fBread\fP(2) は値 1 の 8 バイト値を返し、カウンタ値は 1 減算される。
+.IP *
+\fBread\fP(2) を呼び出した時点で eventfd カウンタが 0 の場合、 \fBread\fP(2)
+はカウンタが 0 以外になるまで停止 (block) する (0 以外になった時点で
+\fBread\fP(2) は上記で述べた通り実行を再開する)、 もしくはファイルディスク
+リプタが非停止 (nonblocking) に設定されている場合はエラー \fBEAGAIN\fPで
+失敗する。
+.RE
+.TP
+\fBwrite\fP(2)
+\fBwrite\fP(2) は、引き数のバッファで渡された 8 バイトの整数値をカウンタに加算する。 カウンタに格納可能な最大値は unsigned の
+64 ビット整数の最大値から 1 を引いた値 (すなわち 0xfffffffffffffffe) である。
+加算を行うとカウンタ値が最大値を超過する場合には、 そのファイルディスクリプタに対して \fBread\fP(2) が実行されるまで、
+\fBwrite\fP(2) は停止 (block) する、 もしくはファイルディスクリプタが非停止 (nonblocking)
+に設定されている場合はエラー \fBEAGAIN\fP で失敗する。
+.IP
+渡されたバッファの大きさが 8 バイト未満の場合、もしくは 値 0xffffffffffffffff を書き込もうとした場合、 \fBwrite\fP(2)
+はエラー \fBEINVAL\fP で失敗する。
+.TP
+\fBpoll\fP(2), \fBselect\fP(2) (と同様の操作)
+返されたファイルディスクリプタは、 \fBpoll\fP(2) (\fBepoll\fP(7) も同じ) や \fBselect\fP(2)
+をサポートしており、以下のような動作をする。
+.RS
+.IP * 3
+カウンタが 0 より大きい値の場合、 ファイルディスクリプタは読み出し可能となる (\fBselect\fP(2) の \fIreadfds\fP 引き数や
+\fBpoll\fP(2) の \fBPOLLIN\fP フラグ)。
+.IP *
+少なくとも値 "1" を、停止 (block) を伴わずに書き込める場合、 ファイルディスクリプタは書き込み可能となる (\fBselect\fP(2) の
+\fIwritefds\fP 引き数や \fBpoll\fP(2) の \fBPOLLOUT\fP フラグ)。
+.IP *
+カウンタ値のオーバーフローが検出された場合、 \fBselect\fP(2) はファイルディスクリプタは読み出し可能と書き込み可能の両方を通知し、
+\fBpoll\fP(2) は \fBPOLLERR\fP イベントを返す。 上述の通り、 \fBwrite\fP(2)
+でカウンタがオーバーフローすることは決してない。 しかしながら、 KAIO サブシステムによって 2^64 回の eventfd "signal
+posts" が 実行された場合にはオーバーフローが起こり得る (理論的にはあり得るが、実用的にはあり得ない)。 オーバーフローが発生した場合、
+\fBread\fP(2) は \fIuint64_t\fP の最大値 (すなわち 0xffffffffffffffff) を返す。
+.RE
+.IP
+eventfd ファイルディスクリプタは、これ以外のファイルディスクリプタ 多重 API である \fBpselect\fP(2), \fBppoll\fP(2),
+\fBepoll\fP(7) もサポートしている。
+.TP
+\fBclose\fP(2)
+ファイルディスクリプタがそれ以降は必要なくなった際には、クローズすべきである。 同じ eventfd
+オブジェクトに関連付けられたファイルディスクリプタが全て クローズされると、そのオブジェクト用の資源がカーネルにより解放される。
+.PP
+\fBfork\fP(2) で生成された子プロセスは、 \fBeventfd\fP() で生成されたファイル
+ディスクリプタのコピーを継承する。 複製されたファイルディスクリプタは同
+じ eventfd オブジェクトに関連付けられる。
+close\-on\-exec フラグが設定されていない場合、 \fBexecve\fP(2) の前後で
+\fBeventfd\fP() で生成されたファイルディスクリプタは保持される。
+.SH 返り値
+成功すると、 \fBeventfd\fP() は新規の eventfd ファイルディスクリプタを返す。 エラーの場合、\-1 を返し、 \fIerrno\fP
+にエラーを示す値を設定する。
+.SH エラー
+.TP
+\fBEINVAL\fP
+\fIflags\fP にサポートされていない値が指定された。
+.TP
+\fBEMFILE\fP
+オープン済みのファイルディスクリプタの数がプロセスあたりの上限に 達していた。
+.TP
+\fBENFILE\fP
+オープン済みのファイル総数がシステム全体の上限に達していた。
+.TP
+\fBENODEV\fP
+.\" Note from Davide:
+.\" The ENODEV error is basically never going to happen if
+.\" the kernel boots correctly. That error happen only if during
+.\" the kernel initialization, some error occur in the anonymous
+.\" inode source initialization.
+(カーネル内の) 無名 inode デバイスをマウントできなかった。
+.TP
+\fBENOMEM\fP
+新しい eventfd ファイルディスクリプタを生成するのに十分なメモリがなかった。
+.SH バージョン
+.\" eventfd() is in glibc 2.7, but reportedly does not build
+\fBeventfd\fP() はカーネル 2.6.22 以降の Linux で利用可能である。 正しく動作する glibc 側のサポートはバージョン
+2.8 以降で提供されている。 \fBeventfd2\fP() システムコール (「注意」参照) は カーネル 2.6.27 以降の Linux
+で利用可能である。 バージョン 2.9 以降では、glibc の \fBeventfd\fP() のラッパー関数は、カーネルが対応していれば
+\fBeventfd2\fP() システムコールを利用する。
+.SH 準拠
+\fBeventfd\fP() と \fBeventfd2\fP() は Linux 固有である。
+.SH 注意
+アプリケーションは、パイプをイベントを通知するためだけに使用している 全ての場面において、パイプの代わりに eventfd ファイルディスクリプタを
+使用することができる。 eventfd ファイルディスクリプタを使う方が、パイプを使う場合に比べて
+カーネルでのオーバヘッドは比べるとずっと小さく、ファイルディスクリプタも 一つしか必要としない (パイプの場合は二つ必要である)。
+
+.\" or eventually syslets/threadlets
+カーネル内で使用すると、eventfd ファイルディスクリプタは カーネル空間とユーザ空間のブリッジ機能を提供することができ、 例えば KAIO
+(kernel AIO) のような機能が、あるファイルディスクリプタに何らかの操作が完了したことを 通知することができる。
+
+eventfd ファイルディスクリプタの重要な点は、 eventfd ファイルディスクリプタが \fBselect\fP(2), \fBpoll\fP(2),
+\fBepoll\fP(7) を使って他のファイルディスクリプタと全く同様に監視できる点である。 このことは、アプリケーションは「従来の
+(traditional)」 ファイルの状態変化と eventfd インタフェースをサポートする他のカーネル機構の状態変化を同時に監視
+できることを意味する (\fBeventfd\fP() インタフェースがない時には、これらのカーネル機構は \fBselect\fP(2),
+\fBpoll\fP(2), \fBepoll\fP(7) 経由で多重することはできなかった)。
+.SS "下層にある Linux のシステムコール"
+下層にある Linux システムコールは二種類あり、 \fBeventfd\fP() と、もっと新しい \fBeventfd2\fP() である。
+\fBeventfd\fP() は \fIflags\fP 引き数を実装していない。 \fBeventfd2\fP() では上記の値の \fIflags\fP
+が実装されている。 glibc のラッパー関数は、 \fBeventfd2\fP() が利用可能であれば、これを使用する。
+.SS "glibc の追加機能"
+GNU C ライブラリは、eventfd ファイルディスクリプタの読み出しと書き込みに
+を関する詳細のいくつか抽象化するために、一つの型と、二つの関数を追加で 定義している。
+.in +4n
+.nf
+
+typedef uint64_t eventfd_t;
+
+int eventfd_read(int fd, eventfd_t *value);
+int eventfd_write(int fd, eventfd_t value);
+.fi
+.in
+
+これらの関数は、eventfd ファイルディスクリプタに対する読み出しと 書き込みの操作を実行し、正しいバイト数が転送された場合には 0
+を返し、そうでない場合は \-1 を返す。
+.SH 例
+.PP
+以下のプログラムは eventfd ファイルディスクリプタを生成し、 その後 fork を実行して子プロセスを生成する。 親プロセスが少しの間
+sleep する間に、子プロセスは プログラムのコマンドライン引き数で指定された整数(列)をそれぞれ eventfd ファイルディスクリプタに書き込む。
+親プロセスは sleep を完了すると eventfd ファイルディスクリプタから 読み出しを行う。
+
+以下に示すシェルセッションにこのプログラムの使い方を示す。
+.in +4n
+.nf
+
+$\fB ./a.out 1 2 4 7 14\fP
+Child writing 1 to efd
+Child writing 2 to efd
+Child writing 4 to efd
+Child writing 7 to efd
+Child writing 14 to efd
+Child completed write loop
+Parent about to read
+Parent read 28 (0x1c) from efd
+.fi
+.in
+.SS プログラムのソース
+\&
+.nf
+#include <sys/eventfd.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h> /* Definition of uint64_t */
+
+#define handle_error(msg) \e
+ do { perror(msg); exit(EXIT_FAILURE); } while (0)
+
+int
+main(int argc, char *argv[])
+{
+ int efd, j;
+ uint64_t u;
+ ssize_t s;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s <num>...\en", argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ efd = eventfd(0, 0);
+ if (efd == \-1)
+ handle_error("eventfd");
+
+ switch (fork()) {
+ case 0:
+ for (j = 1; j < argc; j++) {
+ printf("Child writing %s to efd\en", argv[j]);
+ u = strtoull(argv[j], NULL, 0);
+ /* strtoull() allows various bases */
+ s = write(efd, &u, sizeof(uint64_t));
+ if (s != sizeof(uint64_t))
+ handle_error("write");
+ }
+ printf("Child completed write loop\en");
+
+ exit(EXIT_SUCCESS);
+
+ default:
+ sleep(2);
+
+ printf("Parent about to read\en");
+ s = read(efd, &u, sizeof(uint64_t));
+ if (s != sizeof(uint64_t))
+ handle_error("read");
+ printf("Parent read %llu (0x%llx) from efd\en",
+ (unsigned long long) u, (unsigned long long) u);
+ exit(EXIT_SUCCESS);
+
+ case \-1:
+ handle_error("fork");
+ }
+}
+.fi
+.SH 関連項目
+\fBfutex\fP(2), \fBpipe\fP(2), \fBpoll\fP(2), \fBread\fP(2), \fBselect\fP(2),
+\fBsignalfd\fP(2), \fBtimerfd_create\fP(2), \fBwrite\fP(2), \fBepoll\fP(7),
+\fBsem_overview\fP(7)
+.SH この文書について
+この man ページは Linux \fIman\-pages\fP プロジェクトのリリース 3.41 の一部
+である。プロジェクトの説明とバグ報告に関する情報は
+http://www.kernel.org/doc/man\-pages/ に書かれている。