Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 1 | /* |
Igor Sysoev | 6a644c6 | 2003-03-04 06:33:48 +0000 | [diff] [blame] | 2 | * Copyright (C) 2002-2003 Igor Sysoev, http://sysoev.ru |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 3 | */ |
| 4 | |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 5 | |
| 6 | #include <ngx_config.h> |
Igor Sysoev | 016b852 | 2002-08-29 16:59:54 +0000 | [diff] [blame] | 7 | #include <ngx_core.h> |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 8 | #include <ngx_types.h> |
| 9 | #include <ngx_log.h> |
| 10 | #include <ngx_connection.h> |
| 11 | #include <ngx_event.h> |
Igor Sysoev | fcce8d5 | 2003-01-23 18:47:54 +0000 | [diff] [blame] | 12 | #include <ngx_event_timer.h> |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 13 | #include <ngx_kqueue_module.h> |
| 14 | |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 15 | |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 16 | /* STUB */ |
| 17 | #define KQUEUE_NCHANGES 512 |
| 18 | #define KQUEUE_NEVENTS 512 |
| 19 | |
| 20 | |
Igor Sysoev | 8dcd23e | 2003-04-22 15:02:58 +0000 | [diff] [blame] | 21 | /* should be per-thread if threads are used without thread pool */ |
Igor Sysoev | 7300977 | 2003-02-06 17:21:13 +0000 | [diff] [blame] | 22 | #if 1 |
Igor Sysoev | 8dcd23e | 2003-04-22 15:02:58 +0000 | [diff] [blame] | 23 | int kq; |
Igor Sysoev | 7300977 | 2003-02-06 17:21:13 +0000 | [diff] [blame] | 24 | #else |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 25 | static int kq; |
Igor Sysoev | 7300977 | 2003-02-06 17:21:13 +0000 | [diff] [blame] | 26 | #endif |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 27 | static struct kevent *change_list, *event_list; |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 28 | static unsigned int nchanges; |
| 29 | static int nevents; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 30 | |
Igor Sysoev | 9b25d69 | 2003-01-26 21:08:14 +0000 | [diff] [blame] | 31 | static ngx_event_t *timer_queue; |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame] | 32 | /* */ |
| 33 | |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 34 | |
Igor Sysoev | 31f8818 | 2002-09-27 15:05:29 +0000 | [diff] [blame] | 35 | int ngx_kqueue_init(int max_connections, ngx_log_t *log) |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 36 | { |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 37 | int change_size, event_size; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 38 | |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 39 | nevents = KQUEUE_NEVENTS; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 40 | nchanges = 0; |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 41 | change_size = sizeof(struct kevent) * KQUEUE_NCHANGES; |
| 42 | event_size = sizeof(struct kevent) * KQUEUE_NEVENTS; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 43 | |
Igor Sysoev | 1af7c82 | 2002-09-13 14:47:42 +0000 | [diff] [blame] | 44 | kq = kqueue(); |
| 45 | |
| 46 | if (kq == -1) { |
| 47 | ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "kqueue() failed"); |
Igor Sysoev | 31f8818 | 2002-09-27 15:05:29 +0000 | [diff] [blame] | 48 | return NGX_ERROR; |
Igor Sysoev | 0ad17c0 | 2002-08-26 15:18:19 +0000 | [diff] [blame] | 49 | } |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 50 | |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 51 | ngx_test_null(change_list, ngx_alloc(change_size, log), NGX_ERROR); |
| 52 | ngx_test_null(event_list, ngx_alloc(event_size, log), NGX_ERROR); |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 53 | |
Igor Sysoev | 9b25d69 | 2003-01-26 21:08:14 +0000 | [diff] [blame] | 54 | timer_queue = ngx_event_init_timer(log); |
| 55 | if (timer_queue == NULL) { |
Igor Sysoev | fcce8d5 | 2003-01-23 18:47:54 +0000 | [diff] [blame] | 56 | return NGX_ERROR; |
| 57 | } |
| 58 | |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 59 | ngx_event_actions.add = ngx_kqueue_add_event; |
| 60 | ngx_event_actions.del = ngx_kqueue_del_event; |
Igor Sysoev | 9b25d69 | 2003-01-26 21:08:14 +0000 | [diff] [blame] | 61 | ngx_event_actions.timer = ngx_event_add_timer; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 62 | ngx_event_actions.process = ngx_kqueue_process_events; |
Igor Sysoev | 9b25d69 | 2003-01-26 21:08:14 +0000 | [diff] [blame] | 63 | |
Igor Sysoev | 1e7ec9d | 2003-02-11 07:14:40 +0000 | [diff] [blame] | 64 | #if (HAVE_AIO_EVENT) |
| 65 | |
| 66 | ngx_event_flags = NGX_HAVE_AIO_EVENT; |
| 67 | |
| 68 | #else |
| 69 | |
Igor Sysoev | 9b25d69 | 2003-01-26 21:08:14 +0000 | [diff] [blame] | 70 | ngx_event_flags = NGX_HAVE_LEVEL_EVENT |
Igor Sysoev | 7300977 | 2003-02-06 17:21:13 +0000 | [diff] [blame] | 71 | |NGX_HAVE_ONESHOT_EVENT |
Igor Sysoev | b738757 | 2003-03-11 20:38:13 +0000 | [diff] [blame] | 72 | |
Igor Sysoev | 1e7ec9d | 2003-02-11 07:14:40 +0000 | [diff] [blame] | 73 | #if (HAVE_CLEAR_EVENT) |
| 74 | |NGX_HAVE_CLEAR_EVENT |
Igor Sysoev | b738757 | 2003-03-11 20:38:13 +0000 | [diff] [blame] | 75 | #else |
| 76 | |NGX_USE_LEVEL_EVENT |
Igor Sysoev | 7300977 | 2003-02-06 17:21:13 +0000 | [diff] [blame] | 77 | #endif |
Igor Sysoev | b738757 | 2003-03-11 20:38:13 +0000 | [diff] [blame] | 78 | |
Igor Sysoev | 6a644c6 | 2003-03-04 06:33:48 +0000 | [diff] [blame] | 79 | #if (HAVE_LOWAT_EVENT) |
| 80 | |NGX_HAVE_LOWAT_EVENT |
| 81 | #endif |
Igor Sysoev | b738757 | 2003-03-11 20:38:13 +0000 | [diff] [blame] | 82 | |
Igor Sysoev | 1e7ec9d | 2003-02-11 07:14:40 +0000 | [diff] [blame] | 83 | |NGX_HAVE_KQUEUE_EVENT; |
| 84 | |
Igor Sysoev | ff148df | 2003-02-26 20:21:43 +0000 | [diff] [blame] | 85 | ngx_write_chain_proc = ngx_freebsd_write_chain; |
| 86 | |
Igor Sysoev | 1e7ec9d | 2003-02-11 07:14:40 +0000 | [diff] [blame] | 87 | #endif |
| 88 | |
Igor Sysoev | 31f8818 | 2002-09-27 15:05:29 +0000 | [diff] [blame] | 89 | return NGX_OK; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 90 | } |
| 91 | |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame] | 92 | |
Igor Sysoev | 6a644c6 | 2003-03-04 06:33:48 +0000 | [diff] [blame] | 93 | void ngx_kqueue_done(ngx_log_t *log) |
| 94 | { |
| 95 | if (close(kq) == -1) { |
| 96 | ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "kqueue close() failed"); |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 101 | int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags) |
| 102 | { |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 103 | ev->active = 1; |
Igor Sysoev | 3a40d48 | 2002-09-12 14:42:29 +0000 | [diff] [blame] | 104 | ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1: 0; |
| 105 | |
Igor Sysoev | dc479b4 | 2003-03-20 16:09:44 +0000 | [diff] [blame] | 106 | /* The event addition or change should be always passed to a kernel |
| 107 | because there can be case when event was passed to a kernel then |
| 108 | added again to the change_list and then deleted from the change_list |
| 109 | by ngx_kqueue_del_event() so the first event still remains in a kernel */ |
| 110 | |
| 111 | #if 0 |
| 112 | |
Igor Sysoev | a6717c4 | 2002-12-23 06:29:22 +0000 | [diff] [blame] | 113 | if (nchanges > 0 |
| 114 | && ev->index < nchanges |
| 115 | && change_list[ev->index].udata == ev) |
| 116 | { |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 117 | #if (NGX_DEBUG_EVENT) |
Igor Sysoev | a6717c4 | 2002-12-23 06:29:22 +0000 | [diff] [blame] | 118 | ngx_connection_t *c = (ngx_connection_t *) ev->data; |
| 119 | ngx_log_debug(ev->log, "kqueue add event: %d: ft:%d" _ c->fd _ event); |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 120 | #endif |
Igor Sysoev | dc479b4 | 2003-03-20 16:09:44 +0000 | [diff] [blame] | 121 | |
| 122 | /* if the event is still not passed to a kernel we change it */ |
| 123 | |
Igor Sysoev | a6717c4 | 2002-12-23 06:29:22 +0000 | [diff] [blame] | 124 | change_list[ev->index].filter = event; |
| 125 | change_list[ev->index].flags = flags; |
| 126 | |
| 127 | return NGX_OK; |
| 128 | } |
Igor Sysoev | a6717c4 | 2002-12-23 06:29:22 +0000 | [diff] [blame] | 129 | |
Igor Sysoev | dc479b4 | 2003-03-20 16:09:44 +0000 | [diff] [blame] | 130 | #endif |
| 131 | |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 132 | return ngx_kqueue_set_event(ev, event, EV_ADD | flags); |
| 133 | } |
| 134 | |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame] | 135 | |
| 136 | int ngx_kqueue_del_event(ngx_event_t *ev, int event, u_int flags) |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 137 | { |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 138 | ngx_event_t *e; |
| 139 | |
| 140 | ev->active = 0; |
Igor Sysoev | 2ba1ee0 | 2002-10-04 17:58:04 +0000 | [diff] [blame] | 141 | |
Igor Sysoev | a6717c4 | 2002-12-23 06:29:22 +0000 | [diff] [blame] | 142 | if (nchanges > 0 |
| 143 | && ev->index < nchanges |
Igor Sysoev | 6b863e3 | 2003-05-12 15:52:24 +0000 | [diff] [blame^] | 144 | && (void *) ((uintptr_t) change_list[ev->index].udata & ~1) == ev) |
Igor Sysoev | 8809257 | 2002-12-19 07:08:55 +0000 | [diff] [blame] | 145 | { |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 146 | #if (NGX_DEBUG_EVENT) |
Igor Sysoev | a6717c4 | 2002-12-23 06:29:22 +0000 | [diff] [blame] | 147 | ngx_connection_t *c = (ngx_connection_t *) ev->data; |
| 148 | ngx_log_debug(ev->log, "kqueue del event: %d: ft:%d" _ c->fd _ event); |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 149 | #endif |
Igor Sysoev | dc479b4 | 2003-03-20 16:09:44 +0000 | [diff] [blame] | 150 | |
| 151 | /* if the event is still not passed to a kernel we will not pass it */ |
| 152 | |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame] | 153 | if (ev->index < --nchanges) { |
| 154 | e = (ngx_event_t *) change_list[nchanges].udata; |
| 155 | change_list[ev->index] = change_list[nchanges]; |
| 156 | e->index = ev->index; |
| 157 | } |
Igor Sysoev | 2ba1ee0 | 2002-10-04 17:58:04 +0000 | [diff] [blame] | 158 | |
| 159 | return NGX_OK; |
| 160 | } |
| 161 | |
Igor Sysoev | 6b863e3 | 2003-05-12 15:52:24 +0000 | [diff] [blame^] | 162 | /* when the file descriptor is closed a kqueue automatically deletes |
| 163 | its filters so we do not need to delete explicity the event |
| 164 | before the closing the file descriptor */ |
Igor Sysoev | dc479b4 | 2003-03-20 16:09:44 +0000 | [diff] [blame] | 165 | |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 166 | if (flags & NGX_CLOSE_EVENT) { |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame] | 167 | return NGX_OK; |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 168 | } |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame] | 169 | |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 170 | return ngx_kqueue_set_event(ev, event, EV_DELETE); |
| 171 | } |
| 172 | |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame] | 173 | |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 174 | int ngx_kqueue_set_event(ngx_event_t *ev, int filter, u_int flags) |
| 175 | { |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 176 | struct timespec ts; |
| 177 | ngx_connection_t *c; |
Igor Sysoev | 8809257 | 2002-12-19 07:08:55 +0000 | [diff] [blame] | 178 | |
Igor Sysoev | a6717c4 | 2002-12-23 06:29:22 +0000 | [diff] [blame] | 179 | c = (ngx_connection_t *) ev->data; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 180 | |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 181 | #if (NGX_DEBUG_EVENT) |
Igor Sysoev | 1af7c82 | 2002-09-13 14:47:42 +0000 | [diff] [blame] | 182 | ngx_log_debug(ev->log, "kqueue set event: %d: ft:%d f:%08x" _ |
Igor Sysoev | a6717c4 | 2002-12-23 06:29:22 +0000 | [diff] [blame] | 183 | c->fd _ filter _ flags); |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 184 | #endif |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 185 | |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 186 | if (nchanges >= KQUEUE_NCHANGES) { |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 187 | ngx_log_error(NGX_LOG_WARN, ev->log, 0, |
Igor Sysoev | 31f8818 | 2002-09-27 15:05:29 +0000 | [diff] [blame] | 188 | "kqueue change list is filled up"); |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 189 | |
Igor Sysoev | 8809257 | 2002-12-19 07:08:55 +0000 | [diff] [blame] | 190 | ts.tv_sec = 0; |
| 191 | ts.tv_nsec = 0; |
| 192 | |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 193 | if (kevent(kq, change_list, nchanges, NULL, 0, &ts) == -1) { |
Igor Sysoev | 1af7c82 | 2002-09-13 14:47:42 +0000 | [diff] [blame] | 194 | ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, "kevent failed"); |
| 195 | return NGX_ERROR; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 196 | } |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 197 | |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 198 | nchanges = 0; |
| 199 | } |
| 200 | |
Igor Sysoev | a6717c4 | 2002-12-23 06:29:22 +0000 | [diff] [blame] | 201 | change_list[nchanges].ident = c->fd; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 202 | change_list[nchanges].filter = filter; |
| 203 | change_list[nchanges].flags = flags; |
Igor Sysoev | 6b863e3 | 2003-05-12 15:52:24 +0000 | [diff] [blame^] | 204 | change_list[nchanges].udata = (void *) ((uintptr_t) ev | ev->instance); |
Igor Sysoev | 6a644c6 | 2003-03-04 06:33:48 +0000 | [diff] [blame] | 205 | |
| 206 | #if (HAVE_LOWAT_EVENT) |
| 207 | |
| 208 | if ((flags & EV_ADD) && ev->lowat > 0) { |
| 209 | change_list[nchanges].fflags = NOTE_LOWAT; |
| 210 | change_list[nchanges].data = ev->lowat; |
| 211 | |
| 212 | } else { |
| 213 | change_list[nchanges].fflags = 0; |
| 214 | change_list[nchanges].data = 0; |
| 215 | } |
| 216 | |
| 217 | #else |
| 218 | |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 219 | change_list[nchanges].fflags = 0; |
| 220 | change_list[nchanges].data = 0; |
Igor Sysoev | 6a644c6 | 2003-03-04 06:33:48 +0000 | [diff] [blame] | 221 | |
| 222 | #endif |
Igor Sysoev | 2ba1ee0 | 2002-10-04 17:58:04 +0000 | [diff] [blame] | 223 | |
Igor Sysoev | 0d2bda5 | 2002-12-24 07:09:57 +0000 | [diff] [blame] | 224 | ev->index = nchanges; |
Igor Sysoev | 2ba1ee0 | 2002-10-04 17:58:04 +0000 | [diff] [blame] | 225 | |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 226 | nchanges++; |
| 227 | |
Igor Sysoev | 1af7c82 | 2002-09-13 14:47:42 +0000 | [diff] [blame] | 228 | return NGX_OK; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 229 | } |
| 230 | |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame] | 231 | |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 232 | int ngx_kqueue_process_events(ngx_log_t *log) |
| 233 | { |
Igor Sysoev | 6b863e3 | 2003-05-12 15:52:24 +0000 | [diff] [blame^] | 234 | int events, instance, i; |
Igor Sysoev | 9b25d69 | 2003-01-26 21:08:14 +0000 | [diff] [blame] | 235 | ngx_msec_t timer, delta; |
Igor Sysoev | d4324e6 | 2002-09-17 17:49:32 +0000 | [diff] [blame] | 236 | ngx_event_t *ev; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 237 | struct timeval tv; |
Igor Sysoev | 42feecb | 2002-12-15 06:25:09 +0000 | [diff] [blame] | 238 | struct timespec ts, *tp; |
| 239 | |
Igor Sysoev | 404326f | 2003-01-24 06:20:47 +0000 | [diff] [blame] | 240 | timer = ngx_event_find_timer(); |
| 241 | |
| 242 | if (timer) { |
| 243 | ts.tv_sec = timer / 1000; |
| 244 | ts.tv_nsec = (timer % 1000) * 1000000; |
| 245 | tp = &ts; |
| 246 | gettimeofday(&tv, NULL); |
| 247 | delta = tv.tv_sec * 1000 + tv.tv_usec / 1000; |
| 248 | |
| 249 | } else { |
| 250 | timer = 0; |
| 251 | delta = 0; |
| 252 | tp = NULL; |
| 253 | } |
| 254 | |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 255 | #if (NGX_DEBUG_EVENT) |
Igor Sysoev | 1af7c82 | 2002-09-13 14:47:42 +0000 | [diff] [blame] | 256 | ngx_log_debug(log, "kevent timer: %d" _ timer); |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 257 | #endif |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 258 | |
Igor Sysoev | 1af7c82 | 2002-09-13 14:47:42 +0000 | [diff] [blame] | 259 | events = kevent(kq, change_list, nchanges, event_list, nevents, tp); |
Igor Sysoev | 8809257 | 2002-12-19 07:08:55 +0000 | [diff] [blame] | 260 | |
Igor Sysoev | 1af7c82 | 2002-09-13 14:47:42 +0000 | [diff] [blame] | 261 | if (events == -1) { |
| 262 | ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "kevent failed"); |
| 263 | return NGX_ERROR; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 264 | } |
| 265 | |
| 266 | nchanges = 0; |
| 267 | |
| 268 | if (timer) { |
| 269 | gettimeofday(&tv, NULL); |
| 270 | delta = tv.tv_sec * 1000 + tv.tv_usec / 1000 - delta; |
| 271 | |
Igor Sysoev | dc479b4 | 2003-03-20 16:09:44 +0000 | [diff] [blame] | 272 | /* Expired timers must be deleted before the events processing |
| 273 | because the new timers can be added during the processing */ |
| 274 | |
| 275 | ngx_event_expire_timers(delta); |
| 276 | |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 277 | } else { |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 278 | if (events == 0) { |
| 279 | ngx_log_error(NGX_LOG_ALERT, log, 0, |
| 280 | "kevent returns no events without timeout"); |
| 281 | return NGX_ERROR; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 282 | } |
| 283 | } |
| 284 | |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 285 | #if (NGX_DEBUG_EVENT) |
| 286 | ngx_log_debug(log, "kevent timer: %d, delta: %d" _ timer _ delta); |
| 287 | #endif |
| 288 | |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 289 | for (i = 0; i < events; i++) { |
| 290 | |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 291 | #if (NGX_DEBUG_EVENT) |
Igor Sysoev | 7300977 | 2003-02-06 17:21:13 +0000 | [diff] [blame] | 292 | if (event_list[i].ident > 0x8000000) { |
| 293 | ngx_log_debug(log, |
| 294 | "kevent: %08x: ft:%d f:%08x ff:%08x d:%d ud:%08x" _ |
| 295 | event_list[i].ident _ event_list[i].filter _ |
| 296 | event_list[i].flags _ event_list[i].fflags _ |
| 297 | event_list[i].data _ event_list[i].udata); |
| 298 | } else { |
| 299 | ngx_log_debug(log, |
| 300 | "kevent: %d: ft:%d f:%08x ff:%08x d:%d ud:%08x" _ |
| 301 | event_list[i].ident _ event_list[i].filter _ |
| 302 | event_list[i].flags _ event_list[i].fflags _ |
| 303 | event_list[i].data _ event_list[i].udata); |
| 304 | } |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 305 | #endif |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 306 | |
| 307 | if (event_list[i].flags & EV_ERROR) { |
| 308 | ngx_log_error(NGX_LOG_ALERT, log, event_list[i].data, |
Igor Sysoev | 1af7c82 | 2002-09-13 14:47:42 +0000 | [diff] [blame] | 309 | "kevent error on %d", event_list[i].ident); |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 310 | continue; |
| 311 | } |
| 312 | |
| 313 | ev = (ngx_event_t *) event_list[i].udata; |
Igor Sysoev | 6b863e3 | 2003-05-12 15:52:24 +0000 | [diff] [blame^] | 314 | instance = (uintptr_t) ev & 1; |
| 315 | ev = (void *) ((uintptr_t) ev & ~1); |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 316 | |
Igor Sysoev | 6b863e3 | 2003-05-12 15:52:24 +0000 | [diff] [blame^] | 317 | /* It's a stale event from a file descriptor |
Igor Sysoev | dc479b4 | 2003-03-20 16:09:44 +0000 | [diff] [blame] | 318 | that was just closed in this iteration */ |
| 319 | |
Igor Sysoev | 6b863e3 | 2003-05-12 15:52:24 +0000 | [diff] [blame^] | 320 | if (ev->active == 0 || ev->instance != instance) { |
| 321 | ngx_log_debug(log, "stale kevent"); |
| 322 | continue; |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 323 | } |
| 324 | |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 325 | switch (event_list[i].filter) { |
| 326 | |
| 327 | case EVFILT_READ: |
| 328 | case EVFILT_WRITE: |
Igor Sysoev | dc479b4 | 2003-03-20 16:09:44 +0000 | [diff] [blame] | 329 | |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 330 | ev->available = event_list[i].data; |
| 331 | |
| 332 | if (event_list[i].flags & EV_EOF) { |
| 333 | ev->eof = 1; |
| 334 | ev->error = event_list[i].fflags; |
| 335 | } |
| 336 | |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 337 | if (ev->oneshot) { |
Igor Sysoev | 3a40d48 | 2002-09-12 14:42:29 +0000 | [diff] [blame] | 338 | ngx_del_timer(ev); |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 339 | } |
Igor Sysoev | 3a40d48 | 2002-09-12 14:42:29 +0000 | [diff] [blame] | 340 | |
Igor Sysoev | 7300977 | 2003-02-06 17:21:13 +0000 | [diff] [blame] | 341 | /* fall through */ |
| 342 | |
| 343 | case EVFILT_AIO: |
| 344 | ev->ready = 1; |
| 345 | |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 346 | if (ev->event_handler(ev) == NGX_ERROR) { |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 347 | ev->close_handler(ev); |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 348 | } |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 349 | |
| 350 | break; |
| 351 | |
Igor Sysoev | 7300977 | 2003-02-06 17:21:13 +0000 | [diff] [blame] | 352 | |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 353 | default: |
Igor Sysoev | 3a17f24 | 2002-12-24 17:30:59 +0000 | [diff] [blame] | 354 | ngx_log_error(NGX_LOG_ALERT, log, 0, |
| 355 | "unknown kevent filter %d" _ event_list[i].filter); |
| 356 | } |
| 357 | } |
| 358 | |
Igor Sysoev | 1af7c82 | 2002-09-13 14:47:42 +0000 | [diff] [blame] | 359 | return NGX_OK; |
Igor Sysoev | 6de5c2c | 2002-08-06 16:39:45 +0000 | [diff] [blame] | 360 | } |