@@ -125,9 +125,13 @@ cc -I/usr/local/include -o example_ev example_ev.c -Wl,-rpath /usr/local/lib -lc
125
125
#include <ares.h>
126
126
127
127
typedef struct {
128
- ares_channel_t * channel;
129
- struct pollfd * fds;
130
- size_t nfds;
128
+ ares_channel_t * channel;
129
+ struct pollfd * poll_fds;
130
+ size_t poll_nfds;
131
+ size_t poll_fds_alloc;
132
+
133
+ ares_fd_events_t * ares_fds;
134
+ size_t ares_nfds;
131
135
} dnsstate_t;
132
136
133
137
void sock_state_cb(void * data, ares_socket_t socket_fd, int readable, int writable)
@@ -136,40 +140,49 @@ void sock_state_cb(void *data, ares_socket_t socket_fd, int readable, int writab
136
140
size_t idx;
137
141
138
142
/* Find match * /
139
- for (idx=0; idx<state- >nfds ; idx++) {
140
- if (state->fds [ idx] .fd == socket_fd) {
143
+ for (idx=0; idx<state- >poll_nfds ; idx++) {
144
+ if (state->poll_fds [ idx] .fd == socket_fd) {
141
145
break;
142
146
}
143
147
}
144
148
145
149
/* Not found * /
146
- if (idx >= state->nfds ) {
150
+ if (idx >= state->poll_nfds ) {
147
151
/* Do nothing * /
148
152
if (!readable && !writable) {
149
153
return;
150
154
}
151
155
152
156
/* Add */
153
- state->nfds++;
154
- state->fds = realloc(state->fds, sizeof(*state->fds) * state->nfds);
157
+ state->poll_nfds++;
158
+ if (state->poll_nfds > state->poll_fds_alloc) {
159
+ state->poll_fds_alloc = state->poll_nfds;
160
+
161
+ state->poll_fds = realloc(state->poll_fds,
162
+ sizeof(*state->poll_fds) * state->poll_nfds);
163
+
164
+ /* Make the ares_fds the same size */
165
+ state->ares_fds = realloc(state->ares_fds,
166
+ sizeof(*state->ares_fds) * state->poll_nfds);
167
+ }
155
168
} else {
156
169
/* Remove * /
157
170
if (!readable && !writable) {
158
- memmove(&state->fds [ idx] , &state->fds [ idx+1] ,
159
- sizeof(* state->fds ) * (state->nfds - idx - 1));
160
- state->nfds --;
171
+ memmove(&state->poll_fds [ idx] , &state->poll_fds [ idx+1] ,
172
+ sizeof(* state->poll_fds ) * (state->poll_nfds - idx - 1));
173
+ state->poll_nfds --;
161
174
return;
162
175
}
163
176
}
164
177
165
178
/* Update Poll Events (including on Add) * /
166
- state->fds [ idx] .fd = socket_fd;
167
- state->fds [ idx] .events = 0;
179
+ state->poll_fds [ idx] .fd = socket_fd;
180
+ state->poll_fds [ idx] .events = 0;
168
181
if (readable) {
169
- state->fds [ idx] .events |= POLLIN;
182
+ state->poll_fds [ idx] .events |= POLLIN;
170
183
}
171
184
if (writable) {
172
- state->fds [ idx] .events |= POLLOUT;
185
+ state->poll_fds [ idx] .events |= POLLOUT;
173
186
}
174
187
}
175
188
@@ -181,8 +194,6 @@ void process(dnsstate_t *state)
181
194
int rv;
182
195
int timeout;
183
196
size_t i;
184
- struct pollfd * fds;
185
- size_t nfds;
186
197
187
198
/* Since we don't have any other program state to wait on, we'll just
188
199
* stop looping when we know there are no remaining queries, which is
@@ -193,7 +204,7 @@ void process(dnsstate_t *state)
193
204
194
205
timeout = tv.tv_sec * 1000 + tv.tv_usec / 1000;
195
206
196
- rv = poll(state->fds , state->nfds , timeout);
207
+ rv = poll(state->poll_fds , state->poll_nfds , timeout);
197
208
if (rv < 0) {
198
209
continue;
199
210
} else if (rv == 0) {
@@ -202,24 +213,29 @@ void process(dnsstate_t *state)
202
213
continue;
203
214
}
204
215
205
- /* Duplicate fds structure as calling into ares_process_fd() may manipulate
206
- * the one contained in state */
207
- nfds = state->nfds;
208
- fds = malloc(sizeof(*fds) * nfds);
209
- memcpy(fds, state->fds, sizeof(*fds) * nfds);
210
-
211
- for (i=0; i<nfds; i++) {
212
- if (fds[i].revents == 0) {
216
+ /* Form our notification array */
217
+ state->ares_nfds = 0;
218
+ for (i=0; i<state->poll_nfds; i++) {
219
+ size_t idx;
220
+ if (state->poll_fds[i].revents == 0) {
213
221
continue;
214
222
}
215
223
216
- /* Notify about read/write events per FD */
217
- ares_process_fd(state->channel,
218
- (fds[i].revents & (POLLERR|POLLHUP|POLLIN))?fds[i].fd:ARES_SOCKET_BAD,
219
- (fds[i].revents & POLLOUT)?fds[i].fd:ARES_SOCKET_BAD);
224
+ idx = state->ares_nfds++;
225
+
226
+ state->ares_fds[idx].fd = state->poll_fds[i].fd;
227
+ state->ares_fds[idx].events = 0;
228
+ if (state->poll_fds[i].revents & (POLLERR|POLLHUP|POLLIN)) {
229
+ state->ares_fds[idx].events |= ARES_FD_EVENT_READ;
230
+ }
231
+ if (state->poll_fds[i].revents & POLLOUT) {
232
+ state->ares_fds[idx].events |= ARES_FD_EVENT_WRITE;
233
+ }
220
234
}
221
235
222
- free(fds);
236
+ /* Notify about read/write events per FD */
237
+ ares_process_fds(state->channel, state->ares_fds, state->ares_nfds,
238
+ ARES_PROCESS_FLAG_NONE);
223
239
}
224
240
}
225
241
@@ -296,7 +312,8 @@ int main(int argc, char **argv)
296
312
297
313
/* Cleanup * /
298
314
ares_destroy(state.channel);
299
- free(state.fds);
315
+ free(state.poll_fds);
316
+ free(state.ares_fds);
300
317
301
318
ares_library_cleanup();
302
319
return 0;
0 commit comments