2 * Copyright (c) 2017 Gleb Smirnoff <glebius@FreeBSD.org>
3 * Copyright (c) 2002-2017 Igor Sysoev
4 * Copyright (c) 2011-2017 Nginx, Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/types.h>
30 #include <sys/select.h>
40 static event_module_init_t select_init
;
41 static event_module_fini_t select_fini
;
42 static event_module_add_t select_add
;
43 static event_module_del_t select_del
;
44 static event_module_process_t select_process
;
46 static fd_set master_read_fd_set
;
47 static fd_set master_write_fd_set
;
48 static fd_set work_read_fd_set
;
49 static fd_set work_write_fd_set
;
51 static struct event
**events
;
55 struct event_module event_module
= {
58 .process
= select_process
,
67 events
= calloc(FD_SETSIZE
, sizeof(struct event
*));
71 FD_ZERO(&master_read_fd_set
);
72 FD_ZERO(&master_write_fd_set
);
89 select_add(struct event
*ev
)
92 assert(ev
->fd
< FD_SETSIZE
);
96 FD_SET(ev
->fd
, &master_read_fd_set
);
99 FD_SET(ev
->fd
, &master_write_fd_set
);
103 if (max_fd
!= -1 && max_fd
< ev
->fd
)
106 events
[nevents
] = ev
;
107 ev
->index
= nevents
++;
109 assert(nevents
< FD_SETSIZE
);
115 select_del(struct event
*ev
, int flags
)
118 assert(ev
->fd
< FD_SETSIZE
);
122 FD_CLR(ev
->fd
, &master_read_fd_set
);
125 FD_CLR(ev
->fd
, &master_write_fd_set
);
129 if (max_fd
== ev
->fd
)
132 if (ev
->index
< --nevents
) {
135 ev0
= events
[nevents
];
136 events
[ev
->index
] = ev0
;
137 ev0
->index
= ev
->index
;
145 select_process(struct timeval
*tv
)
150 /* Need to rescan for max_fd. */
152 for (i
= 0; i
< nevents
; i
++) {
153 if (max_fd
< events
[i
]->fd
)
154 max_fd
= events
[i
]->fd
;
157 work_read_fd_set
= master_read_fd_set
;
158 work_write_fd_set
= master_write_fd_set
;
160 ready
= select(max_fd
+ 1, &work_read_fd_set
, &work_write_fd_set
, NULL
, tv
);
165 DPRINTF(E_FATAL
, L_GENERAL
, "select(): %s. EXITING\n", strerror(errno
));
171 for (i
= 0; i
< nevents
; i
++) {
176 if (FD_ISSET(ev
->fd
, &work_read_fd_set
))
180 if (FD_ISSET(ev
->fd
, &work_write_fd_set
))