kqueue

명칭
     kqueue, kevent — 커널 이벤트 통지 메카니즘

프로그램 라이브러리
     Standard C Library (libc, -lc)

서식
     <sys/types.h> <sys/event.h> <sys/time.h> int kqueue(void) int kevent(int
     kq, const struct kevent *changelist, int nchanges, struct kevent
     *eventlist, int nevents, const struct timespec *timeout) EV_SET(&kev,
     ident, filter, flags, fflags, data, udata)

해설
     kqueue() (은)는, 필터로 불리는 작은 커널 코드의 실행 결과에 근거해, 이벤트의 발생이나 있는 상태의 성립을 유저에게 통지하는
     일반적인 방법을 제공합니다.  kevent 는 (ident, filter)의 페어에 의해 식별됩니다.  여기서, ident 는 식별자,
     filter 는 필터를 나타냅니다.  1 개의 kqueue 에는, 같은 kevent 가 복수 존재할 수 없습니다.

     필터는, kevent 의 초기 등록시에 이전부터 존재한 상태를 검출하기 위해서 실행됩니다.  또, 어느 이벤트가 평가를 위해서(때문에)
     필터에게 건네질 때마다 실행됩니다.  상태를 보고 해야 한다고 필터가 결정되었을 경우에는, 그 kevent 는 유저가 회수할 수
     있도록(듯이) kqueue 에 놓여집니다.

     유저가 kqueue 로부터 kevent 를 회수하려고 했을 때에도, 필터가 실행됩니다.  필터의 실행에 의해, 그 이벤트를 방아쇠 한
     상태가 성립하고 있지 않는 것 하지만 나타났을 경우에는, 그 kevent 는 kqueue 로부터 삭제되어 유저에게 건네지지 않습니다.

     필터를 방아쇠 하는 이벤트가 다수 있는 경우에서도, kqueue 안에 kevent 가 복수 놓여지는 것은 아닙니다.  대신에, 필터는
     복수의 이벤트를 단일의 kevent 구조체에 모읍니다.  파일 기술자에 대한다 close() 의 호출은, 그 기술자를 참조하고 있는
     모든 kevent 를 삭제합니다.

     kqueue() (은)는 신규의 커널 이벤트 큐를 생성해 기술자를 돌려줍니다.  큐는 fork(2) 그리고 생성된 child
     process에는 계승되지 않습니다.  그렇지만, RFFDG 플래그없이 rfork(2) 하지만 불려 갔을 경우에는, 기술자 테이블이
     공유되어 2 개(살)의 프로세스간에 kqueue 의 공유가 가능하게 됩니다.

     kevent() (은)는, 큐에 이벤트를 등록해, 보류중의 모든 이벤트를 유저에게 돌려주기 위해서(때문에) 사용됩니다.
     changelist kevent 구조체의 배열에의 포인터입니다. 이 구조체는 ⟨sys/event.h⟩ 그리고 정의되고 있습니다.
     보류중의 이벤트를 큐로부터 읽어들이기 전에, changelist 에 포함되어 있는 모든 변경을 적용합니다.  nchanges changelist 의 크기를 줍니다.  eventlist (은)는 kevent 구조체의 배열에의 포인터입니다.  nevents eventlist 의 크기를 결정합니다.  timeout 하지만 NULL 가 아닌 포인터의 경우에는, timespec 구조체이다고
     해석되어, 이벤트를 기다리는 최대 대기 시간을 지정합니다.  timeout 하지만 NULL 포인터의 경우에는, kevent() (은)는
     무기한으로 기다립니다.  폴링의 효과를 얻기 위해서(때문에)는, timeout 인수에, 0 을 나타낸다 timespec 구조체를
     가리키는 비 NULL 의 포인터를 주어야 합니다.  changelist (와)과 eventlist 용으로 같은 배열을 사용할 수가
     있습니다.

     EV_SET() (은)는 kevent 구조체의 초기화를 간단하게 하는 매크로입니다.

     kevent 구조체는 다음과 같이 정의되고 있습니다.

     struct kevent {
             uintptr_t ident;        /* 이 이벤트의 식별자 */
             short     filter;       /* 이벤트의 필터 */
             u_short   flags;        /* kqueue 의 액션 플래그 */
             u_int     fflags;       /* 필터 플래그치 */
             intptr_t  data;         /* 필터 데이터치 */
             void      *udata;       /* 불투명한 유저 데이터 식별자 */
     };

     struct kevent 의 필드는 이하와 같습니다.

     ident      이 이벤트를 식별하기 위해서 사용되는 값입니다.  엄밀한 해석은 연결시킬 수 있었던 필터에 의해 결정됩니다만,
                보통은 파일 기술자로서 해석됩니다.

     filter     이 이벤트를 처리하기 위해서 사용되는 커널 필터를 식별합니다.  미리 정의된 시스템 필터는 후술 되어 있습니다.

     flags      이벤트 발생시에 실행해야 할 액션입니다.

     fflags     필터 고유의 플래그입니다.

     data       필터 고유의 데이터의 값입니다.

     udata      변경되지 않고 커널을 통해 건네받는 불투명한 유저 정의의 값입니다.

     flags 필드는 이하의 값을 포함할 수가 있습니다.

     EV_ADD         이벤트를 kqueue 에 추가합니다.  기존의 이벤트를 다시 추가하면(자), 원의 이벤트의 파라미터가
                    변경됩니다.  중복 하는 엔트리가 생기는 것은 아닙니다.  이벤트를 추가하면(자), EV_DISABLE
                    플래그에 의해 덧쓰기되지 않는 한은 자동적으로 유효하게 됩니다.

     EV_ENABLE      이벤트가 방아쇠 되었을 경우에, kevent() 하지만 그 이벤트를 돌려주는 것을 허가합니다.

     EV_DISABLE     이벤트를 무효로 합니다. 이것에 의해 kevent() (은)는 그 이벤트를 돌려주지 않게 됩니다.  필터
                    자신은 무효로 되지 않습니다.

     EV_DELETE      kqueue 로부터 이벤트를 삭제합니다.  파일 기술자가 연결시킬 수 있고 있는 이벤트는, 그 기술자의
                    마지막 클로우즈시에 자동적으로 삭제됩니다.

     EV_ONESHOT     필터가 최초 방아쇠 되었을 때에 마셔, 이벤트가 돌아가도록(듯이) 합니다.  유저가 이벤트를 kqueue
                    로부터 회수한 다음에, 그 이벤트는 삭제됩니다.

     EV_CLEAR       유저가 이벤트를 회수한 후에, 그 상태를 리셋트 합니다.  이것은 현재 상태가 아니고, 상태의 변화를
                    보고하는 필터에 유용합니다.  몇개의 필터는 내부에서 이 플래그를 자동적으로 세트 하고 있다 일지도 모르는
                    것에 주의해 주세요.

     EV_EOF         그 필터 고유의 EOF 상태인 것을 나타내기 위해서(때문에), 필터가 이 플래그를 세트 하는 일이 있습니다.

     EV_ERROR       후술의 반환값 (을)를 참조해 주세요.

     미리 정의된 시스템 필터를 다음에 나타냅니다.  인수는 kevent 구조체의 fflags data 필드를 경유해 교환할 수가
     있습니다.

     EVFILT_READ    식별자에 기술자를 인수로서 취합니다.  읽어들여 가능한 데이터가 있을 때 돌아옵니다.  이 필터의 행동은,
                    그 기술자의 형태에 의해 조금 다릅니다.

                    소켓  사전에 listen() 에게 건네진 소켓의 경우, 보류중의 다음의 접속이 있을 때 돌아옵니다.
                        data 에는 listen 의 백 로그 (backlog)의 크기가 들어가 있습니다.

                        그 외의 소켓 기술자의 경우, 소켓 버퍼의 SO_RCVLOWAT 의 값을 기준으로 해, 읽어들이는
                        데이터가 있을 때 돌아옵니다.  필터를 추가할 경우에, fflags 에 NOTE_LOWAT 를 설정해
                        data 에 새로운 최저 기준치를 지정하는 것으로써, 이 값을, 필터마다의 최저 기준치로 덧쓰기하는
                        것이 가능합니다. 돌아올 때는, data 에는 소켓 버퍼안의 바이트수가 들어가 있습니다.

                        소켓의 읽기측이 절단 되었을 경우에는, 필터는 flags 에 EV_EOF 도 설정합니다. 여기서
                        에러가 일어났을 경우에는, fflags 에 소켓 에러를 돌려줍니다.  소켓 버퍼안에 보류중의 데이터가
                        남아 있어도, (접속이 끊어진 것을 나타낸다) EOF 가 돌려주어지는 일이 있습니다.

                    vnode
                        파일 포인터가 파일의 최후 (EOF)가 아닐 때에 돌아옵니다.  data (은)는 현재 위치로부터
                        파일의 최후 (EOF)까지의 오프셋(offset)가 들어가 있습니다.  이 값은 부일지도 모릅니다.

                    FIFO 와 파이프
                        읽어들여야 할 데이터가 있을 때 돌아옵니다.  data 에는 유효한 바이트수가 들어가 있습니다.

                        마지막 기입측이 절단 했을 때에, 필터는 flags 에 EV_EOF 를 세트 합니다.
                        EV_CLEAR 를 건네주는 것으로, 이 플래그를 클리어 할 수가 있어 필터는 데이터를 읽어들일 수
                        있도록(듯이) 되는 것을 돌아오지 않고 다시 기다립니다.

     EVFILT_WRITE   식별자에 기술자를 인수로서 취합니다.  그 기술자가 기입해 가능하게 될 때마다 돌아옵니다.  소켓, 파이프
                    및 FIFO 에서는, data 에는 기입 버퍼의 나머지 area의 크기가 들어가 있습니다.  읽기측이 절단
                    했을 때에, 필터는 EV_EOF 를 세트 합니다.  FIFO 의 경우, EV_CLEAR 를 사용해 이것을
                    클리어 할 수가 있습니다.  이 필터는 vnode 를 서포트하고 있지 않는 것에 주의해 주세요.

                    소켓의 경우, 최저 기준치 및 소켓 에러의 취급은 EVFULT_READ 의 경우와 같습니다.

     EVFILT_AIO     비동기 입출력 리퀘스트의 sigevent 부분의, sigev_notify_kqueue 에는 이벤트를 부가하는
                    kqueue 의 기술자를 넣어 sigev_value 에는 udata 의 값을 입금시켜 sigev_notify
                    에는 SIGEV_KEVENT 를 넣어, 비동기 입출력 리퀘스트를 묻습니다.  aio_* 함수가 불려 갔을
                    때, 그 이벤트는 지정된 kqueue 에 등록됩니다. aio_* 함수가 돌려주었다 aiocb 구조체를
                    ident 인수에 세트 합니다.  이 필터는 aio_error 와 같은 조건으로 돌아옵니다.

                    다른 방법으로서 ident 에 kqueue 기술자를 넣어 kevent 구조체를 초기화해, 그 주소를 비동기
                    리퀘스트의 aio_lio_opcode 필드에 두는 일도 가능합니다.  그렇지만, 이 접근는 64 비트
                    포인터의 아키텍쳐에서는 동작하지 않을 것입니다 해, 목표로 해야 하는 것이 아닙니다.

     EVFILT_VNODE   파일 기술자를 식별자에, 감시하는 이벤트를 fflags 에 인수로서 취합니다.  지정한 기술자에 대해 요구된
                    이벤트가 1 개 이상 발생했을 때에 돌아옵니다.  감시하는 이벤트를 이하에 나타냅니다.

                    NOTE_DELETE    기술자가 참조하는 파일에 대해 unlink() 하지만 불렸습니다.

                    NOTE_WRITE     기술자가 참조하는 파일에 대해 기입이 일어났습니다.

                    NOTE_EXTEND    기술자가 참조하는 파일의 사이즈가 확장되었습니다.

                    NOTE_ATTRIB    기술자가 참조하는 파일의 속성이 변경되었습니다.

                    NOTE_LINK      파일의 링크수가 변경되었습니다.

                    NOTE_RENAME    기술자가 참조하는 파일이 rename 되었습니다.

                    NOTE_REVOKE    파일에의 액세스가 revoke(2) 에 의해 무효로 되었는지, 혹은, 하위층의
                                   파일 시스템이 mount 되고 있지 않습니다.

                    돌아올 때, fflags 에 필터를 방아쇠 한 이벤트가 들어가 있습니다.

     EVFILT_PROC    감시하는 프로세스 ID 를 식별자에, 감시하는 이벤트를 fflags 에 인수로서 취합니다.  요구된 이벤트를
                    1 개 이상 프로세스가 실행할 경우에 돌아옵니다.  어느 프로세스가 다른 프로세스를 정상적으로 볼 수가 있는
                    경우에는, 이벤트를 그 프로세스에 연결시킬 수가 있습니다.  감시하는 이벤트를 다음에 나타냅니다.

                    NOTE_EXIT        프로세스가 종료했습니다.

                    NOTE_FORK        프로세스가 fork() (을)를 불렀습니다.

                    NOTE_EXEC        프로세스가 execve(2) 또는 유사한 호출에 의해, 신규의 프로세스를
                                     실행했습니다.

                    NOTE_TRACK       fork() 의 호출을 넘어, 프로세스를 추적합니다.  parent
                                     process는 fflags 필드에 NOTE_TRACK 를 세트 해 돌아와,
                                     한편, child process는 fflags 에 NOTE_CHILD 를
                                     data 에 parent process의 PID 를 세트 해 돌아옵니다.

                    NOTE_TRACKERR    이 플래그는, 시스템이 child process에의 이벤트를 연결시킬 수가
                                     없었을 때에 돌아옵니다.  통상, 이것은 자원의 제한에 의해 생깁니다.

                    돌아올 때, fflags (은)는 필터를 방아쇠 한 이벤트가 들어가 있습니다.

     EVFILT_SIGNAL  감시하는 시그널 번호를 식별자에 인수로서 취합니다.  주어진 시그널이 프로세스에 배송되었을 때에 돌아옵니다.
                    이것은 signal() 및 sigaction() 의 구조와 공존해, 낮은 우선 순위를 가지고 있습니다.
                    비록 그 시그널이 SIG_IGN 와 마크 되고 있었다고 해도, 필터는 프로세스에 배송되려고 한 시그널 모두를
                    기록합니다.  통상의 시그널 배송 처리의 뒤에, 이벤트 통지가 발생합니다.  data 에는 kevent()
                    (을)를 마지막으로 호출하고 나서의 시그널 발생의 회수가 돌아갑니다.  이 필터는 내부에서 자동적으로
                    EV_CLEAR 플래그를 세트 합니다.

     EVFILT_TIMER   ident 그리고 식별되는, 임의의 타이머를 설정합니다.  타이머를 추가하는 경우, data (은)는 타임
                    아웃을 밀리 세컨드 단위로 지정합니다.  EV_ONESHOT 를 지정하지 않는 한, 타이머는 주기적입니다.
                    data 에는, kevent() (을)를 마지막으로 호출하고 나서의 타임 아웃의 회수가 돌아갑니다.  이
                    필터는 내부에서 자동적으로 EV_CLEAR 플래그를 세트 합니다.

반환값
     kqueue() (은)는 신규의 커널 이벤트 큐를 생성해, 파일 기술자를 돌려줍니다.  커널 이벤트 큐의 생성시에 에러가 있었을
     경우에는, 값 -1 이 돌려주어져 errno 가 세트 됩니다.

     kevent() 하 eventlist 에 배열되고 있는 이벤트의 수를 돌려줍니다.  이 수는, 최대 nevents 그리고 주어진
     값까지입니다.  changelist 의 요소의 처리중에 에러가 발생해, 한편 eventlist 에 충분한 여지가 있는 경우에는,
     flags 에 EV_ERROR 하지만 세트 되어 data 에 시스템 우류가 세트 된 이벤트가, eventlist 에 놓여집니다.  아주
     없으면, -1 하지만 돌려주어 errno 하지만 에러 상태를 나타내기 위해서(때문에) 세트 됩니다.  마감 시간의 경우에는,
     kevent() (은)는 0 을 돌려줍니다.

에러
     kqueue() 함수는 이하의 경우에 실패합니다.

     [ENOMEM]           커널이 커넬 큐를 위한 충분한 메모리의 할당해에 실패했습니다.

     [EMFILE]           프로세스의 기술자 테이블이 만배입니다.

     [ENFILE]           시스템 파일 테이블이 만배입니다.

     kevent() 함수는 이하의 경우에 실패합니다.

     [EACCES]           프로세스가 필터를 등록하는 권한을 가지고 있지 않습니다.

     [EFAULT]           kevent 구조체의 읽어들여 또는 기입으로 에러가 있었습니다.

     [EBADF]            지정된 기술자가 유효하지는 않습니다.

     [EINTR]            마감 시간전이나, 돌아오기 위한 어떠한 이벤트가 kqueue 에 놓여지기 전에, 시그널이
                        배송되었습니다.

     [EINVAL]           지정된 시한 또는 필터가 무효입니다.

     [ENOENT]           수정 또는 삭제되어야 할 이벤트가 발견되지 않습니다.

     [ENOMEM]           이벤트 등록을 위한 메모리가 없습니다.

     [ESRCH]            연결시키기 위해서(때문에) 지정한 프로세스가 존재하지 않습니다.

관련 항목
     aio_error(2), aio_read(2), aio_return(2), poll(2), read(2), select(2),
     sigaction(2), write(2), signal(3)

역사
     kqueue() 및 kevent() 함수는 FreeBSD 4.1 그리고 처음으로 등장했습니다.

저자
     kqueue() 시스템과 이 메뉴얼 페이지는 Jonathan Lemon <jlemon@FreeBSD.org> 하지만 썼습니다.

버그
     현재는, UFS 파일 시스템에 속하지 않는다 vnode(9) (을)를 감시할 수가 없습니다.