xref: /unit/src/nxt_event_engine.h (revision 20)
10Sigor@sysoev.ru 
20Sigor@sysoev.ru /*
30Sigor@sysoev.ru  * Copyright (C) Igor Sysoev
40Sigor@sysoev.ru  * Copyright (C) NGINX, Inc.
50Sigor@sysoev.ru  */
60Sigor@sysoev.ru 
70Sigor@sysoev.ru #ifndef _NXT_EVENT_ENGINE_H_INCLUDED_
80Sigor@sysoev.ru #define _NXT_EVENT_ENGINE_H_INCLUDED_
90Sigor@sysoev.ru 
1012Sigor@sysoev.ru /*
1112Sigor@sysoev.ru  * An event interface is kernel interface such as kqueue, epoll, etc.
1212Sigor@sysoev.ru  * intended to get event notifications about file descriptor state,
1312Sigor@sysoev.ru  * signals, etc.
1412Sigor@sysoev.ru  */
1512Sigor@sysoev.ru 
1612Sigor@sysoev.ru #define NXT_FILE_EVENTS           1
1712Sigor@sysoev.ru #define NXT_NO_FILE_EVENTS        0
1812Sigor@sysoev.ru 
1912Sigor@sysoev.ru #define NXT_SIGNAL_EVENTS         1
2012Sigor@sysoev.ru #define NXT_NO_SIGNAL_EVENTS      0
2112Sigor@sysoev.ru 
2212Sigor@sysoev.ru 
2312Sigor@sysoev.ru typedef struct {
2412Sigor@sysoev.ru 
2512Sigor@sysoev.ru     /* The canonical event set name. */
2612Sigor@sysoev.ru     const char                    *name;
2712Sigor@sysoev.ru 
2812Sigor@sysoev.ru     /*
2912Sigor@sysoev.ru      * Create an event set.  The mchanges argument is a maximum number of
3012Sigor@sysoev.ru      * changes to send to the kernel.  The mevents argument is a maximum
3112Sigor@sysoev.ru      * number of events to retrieve from the kernel at once, if underlying
3212Sigor@sysoev.ru      * event facility supports batch operations.
3312Sigor@sysoev.ru      */
3412Sigor@sysoev.ru     nxt_int_t                     (*create)(nxt_event_engine_t *engine,
3512Sigor@sysoev.ru                                       nxt_uint_t mchanges, nxt_uint_t mevents);
3612Sigor@sysoev.ru 
3712Sigor@sysoev.ru     /* Close and free an event set. */
3812Sigor@sysoev.ru     void                          (*free)(nxt_event_engine_t *engine);
3912Sigor@sysoev.ru 
4012Sigor@sysoev.ru     /*
4112Sigor@sysoev.ru      * Add a file descriptor to an event set and enable the most
4212Sigor@sysoev.ru      * effective read and write event notification method provided
4312Sigor@sysoev.ru      * by underlying event facility.
4412Sigor@sysoev.ru      */
4512Sigor@sysoev.ru     void                          (*enable)(nxt_event_engine_t *engine,
4612Sigor@sysoev.ru                                       nxt_fd_event_t *ev);
4712Sigor@sysoev.ru 
4812Sigor@sysoev.ru     /* Disable file descriptor event notifications. */
4912Sigor@sysoev.ru     void                          (*disable)(nxt_event_engine_t *engine,
5012Sigor@sysoev.ru                                       nxt_fd_event_t *ev);
5112Sigor@sysoev.ru 
5212Sigor@sysoev.ru     /*
5312Sigor@sysoev.ru      * Delete a file descriptor from an event set.  A possible usage
5412Sigor@sysoev.ru      * is a moving of the file descriptor from one event set to another.
5512Sigor@sysoev.ru      */
5612Sigor@sysoev.ru     void                          (*delete)(nxt_event_engine_t *engine,
5712Sigor@sysoev.ru                                       nxt_fd_event_t *ev);
5812Sigor@sysoev.ru 
5912Sigor@sysoev.ru     /*
6012Sigor@sysoev.ru      * Delete a file descriptor from an event set before closing the
6112Sigor@sysoev.ru      * file descriptor.  The most event facilities such as Linux epoll,
6212Sigor@sysoev.ru      * BSD kqueue, Solaris event ports, AIX pollset, and HP-UX /dev/poll
6312Sigor@sysoev.ru      * delete a file descriptor automatically on the file descriptor close.
6412Sigor@sysoev.ru      * Some facilities such as Solaris /dev/poll require to delete a file
6512Sigor@sysoev.ru      * descriptor explicitly.
6612Sigor@sysoev.ru      */
6712Sigor@sysoev.ru     nxt_bool_t                    (*close)(nxt_event_engine_t *engine,
6812Sigor@sysoev.ru                                       nxt_fd_event_t *ev);
6912Sigor@sysoev.ru 
7012Sigor@sysoev.ru     /*
7112Sigor@sysoev.ru      * Add a file descriptor to an event set and enable the most effective
7212Sigor@sysoev.ru      * read event notification method provided by underlying event facility.
7312Sigor@sysoev.ru      */
7412Sigor@sysoev.ru     void                          (*enable_read)(nxt_event_engine_t *engine,
7512Sigor@sysoev.ru                                       nxt_fd_event_t *ev);
7612Sigor@sysoev.ru 
7712Sigor@sysoev.ru     /*
7812Sigor@sysoev.ru      * Add a file descriptor to an event set and enable the most effective
7912Sigor@sysoev.ru      * write event notification method provided by underlying event facility.
8012Sigor@sysoev.ru      */
8112Sigor@sysoev.ru     void                          (*enable_write)(nxt_event_engine_t *engine,
8212Sigor@sysoev.ru                                       nxt_fd_event_t *ev);
8312Sigor@sysoev.ru 
8412Sigor@sysoev.ru     /* Disable file descriptor read event notifications. */
8512Sigor@sysoev.ru     void                          (*disable_read)(nxt_event_engine_t *engine,
8612Sigor@sysoev.ru                                       nxt_fd_event_t *ev);
8712Sigor@sysoev.ru 
8812Sigor@sysoev.ru     /* Disable file descriptor write event notifications. */
8912Sigor@sysoev.ru     void                          (*disable_write)(nxt_event_engine_t *engine,
9012Sigor@sysoev.ru                                       nxt_fd_event_t *ev);
9112Sigor@sysoev.ru 
9212Sigor@sysoev.ru     /* Block file descriptor read event notifications. */
9312Sigor@sysoev.ru     void                          (*block_read)(nxt_event_engine_t *engine,
9412Sigor@sysoev.ru                                       nxt_fd_event_t *ev);
9512Sigor@sysoev.ru 
9612Sigor@sysoev.ru     /* Block file descriptor write event notifications. */
9712Sigor@sysoev.ru     void                          (*block_write)(nxt_event_engine_t *engine,
9812Sigor@sysoev.ru                                       nxt_fd_event_t *ev);
9912Sigor@sysoev.ru 
10012Sigor@sysoev.ru     /*
10112Sigor@sysoev.ru      * Add a file descriptor to an event set and enable an oneshot
10212Sigor@sysoev.ru      * read event notification method.
10312Sigor@sysoev.ru      */
10412Sigor@sysoev.ru     void                          (*oneshot_read)(nxt_event_engine_t *engine,
10512Sigor@sysoev.ru                                       nxt_fd_event_t *ev);
10612Sigor@sysoev.ru 
10712Sigor@sysoev.ru     /*
10812Sigor@sysoev.ru      * Add a file descriptor to an event set and enable an oneshot
10912Sigor@sysoev.ru      * write event notification method.
11012Sigor@sysoev.ru      */
11112Sigor@sysoev.ru     void                          (*oneshot_write)(nxt_event_engine_t *engine,
11212Sigor@sysoev.ru                                       nxt_fd_event_t *ev);
11312Sigor@sysoev.ru 
11412Sigor@sysoev.ru     /*
11512Sigor@sysoev.ru      * Add a listening socket descriptor to an event set and enable
11612Sigor@sysoev.ru      * a level-triggered read event notification method.
11712Sigor@sysoev.ru      */
11812Sigor@sysoev.ru     void                          (*enable_accept)(nxt_event_engine_t *engine,
11912Sigor@sysoev.ru                                       nxt_fd_event_t *ev);
12012Sigor@sysoev.ru 
12112Sigor@sysoev.ru     /*
12212Sigor@sysoev.ru      * Add a file to an event set and enable a file change notification
12312Sigor@sysoev.ru      * events.
12412Sigor@sysoev.ru      */
12512Sigor@sysoev.ru     void                          (*enable_file)(nxt_event_engine_t *engine,
12612Sigor@sysoev.ru                                       nxt_event_file_t *fev);
12712Sigor@sysoev.ru 
12812Sigor@sysoev.ru     /*
12912Sigor@sysoev.ru      * Delete a file from an event set before closing the file descriptor.
13012Sigor@sysoev.ru      */
13112Sigor@sysoev.ru     void                          (*close_file)(nxt_event_engine_t *engine,
13212Sigor@sysoev.ru                                       nxt_event_file_t *fev);
13312Sigor@sysoev.ru 
13412Sigor@sysoev.ru     /*
13512Sigor@sysoev.ru      * Enable post event notifications and set a post handler to handle
13612Sigor@sysoev.ru      * the zero signal.
13712Sigor@sysoev.ru      */
13812Sigor@sysoev.ru     nxt_int_t                     (*enable_post)(nxt_event_engine_t *engine,
13912Sigor@sysoev.ru                                       nxt_work_handler_t handler);
14012Sigor@sysoev.ru 
14112Sigor@sysoev.ru     /*
14212Sigor@sysoev.ru      * Signal an event set.  If a signal number is non-zero then
14312Sigor@sysoev.ru      * a signal handler added to the event set is called.  This is
14412Sigor@sysoev.ru      * a way to route Unix signals to an event engine if underlying
14512Sigor@sysoev.ru      * event facility does not support signal events.
14612Sigor@sysoev.ru      *
14712Sigor@sysoev.ru      * If a signal number is zero, then the post_handler of the event
14812Sigor@sysoev.ru      * set is called.  This has no relation to Unix signals but is
14912Sigor@sysoev.ru      * a way to wake up the event set to process works posted to
15012Sigor@sysoev.ru      * the event engine locked work queue.
15112Sigor@sysoev.ru      */
15212Sigor@sysoev.ru     void                          (*signal)(nxt_event_engine_t *engine,
15312Sigor@sysoev.ru                                       nxt_uint_t signo);
15412Sigor@sysoev.ru 
15512Sigor@sysoev.ru     /* Poll an event set for new event notifications. */
15612Sigor@sysoev.ru     void                          (*poll)(nxt_event_engine_t *engine,
15712Sigor@sysoev.ru                                       nxt_msec_t timeout);
15812Sigor@sysoev.ru 
15912Sigor@sysoev.ru     /* I/O operations suitable to underlying event facility. */
16012Sigor@sysoev.ru     nxt_event_conn_io_t           *io;
16112Sigor@sysoev.ru 
16212Sigor@sysoev.ru     /* True if an event facility supports file change event notifications. */
16312Sigor@sysoev.ru     uint8_t                       file_support;   /* 1 bit */
16412Sigor@sysoev.ru 
16512Sigor@sysoev.ru     /* True if an event facility supports signal event notifications. */
16612Sigor@sysoev.ru     uint8_t                       signal_support;  /* 1 bit */
16712Sigor@sysoev.ru } nxt_event_interface_t;
16812Sigor@sysoev.ru 
16912Sigor@sysoev.ru 
17012Sigor@sysoev.ru #if (NXT_HAVE_KQUEUE)
17112Sigor@sysoev.ru 
17212Sigor@sysoev.ru typedef struct {
17312Sigor@sysoev.ru     int                           fd;
17412Sigor@sysoev.ru     int                           nchanges;
17512Sigor@sysoev.ru     int                           mchanges;
17612Sigor@sysoev.ru     int                           mevents;
17712Sigor@sysoev.ru     nxt_pid_t                     pid;
17812Sigor@sysoev.ru 
17912Sigor@sysoev.ru     nxt_work_handler_t            post_handler;
18012Sigor@sysoev.ru 
18112Sigor@sysoev.ru     struct kevent                 *changes;
18212Sigor@sysoev.ru     struct kevent                 *events;
18312Sigor@sysoev.ru } nxt_kqueue_engine_t;
18412Sigor@sysoev.ru 
18512Sigor@sysoev.ru extern const nxt_event_interface_t  nxt_kqueue_engine;
18612Sigor@sysoev.ru 
18712Sigor@sysoev.ru #endif
18812Sigor@sysoev.ru 
18912Sigor@sysoev.ru 
19012Sigor@sysoev.ru #if (NXT_HAVE_EPOLL)
19112Sigor@sysoev.ru 
19212Sigor@sysoev.ru typedef struct {
19312Sigor@sysoev.ru     int                           op;
19412Sigor@sysoev.ru     struct epoll_event            event;
19512Sigor@sysoev.ru } nxt_epoll_change_t;
19612Sigor@sysoev.ru 
19712Sigor@sysoev.ru 
19812Sigor@sysoev.ru typedef struct {
19912Sigor@sysoev.ru     int                           fd;
20012Sigor@sysoev.ru     uint32_t                      mode;
20112Sigor@sysoev.ru     nxt_uint_t                    nchanges;
20212Sigor@sysoev.ru     nxt_uint_t                    mchanges;
20312Sigor@sysoev.ru     int                           mevents;
20412Sigor@sysoev.ru 
20512Sigor@sysoev.ru     nxt_epoll_change_t            *changes;
20612Sigor@sysoev.ru     struct epoll_event            *events;
20712Sigor@sysoev.ru 
20812Sigor@sysoev.ru #if (NXT_HAVE_EVENTFD)
20912Sigor@sysoev.ru     nxt_work_handler_t            post_handler;
21012Sigor@sysoev.ru     nxt_fd_event_t                eventfd;
21112Sigor@sysoev.ru     uint32_t                      neventfd;
21212Sigor@sysoev.ru #endif
21312Sigor@sysoev.ru 
21412Sigor@sysoev.ru #if (NXT_HAVE_SIGNALFD)
21512Sigor@sysoev.ru     nxt_fd_event_t                signalfd;
21612Sigor@sysoev.ru #endif
21712Sigor@sysoev.ru } nxt_epoll_engine_t;
21812Sigor@sysoev.ru 
21912Sigor@sysoev.ru 
22012Sigor@sysoev.ru extern const nxt_event_interface_t  nxt_epoll_edge_engine;
22112Sigor@sysoev.ru extern const nxt_event_interface_t  nxt_epoll_level_engine;
22212Sigor@sysoev.ru 
22312Sigor@sysoev.ru #endif
22412Sigor@sysoev.ru 
22512Sigor@sysoev.ru 
22612Sigor@sysoev.ru #if (NXT_HAVE_EVENTPORT)
22712Sigor@sysoev.ru 
22812Sigor@sysoev.ru typedef struct {
22912Sigor@sysoev.ru     int                           events;
23012Sigor@sysoev.ru     nxt_fd_event_t                *event;
23112Sigor@sysoev.ru } nxt_eventport_change_t;
23212Sigor@sysoev.ru 
23312Sigor@sysoev.ru 
23412Sigor@sysoev.ru typedef struct {
23512Sigor@sysoev.ru     int                           fd;
23612Sigor@sysoev.ru     nxt_uint_t                    nchanges;
23712Sigor@sysoev.ru     nxt_uint_t                    mchanges;
23812Sigor@sysoev.ru     u_int                         mevents;
23912Sigor@sysoev.ru 
24012Sigor@sysoev.ru     nxt_eventport_change_t        *changes;
24112Sigor@sysoev.ru     port_event_t                  *events;
24212Sigor@sysoev.ru 
24312Sigor@sysoev.ru     nxt_work_handler_t            post_handler;
24412Sigor@sysoev.ru     nxt_work_handler_t            signal_handler;
24512Sigor@sysoev.ru } nxt_eventport_engine_t;
24612Sigor@sysoev.ru 
24712Sigor@sysoev.ru extern const nxt_event_interface_t  nxt_eventport_engine;
24812Sigor@sysoev.ru 
24912Sigor@sysoev.ru #endif
25012Sigor@sysoev.ru 
25112Sigor@sysoev.ru 
25212Sigor@sysoev.ru #if (NXT_HAVE_DEVPOLL)
25312Sigor@sysoev.ru 
25412Sigor@sysoev.ru typedef struct {
25512Sigor@sysoev.ru     uint8_t                       op;
25612Sigor@sysoev.ru     short                         events;
25712Sigor@sysoev.ru     nxt_fd_event_t                *event;
25812Sigor@sysoev.ru } nxt_devpoll_change_t;
25912Sigor@sysoev.ru 
26012Sigor@sysoev.ru 
26112Sigor@sysoev.ru typedef struct {
26212Sigor@sysoev.ru     int                           fd;
26312Sigor@sysoev.ru     int                           nchanges;
26412Sigor@sysoev.ru     int                           mchanges;
26512Sigor@sysoev.ru     int                           mevents;
26612Sigor@sysoev.ru 
26712Sigor@sysoev.ru     nxt_devpoll_change_t          *changes;
26812Sigor@sysoev.ru     struct pollfd                 *write_changes;
26912Sigor@sysoev.ru     struct pollfd                 *events;
27012Sigor@sysoev.ru     nxt_lvlhsh_t                  fd_hash;
27112Sigor@sysoev.ru } nxt_devpoll_engine_t;
27212Sigor@sysoev.ru 
27312Sigor@sysoev.ru extern const nxt_event_interface_t  nxt_devpoll_engine;
27412Sigor@sysoev.ru 
27512Sigor@sysoev.ru #endif
27612Sigor@sysoev.ru 
27712Sigor@sysoev.ru 
27812Sigor@sysoev.ru #if (NXT_HAVE_POLLSET)
27912Sigor@sysoev.ru 
28012Sigor@sysoev.ru typedef struct {
28112Sigor@sysoev.ru     uint8_t                       op;
28212Sigor@sysoev.ru     uint8_t                       cmd;
28312Sigor@sysoev.ru     short                         events;
28412Sigor@sysoev.ru     nxt_fd_event_t                *event;
28512Sigor@sysoev.ru } nxt_pollset_change_t;
28612Sigor@sysoev.ru 
28712Sigor@sysoev.ru 
28812Sigor@sysoev.ru typedef struct {
28912Sigor@sysoev.ru     pollset_t                     ps;
29012Sigor@sysoev.ru     int                           nchanges;
29112Sigor@sysoev.ru     int                           mchanges;
29212Sigor@sysoev.ru     int                           mevents;
29312Sigor@sysoev.ru 
29412Sigor@sysoev.ru     nxt_pollset_change_t          *changes;
29512Sigor@sysoev.ru     struct poll_ctl               *write_changes;
29612Sigor@sysoev.ru     struct pollfd                 *events;
29712Sigor@sysoev.ru     nxt_lvlhsh_t                  fd_hash;
29812Sigor@sysoev.ru } nxt_pollset_engine_t;
29912Sigor@sysoev.ru 
30012Sigor@sysoev.ru extern const nxt_event_interface_t  nxt_pollset_engine;
30112Sigor@sysoev.ru 
30212Sigor@sysoev.ru #endif
30312Sigor@sysoev.ru 
30412Sigor@sysoev.ru 
30512Sigor@sysoev.ru typedef struct {
30612Sigor@sysoev.ru     uint8_t                       op;
30712Sigor@sysoev.ru     short                         events;
30812Sigor@sysoev.ru     nxt_fd_event_t                *event;
30912Sigor@sysoev.ru } nxt_poll_change_t;
31012Sigor@sysoev.ru 
31112Sigor@sysoev.ru 
31212Sigor@sysoev.ru typedef struct {
31312Sigor@sysoev.ru     nxt_uint_t                    max_nfds;
31412Sigor@sysoev.ru     nxt_uint_t                    nfds;
31512Sigor@sysoev.ru 
31612Sigor@sysoev.ru     nxt_uint_t                    nchanges;
31712Sigor@sysoev.ru     nxt_uint_t                    mchanges;
31812Sigor@sysoev.ru 
31912Sigor@sysoev.ru     nxt_poll_change_t             *changes;
32012Sigor@sysoev.ru     struct pollfd                 *set;
32112Sigor@sysoev.ru 
32212Sigor@sysoev.ru     nxt_lvlhsh_t                  fd_hash;
32312Sigor@sysoev.ru } nxt_poll_engine_t;
32412Sigor@sysoev.ru 
32512Sigor@sysoev.ru extern const nxt_event_interface_t  nxt_poll_engine;
32612Sigor@sysoev.ru 
32712Sigor@sysoev.ru 
32812Sigor@sysoev.ru typedef struct {
32912Sigor@sysoev.ru     int                           nfds;
33012Sigor@sysoev.ru     uint32_t                      update_nfds;  /* 1 bit */
33112Sigor@sysoev.ru 
33212Sigor@sysoev.ru     nxt_fd_event_t                **events;
33312Sigor@sysoev.ru 
33412Sigor@sysoev.ru     fd_set                        main_read_fd_set;
33512Sigor@sysoev.ru     fd_set                        main_write_fd_set;
33612Sigor@sysoev.ru     fd_set                        work_read_fd_set;
33712Sigor@sysoev.ru     fd_set                        work_write_fd_set;
33812Sigor@sysoev.ru } nxt_select_engine_t;
33912Sigor@sysoev.ru 
34012Sigor@sysoev.ru extern const nxt_event_interface_t  nxt_select_engine;
34112Sigor@sysoev.ru 
34212Sigor@sysoev.ru 
34312Sigor@sysoev.ru nxt_int_t nxt_fd_event_hash_add(nxt_lvlhsh_t *lvlhsh, nxt_fd_t fd,
34412Sigor@sysoev.ru     nxt_fd_event_t *ev);
34512Sigor@sysoev.ru void *nxt_fd_event_hash_get(nxt_task_t *task, nxt_lvlhsh_t *lvlhsh,
34612Sigor@sysoev.ru     nxt_fd_t fd);
34712Sigor@sysoev.ru void nxt_fd_event_hash_delete(nxt_task_t *task, nxt_lvlhsh_t *lvlhsh,
34812Sigor@sysoev.ru     nxt_fd_t fd, nxt_bool_t ignore);
34912Sigor@sysoev.ru void nxt_fd_event_hash_destroy(nxt_lvlhsh_t *lvlhsh);
35012Sigor@sysoev.ru 
35112Sigor@sysoev.ru 
35212Sigor@sysoev.ru #define                                                                       \
35312Sigor@sysoev.ru nxt_fd_event_disable(engine, ev)                                              \
35412Sigor@sysoev.ru     (engine)->event.disable(engine, ev)
35512Sigor@sysoev.ru 
35612Sigor@sysoev.ru 
35712Sigor@sysoev.ru #define                                                                       \
35812Sigor@sysoev.ru nxt_fd_event_close(engine, ev)                                                \
35912Sigor@sysoev.ru     (engine)->event.close(engine, ev)
36012Sigor@sysoev.ru 
36112Sigor@sysoev.ru 
36212Sigor@sysoev.ru #define                                                                       \
36312Sigor@sysoev.ru nxt_fd_event_enable_read(engine, ev)                                          \
36412Sigor@sysoev.ru     (engine)->event.enable_read(engine, ev)
36512Sigor@sysoev.ru 
36612Sigor@sysoev.ru 
36712Sigor@sysoev.ru #define                                                                       \
36812Sigor@sysoev.ru nxt_fd_event_enable_write(engine, ev)                                         \
36912Sigor@sysoev.ru     (engine)->event.enable_write(engine, ev)
37012Sigor@sysoev.ru 
37112Sigor@sysoev.ru 
37212Sigor@sysoev.ru #define                                                                       \
37312Sigor@sysoev.ru nxt_fd_event_disable_read(engine, ev)                                         \
37412Sigor@sysoev.ru     (engine)->event.disable_read(engine, ev)
37512Sigor@sysoev.ru 
37612Sigor@sysoev.ru 
37712Sigor@sysoev.ru #define                                                                       \
37812Sigor@sysoev.ru nxt_fd_event_disable_write(engine, ev)                                        \
37912Sigor@sysoev.ru     (engine)->event.disable_write(engine, ev)
38012Sigor@sysoev.ru 
38112Sigor@sysoev.ru 
38212Sigor@sysoev.ru #define                                                                       \
38312Sigor@sysoev.ru nxt_fd_event_block_read(engine, ev)                                           \
38412Sigor@sysoev.ru     do {                                                                      \
38512Sigor@sysoev.ru         if (nxt_fd_event_is_active((ev)->read)) {                             \
38612Sigor@sysoev.ru             (engine)->event.block_read(engine, ev);                           \
38712Sigor@sysoev.ru         }                                                                     \
38812Sigor@sysoev.ru     } while (0)
38912Sigor@sysoev.ru 
39012Sigor@sysoev.ru 
39112Sigor@sysoev.ru #define                                                                       \
39212Sigor@sysoev.ru nxt_fd_event_block_write(engine, ev)                                          \
39312Sigor@sysoev.ru     do {                                                                      \
39412Sigor@sysoev.ru         if (nxt_fd_event_is_active((ev)->write)) {                            \
39512Sigor@sysoev.ru             (engine)->event.block_write(engine, ev);                          \
39612Sigor@sysoev.ru         }                                                                     \
39712Sigor@sysoev.ru     } while (0)
39812Sigor@sysoev.ru 
39912Sigor@sysoev.ru 
40012Sigor@sysoev.ru #define                                                                       \
40112Sigor@sysoev.ru nxt_fd_event_oneshot_read(engine, ev)                                         \
40212Sigor@sysoev.ru     (engine)->event.oneshot_read(engine, ev)
40312Sigor@sysoev.ru 
40412Sigor@sysoev.ru 
40512Sigor@sysoev.ru #define                                                                       \
40612Sigor@sysoev.ru nxt_fd_event_oneshot_write(engine, ev)                                        \
40712Sigor@sysoev.ru     (engine)->event.oneshot_write(engine, ev)
40812Sigor@sysoev.ru 
40912Sigor@sysoev.ru 
41012Sigor@sysoev.ru #define                                                                       \
41112Sigor@sysoev.ru nxt_fd_event_enable_accept(engine, ev)                                        \
41212Sigor@sysoev.ru     (engine)->event.enable_accept(engine, ev)
41312Sigor@sysoev.ru 
4140Sigor@sysoev.ru 
4150Sigor@sysoev.ru #define NXT_ENGINE_FIBERS      1
4160Sigor@sysoev.ru 
4170Sigor@sysoev.ru 
4180Sigor@sysoev.ru typedef struct {
4190Sigor@sysoev.ru     nxt_fd_t                   fds[2];
42012Sigor@sysoev.ru     nxt_fd_event_t             event;
4210Sigor@sysoev.ru } nxt_event_engine_pipe_t;
4220Sigor@sysoev.ru 
4230Sigor@sysoev.ru 
4240Sigor@sysoev.ru struct nxt_event_engine_s {
42512Sigor@sysoev.ru     nxt_task_t                 task;
42612Sigor@sysoev.ru 
42712Sigor@sysoev.ru     union {
42812Sigor@sysoev.ru         nxt_poll_engine_t      poll;
42912Sigor@sysoev.ru         nxt_select_engine_t    select;
43012Sigor@sysoev.ru 
43112Sigor@sysoev.ru #if (NXT_HAVE_KQUEUE)
43212Sigor@sysoev.ru         nxt_kqueue_engine_t    kqueue;
43312Sigor@sysoev.ru #endif
43412Sigor@sysoev.ru #if (NXT_HAVE_EPOLL)
43512Sigor@sysoev.ru         nxt_epoll_engine_t     epoll;
43612Sigor@sysoev.ru #endif
43712Sigor@sysoev.ru #if (NXT_HAVE_EVENTPORT)
43812Sigor@sysoev.ru         nxt_eventport_engine_t eventport;
43912Sigor@sysoev.ru #endif
44012Sigor@sysoev.ru #if (NXT_HAVE_DEVPOLL)
44112Sigor@sysoev.ru         nxt_devpoll_engine_t   devpoll;
44212Sigor@sysoev.ru #endif
44312Sigor@sysoev.ru #if (NXT_HAVE_POLLSET)
44412Sigor@sysoev.ru         nxt_pollset_engine_t   pollset;
44512Sigor@sysoev.ru #endif
44612Sigor@sysoev.ru     } u;
4470Sigor@sysoev.ru 
4486Sigor@sysoev.ru     nxt_timers_t               timers;
4490Sigor@sysoev.ru 
4504Sigor@sysoev.ru     nxt_work_queue_cache_t     work_queue_cache;
4514Sigor@sysoev.ru     nxt_work_queue_t           *current_work_queue;
4524Sigor@sysoev.ru     nxt_work_queue_t           fast_work_queue;
4530Sigor@sysoev.ru     nxt_work_queue_t           accept_work_queue;
4540Sigor@sysoev.ru     nxt_work_queue_t           read_work_queue;
4550Sigor@sysoev.ru     nxt_work_queue_t           socket_work_queue;
4560Sigor@sysoev.ru     nxt_work_queue_t           connect_work_queue;
4570Sigor@sysoev.ru     nxt_work_queue_t           write_work_queue;
4580Sigor@sysoev.ru     nxt_work_queue_t           shutdown_work_queue;
4590Sigor@sysoev.ru     nxt_work_queue_t           close_work_queue;
4600Sigor@sysoev.ru 
4614Sigor@sysoev.ru     nxt_locked_work_queue_t    locked_work_queue;
4620Sigor@sysoev.ru 
46312Sigor@sysoev.ru     nxt_event_interface_t      event;
46412Sigor@sysoev.ru 
46512Sigor@sysoev.ru     /*
46612Sigor@sysoev.ru      * A pipe to pass event signals to the engine, if the engine's
46712Sigor@sysoev.ru      * underlying event facility does not support user events.
46812Sigor@sysoev.ru      */
46912Sigor@sysoev.ru     nxt_event_engine_pipe_t    *pipe;
47012Sigor@sysoev.ru 
4710Sigor@sysoev.ru     nxt_event_signals_t        *signals;
4720Sigor@sysoev.ru 
4730Sigor@sysoev.ru     nxt_fiber_main_t           *fibers;
4740Sigor@sysoev.ru 
47512Sigor@sysoev.ru     /* The engine ID, the main engine has ID 0. */
47612Sigor@sysoev.ru     uint32_t                   id;
47712Sigor@sysoev.ru 
4780Sigor@sysoev.ru     uint8_t                    shutdown;  /* 1 bit */
4790Sigor@sysoev.ru 
480*20Sigor@sysoev.ru     uint32_t                   batch;
4810Sigor@sysoev.ru     uint32_t                   connections;
4820Sigor@sysoev.ru     uint32_t                   max_connections;
4830Sigor@sysoev.ru 
4840Sigor@sysoev.ru     nxt_queue_t                listen_connections;
4850Sigor@sysoev.ru     nxt_queue_t                idle_connections;
4860Sigor@sysoev.ru };
4870Sigor@sysoev.ru 
4880Sigor@sysoev.ru 
489*20Sigor@sysoev.ru NXT_EXPORT nxt_event_engine_t *nxt_event_engine_create(nxt_task_t *task,
49012Sigor@sysoev.ru     const nxt_event_interface_t *interface, const nxt_sig_event_t *signals,
4910Sigor@sysoev.ru     nxt_uint_t flags, nxt_uint_t batch);
492*20Sigor@sysoev.ru NXT_EXPORT nxt_int_t nxt_event_engine_change(nxt_event_engine_t *engine,
493*20Sigor@sysoev.ru     const nxt_event_interface_t *interface, nxt_uint_t batch);
4940Sigor@sysoev.ru NXT_EXPORT void nxt_event_engine_free(nxt_event_engine_t *engine);
4950Sigor@sysoev.ru NXT_EXPORT void nxt_event_engine_start(nxt_event_engine_t *engine);
4960Sigor@sysoev.ru 
4970Sigor@sysoev.ru NXT_EXPORT void nxt_event_engine_post(nxt_event_engine_t *engine,
4984Sigor@sysoev.ru     nxt_work_t *work);
4990Sigor@sysoev.ru NXT_EXPORT void nxt_event_engine_signal(nxt_event_engine_t *engine,
5000Sigor@sysoev.ru     nxt_uint_t signo);
5010Sigor@sysoev.ru 
5020Sigor@sysoev.ru 
5030Sigor@sysoev.ru nxt_inline nxt_event_engine_t *
5040Sigor@sysoev.ru nxt_thread_event_engine(void)
5050Sigor@sysoev.ru {
5060Sigor@sysoev.ru     nxt_thread_t  *thr;
5070Sigor@sysoev.ru 
5080Sigor@sysoev.ru     thr = nxt_thread();
5090Sigor@sysoev.ru     return thr->engine;
5100Sigor@sysoev.ru }
5110Sigor@sysoev.ru 
5120Sigor@sysoev.ru 
5130Sigor@sysoev.ru #endif /* _NXT_EVENT_ENGINE_H_INCLUDED_ */
514