dns: simplify code by reaping dns child as soon as we have answers.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2016-11-04 11:17:03 +10:30
parent 78a0177f1c
commit 4c7017f607
1 changed files with 20 additions and 18 deletions

View File

@ -16,7 +16,6 @@
#include <sys/wait.h>
struct dns_async {
size_t use;
struct lightningd_state *dstate;
struct io_plan *(*init)(struct io_conn *, struct lightningd_state *,
void *);
@ -72,11 +71,15 @@ static void lookup_and_write(int fd, const char *name, const char *port)
static struct io_plan *connected(struct io_conn *conn, struct dns_async *d)
{
/* No longer need to try more connections. */
struct io_plan *plan;
/* No longer need to try more connections via connect_failed. */
io_set_finish(conn, NULL, NULL);
/* Keep use count, so reap_child won't fail. */
return d->init(conn, d->dstate, d->arg);
plan = d->init(conn, d->dstate, d->arg);
tal_free(d);
return plan;
}
static void try_connect_one(struct dns_async *d);
@ -100,7 +103,6 @@ static struct io_plan *init_conn(struct io_conn *conn, struct dns_async *d)
io_set_finish(conn, connect_failed, d);
/* That new connection owns d */
tal_steal(conn, d);
return io_connect(conn, &a, connected, d);
}
@ -132,8 +134,8 @@ static void try_connect_one(struct dns_async *d)
}
/* We're out of things to try. Fail. */
if (--d->use == 0)
d->fail(d->dstate, d->arg);
d->fail(d->dstate, d->arg);
tal_free(d);
}
static struct io_plan *start_connecting(struct io_conn *conn,
@ -141,9 +143,12 @@ static struct io_plan *start_connecting(struct io_conn *conn,
{
assert(d->num_addresses);
/* reap_child and our connections can race: only last one should call
* fail. */
d->use++;
/* OK, we've read all we want, child should exit. */
waitpid(d->pid, NULL, 0);
/* No need to call dns_lookup_failed now. */
io_set_finish(conn, NULL, NULL);
try_connect_one(d);
return io_close(conn);
}
@ -162,12 +167,11 @@ static struct io_plan *init_dns_conn(struct io_conn *conn, struct dns_async *d)
read_addresses, d);
}
static void reap_child(struct io_conn *conn, struct dns_async *d)
static void dns_lookup_failed(struct io_conn *conn, struct dns_async *d)
{
waitpid(d->pid, NULL, 0);
/* Last user calls fail. */
if (--d->use == 0)
d->fail(d->dstate, d->arg);
d->fail(d->dstate, d->arg);
tal_free(d);
}
struct dns_async *dns_resolve_and_connect_(struct lightningd_state *dstate,
@ -179,7 +183,7 @@ struct dns_async *dns_resolve_and_connect_(struct lightningd_state *dstate,
void *arg)
{
int pfds[2];
struct dns_async *d = tal(NULL, struct dns_async);
struct dns_async *d = tal(dstate, struct dns_async);
struct io_conn *conn;
d->dstate = dstate;
@ -212,9 +216,7 @@ struct dns_async *dns_resolve_and_connect_(struct lightningd_state *dstate,
}
close(pfds[1]);
d->use = 1;
conn = io_new_conn(dstate, pfds[0], init_dns_conn, d);
io_set_finish(conn, reap_child, d);
tal_steal(conn, d);
io_set_finish(conn, dns_lookup_failed, d);
return d;
}