mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-09 12:28:19 -04:00
Fix a race condition in the dns/bufferevent_connect_hostname test.
As originally written, the test would only pass if the accept() callbacks for the evconnlistener were all invoked before the last of the CONNECTED/ERROR callbacks for the connecting/resolving bufferevent had its call to event_base_loopexit() complete. But this was only accidentally true in 2.0, and might not be true at all in 2.1 where we schedule event_base_once() callbacks more aggressively. Found by Sebastian Hahn.
This commit is contained in:
parent
ecfc720a4f
commit
cba48c7d46
@ -862,6 +862,7 @@ end:
|
|||||||
/* === Test for bufferevent_socket_connect_hostname */
|
/* === Test for bufferevent_socket_connect_hostname */
|
||||||
|
|
||||||
static int total_connected_or_failed = 0;
|
static int total_connected_or_failed = 0;
|
||||||
|
static int total_n_accepted = 0;
|
||||||
static struct event_base *be_connect_hostname_base = NULL;
|
static struct event_base *be_connect_hostname_base = NULL;
|
||||||
|
|
||||||
/* Implements a DNS server for the connect_hostname test and the
|
/* Implements a DNS server for the connect_hostname test and the
|
||||||
@ -995,7 +996,11 @@ nil_accept_cb(struct evconnlistener *l, evutil_socket_t fd, struct sockaddr *s,
|
|||||||
{
|
{
|
||||||
int *p = arg;
|
int *p = arg;
|
||||||
(*p)++;
|
(*p)++;
|
||||||
|
++total_n_accepted;
|
||||||
/* don't do anything with the socket; let it close when we exit() */
|
/* don't do anything with the socket; let it close when we exit() */
|
||||||
|
if (total_n_accepted >= 3 && total_connected_or_failed >= 5)
|
||||||
|
event_base_loopexit(be_connect_hostname_base,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct be_conn_hostname_result {
|
struct be_conn_hostname_result {
|
||||||
@ -1015,14 +1020,14 @@ be_connect_hostname_event_cb(struct bufferevent *bev, short what, void *ctx)
|
|||||||
|
|
||||||
if ((what & BEV_EVENT_CONNECTED) || (what & BEV_EVENT_ERROR)) {
|
if ((what & BEV_EVENT_CONNECTED) || (what & BEV_EVENT_ERROR)) {
|
||||||
int r;
|
int r;
|
||||||
++total_connected_or_failed;
|
|
||||||
TT_BLATHER(("Got %d connections or errors.", total_connected_or_failed));
|
|
||||||
if ((r = bufferevent_socket_get_dns_error(bev))) {
|
if ((r = bufferevent_socket_get_dns_error(bev))) {
|
||||||
got->dnserr = r;
|
got->dnserr = r;
|
||||||
TT_BLATHER(("DNS error %d: %s", r,
|
TT_BLATHER(("DNS error %d: %s", r,
|
||||||
evutil_gai_strerror(r)));
|
evutil_gai_strerror(r)));
|
||||||
}
|
} ++total_connected_or_failed;
|
||||||
if (total_connected_or_failed >= 5)
|
TT_BLATHER(("Got %d connections or errors.", total_connected_or_failed));
|
||||||
|
|
||||||
|
if (total_n_accepted >= 3 && total_connected_or_failed >= 5)
|
||||||
event_base_loopexit(be_connect_hostname_base,
|
event_base_loopexit(be_connect_hostname_base,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user