21
21
#include "includes.h"
22
#include <tevent_internal.h>
24
void event_fd_set_writeable(struct tevent_fd *fde)
26
TEVENT_FD_WRITEABLE(fde);
29
void event_fd_set_not_writeable(struct tevent_fd *fde)
31
TEVENT_FD_NOT_WRITEABLE(fde);
34
void event_fd_set_readable(struct tevent_fd *fde)
36
TEVENT_FD_READABLE(fde);
39
void event_fd_set_not_readable(struct tevent_fd *fde)
41
TEVENT_FD_NOT_READABLE(fde);
45
* Return if there's something in the queue
48
bool event_add_to_select_args(struct tevent_context *ev,
49
const struct timeval *now,
50
fd_set *read_fds, fd_set *write_fds,
51
struct timeval *timeout, int *maxfd)
53
struct tevent_fd *fde;
22
#include "lib/tevent/tevent_internal.h"
23
#include "../lib/util/select.h"
24
#include "system/select.h"
26
struct tevent_poll_private {
28
* Index from file descriptor into the pollfd array
33
* Cache for s3_event_loop_once to avoid reallocs
38
static struct tevent_poll_private *tevent_get_poll_private(
39
struct tevent_context *ev)
41
struct tevent_poll_private *state;
43
state = (struct tevent_poll_private *)ev->additional_data;
45
state = TALLOC_ZERO_P(ev, struct tevent_poll_private);
46
ev->additional_data = (void *)state;
48
DEBUG(10, ("talloc failed\n"));
54
static void count_fds(struct tevent_context *ev,
55
int *pnum_fds, int *pmax_fd)
57
struct tevent_fd *fde;
61
for (fde = ev->fd_events; fde != NULL; fde = fde->next) {
62
if (fde->flags & (EVENT_FD_READ|EVENT_FD_WRITE)) {
64
if (fde->fd > max_fd) {
73
bool event_add_to_poll_args(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
74
struct pollfd **pfds, int *pnum_pfds,
77
struct tevent_poll_private *state;
78
struct tevent_fd *fde;
79
int i, num_fds, max_fd, num_pollfds, idx_len;
81
struct timeval now, diff;
84
state = tevent_get_poll_private(ev);
88
count_fds(ev, &num_fds, &max_fd);
92
if (talloc_array_length(state->pollfd_idx) < idx_len) {
93
state->pollfd_idx = TALLOC_REALLOC_ARRAY(
94
state, state->pollfd_idx, int, idx_len);
95
if (state->pollfd_idx == NULL) {
96
DEBUG(10, ("talloc_realloc failed\n"));
102
num_pollfds = *pnum_pfds;
105
* The +1 is for the sys_poll calling convention. It expects
106
* an array 1 longer for the signal pipe
109
if (talloc_array_length(fds) < num_pollfds + num_fds + 1) {
110
fds = TALLOC_REALLOC_ARRAY(mem_ctx, fds, struct pollfd,
111
num_pollfds + num_fds + 1);
113
DEBUG(10, ("talloc_realloc failed\n"));
118
memset(&fds[num_pollfds], 0, sizeof(struct pollfd) * num_fds);
121
* This needs tuning. We need to cope with multiple fde's for a file
122
* descriptor. The problem is that we need to re-use pollfd_idx across
123
* calls for efficiency. One way would be a direct bitmask that might
124
* be initialized quicker, but our bitmap_init implementation is
125
* pretty heavy-weight as well.
127
for (i=0; i<idx_len; i++) {
128
state->pollfd_idx[i] = -1;
57
131
for (fde = ev->fd_events; fde; fde = fde->next) {
58
if (fde->fd < 0 || fde->fd >= FD_SETSIZE) {
59
/* We ignore here, as it shouldn't be
60
possible to add an invalid fde->fd
61
but we don't want FD_SET to see an
134
if ((fde->flags & (EVENT_FD_READ|EVENT_FD_WRITE)) == 0) {
138
if (state->pollfd_idx[fde->fd] == -1) {
140
* We haven't seen this fd yet. Allocate a new pollfd.
142
state->pollfd_idx[fde->fd] = num_pollfds;
143
pfd = &fds[num_pollfds];
147
* We have already seen this fd. OR in the flags.
149
pfd = &fds[state->pollfd_idx[fde->fd]];
66
154
if (fde->flags & EVENT_FD_READ) {
67
FD_SET(fde->fd, read_fds);
155
pfd->events |= (POLLIN|POLLHUP);
70
157
if (fde->flags & EVENT_FD_WRITE) {
71
FD_SET(fde->fd, write_fds);
75
if ((fde->flags & (EVENT_FD_READ|EVENT_FD_WRITE))
76
&& (fde->fd > *maxfd)) {
158
pfd->events |= POLLOUT;
162
*pnum_pfds = num_pollfds;
81
164
if (ev->immediate_events != NULL) {
82
*timeout = timeval_zero();
86
168
if (ev->timer_events == NULL) {
90
diff = timeval_until(now, &ev->timer_events->next_event);
91
*timeout = timeval_min(timeout, &diff);
169
*ptimeout = MIN(*ptimeout, INT_MAX);
173
now = timeval_current();
174
diff = timeval_until(&now, &ev->timer_events->next_event);
175
timeout = timeval_to_msec(diff);
177
if (timeout < *ptimeout) {
96
bool run_events(struct tevent_context *ev,
97
int selrtn, fd_set *read_fds, fd_set *write_fds)
184
bool run_events_poll(struct tevent_context *ev, int pollrtn,
185
struct pollfd *pfds, int num_pfds)
187
struct tevent_poll_private *state;
99
189
struct tevent_fd *fde;
100
190
struct timeval now;
239
state = (struct tevent_poll_private *)ev->additional_data;
240
pollfd_idx = state->pollfd_idx;
149
242
for (fde = ev->fd_events; fde; fde = fde->next) {
150
244
uint16 flags = 0;
152
if (FD_ISSET(fde->fd, read_fds)) flags |= EVENT_FD_READ;
153
if (FD_ISSET(fde->fd, write_fds)) flags |= EVENT_FD_WRITE;
246
if ((fde->flags & (EVENT_FD_READ|EVENT_FD_WRITE)) == 0) {
250
if (pollfd_idx[fde->fd] >= num_pfds) {
251
DEBUG(1, ("internal error: pollfd_idx[fde->fd] (%d) "
252
">= num_pfds (%d)\n", pollfd_idx[fde->fd],
256
pfd = &pfds[pollfd_idx[fde->fd]];
258
if (pfd->fd != fde->fd) {
259
DEBUG(1, ("internal error: pfd->fd (%d) "
260
"!= fde->fd (%d)\n", pollfd_idx[fde->fd],
265
if (pfd->revents & (POLLHUP|POLLERR)) {
266
/* If we only wait for EVENT_FD_WRITE, we
267
should not tell the event handler about it,
268
and remove the writable flag, as we only
269
report errors when waiting for read events
270
to match the select behavior. */
271
if (!(fde->flags & EVENT_FD_READ)) {
272
EVENT_FD_NOT_WRITEABLE(fde);
275
flags |= EVENT_FD_READ;
278
if (pfd->revents & POLLIN) {
279
flags |= EVENT_FD_READ;
281
if (pfd->revents & POLLOUT) {
282
flags |= EVENT_FD_WRITE;
155
284
if (flags & fde->flags) {
156
DLIST_DEMOTE(ev->fd_events, fde, struct tevent_fd *);
285
DLIST_DEMOTE(ev->fd_events, fde, struct tevent_fd);
157
286
fde->handler(ev, fde, flags, fde->private_data);
188
316
static int s3_event_loop_once(struct tevent_context *ev, const char *location)
190
struct timeval now, to;
318
struct tevent_poll_private *state;
198
to.tv_sec = 9999; /* Max timeout */
201
if (run_events(ev, 0, NULL, NULL)) {
325
state = tevent_get_poll_private(ev);
331
if (run_events_poll(ev, 0, NULL, 0)) {
207
if (!event_add_to_select_args(ev, &now, &r_fds, &w_fds, &to, &maxfd)) {
336
if (!event_add_to_poll_args(ev, state,
337
&state->pfds, &num_pfds, &timeout)) {
211
ret = sys_select(maxfd+1, &r_fds, &w_fds, NULL, &to);
341
ret = sys_poll(state->pfds, num_pfds, timeout);
213
342
if (ret == -1 && errno != EINTR) {
214
343
tevent_debug(ev, TEVENT_DEBUG_FATAL,
215
"sys_select() failed: %d:%s\n",
344
"poll() failed: %d:%s\n",
216
345
errno, strerror(errno));
220
run_events(ev, ret, &r_fds, &w_fds);
349
run_events_poll(ev, ret, state->pfds, num_pfds);
224
void event_context_reinit(struct tevent_context *ev)
226
tevent_common_context_destructor(ev);
230
353
static int s3_event_context_init(struct tevent_context *ev)