Merge remote-tracking branch 'origin/patches-2.0'

This commit is contained in:
Nick Mathewson 2011-05-03 14:29:44 -04:00
commit 9610797471
2 changed files with 55 additions and 15 deletions

View File

@ -227,6 +227,23 @@ kq_build_changes_list(const struct event_changelist *changelist,
return n_changes;
}
static int
kq_grow_events(struct kqop *kqop, size_t new_size)
{
struct kevent *newresult;
newresult = mm_realloc(kqop->events,
new_size * sizeof(struct kevent));
if (newresult) {
kqop->events = newresult;
kqop->events_size = new_size;
return 0;
} else {
return -1;
}
}
static int
kq_dispatch(struct event_base *base, struct timeval *tv)
{
@ -254,6 +271,25 @@ kq_dispatch(struct event_base *base, struct timeval *tv)
changes = kqop->changes;
kqop->changes = NULL;
/* Make sure that 'events' is at least as long as the list of changes:
* otherwise errors in the changes can get reported as a -1 return
* value from kevent() rather than as EV_ERROR events in the events
* array.
*
* (We could instead handle -1 return values from kevent() by
* retrying with a smaller changes array or a larger events array,
* but this approach seems less risky for now.)
*/
if (kqop->events_size < n_changes) {
int new_size = kqop->events_size;
do {
new_size *= 2;
} while (new_size < n_changes);
kq_grow_events(kqop, new_size);
events = kqop->events;
}
EVBASE_RELEASE_LOCK(base, th_base_lock);
res = kevent(kqop->kq, changes, n_changes,
@ -318,17 +354,9 @@ kq_dispatch(struct event_base *base, struct timeval *tv)
}
if (res == kqop->events_size) {
struct kevent *newresult;
int size = kqop->events_size;
/* We used all the events space that we have. Maybe we should
make it bigger. */
size *= 2;
newresult = mm_realloc(kqop->events,
size * sizeof(struct kevent));
if (newresult) {
kqop->events = newresult;
kqop->events_size = size;
}
kq_grow_events(kqop, kqop->events_size * 2);
}
return (0);

View File

@ -2204,7 +2204,7 @@ many_event_cb(evutil_socket_t fd, short event, void *arg)
static void
test_many_events(void *arg)
{
/* Try 70 events that should all be aready at once. This will
/* Try 70 events that should all be ready at once. This will
* exercise the "resize" code on most of the backends, and will make
* sure that we can get past the 64-handle limit of some windows
* functions. */
@ -2212,10 +2212,16 @@ test_many_events(void *arg)
struct basic_test_data *data = arg;
struct event_base *base = data->base;
int one_at_a_time = data->setup_data != NULL;
evutil_socket_t sock[MANY];
struct event *ev[MANY];
int called[MANY];
int i;
int loopflags = EVLOOP_NONBLOCK, evflags=0;
if (one_at_a_time) {
loopflags |= EVLOOP_ONCE;
evflags = EV_PERSIST;
}
memset(sock, 0xff, sizeof(sock));
memset(ev, 0, sizeof(ev));
@ -2228,15 +2234,20 @@ test_many_events(void *arg)
sock[i] = socket(AF_INET, SOCK_DGRAM, 0);
tt_assert(sock[i] >= 0);
called[i] = 0;
ev[i] = event_new(base, sock[i], EV_WRITE, many_event_cb,
&called[i]);
ev[i] = event_new(base, sock[i], EV_WRITE|evflags,
many_event_cb, &called[i]);
event_add(ev[i], NULL);
if (one_at_a_time)
event_base_loop(base, EVLOOP_NONBLOCK|EVLOOP_ONCE);
}
event_base_loop(base, EVLOOP_NONBLOCK);
event_base_loop(base, loopflags);
for (i = 0; i < MANY; ++i) {
tt_int_op(called[i], ==, 1);
if (one_at_a_time)
tt_int_op(called[i], ==, MANY - i + 1);
else
tt_int_op(called[i], ==, 1);
}
end:
@ -2303,7 +2314,8 @@ struct testcase_t main_testcases[] = {
{ "dup_fd", test_dup_fd, TT_ISOLATED, &basic_setup, NULL },
#endif
{ "mm_functions", test_mm_functions, TT_FORK, NULL, NULL },
BASIC(many_events, TT_ISOLATED),
{ "many_events", test_many_events, TT_ISOLATED, &basic_setup, NULL },
{ "many_events_slow_add", test_many_events, TT_ISOLATED, &basic_setup, (void*)1 },
{ "struct_event_size", test_struct_event_size, 0, NULL, NULL },