Skip to content

Commit 029c62c

Browse files
committed
askrene: make "child.c" to be the explicit child entry point.
The fork logic itself is pretty simple, so do that directly in askrene.c, and then call into "run_child()" almost as soon as we do the fork. Signed-off-by: Rusty Russell <[email protected]>
1 parent e67af12 commit 029c62c

File tree

5 files changed

+103
-115
lines changed

5 files changed

+103
-115
lines changed

plugins/askrene/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ PLUGIN_ASKRENE_PARENT_SRC := \
22
plugins/askrene/askrene.c \
33
plugins/askrene/datastore_wire.c \
44
plugins/askrene/layer.c \
5-
plugins/askrene/reserve.c \
5+
plugins/askrene/reserve.c
66

77
PLUGIN_ASKRENE_CHILD_SRC := \
8-
plugins/askrene/child/entry.c \
8+
plugins/askrene/child/child.c \
99
plugins/askrene/child/mcf.c \
1010
plugins/askrene/child/dijkstra.c \
1111
plugins/askrene/child/flow.c \

plugins/askrene/askrene.c

Lines changed: 48 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99
#include "config.h"
1010
#include <ccan/array_size/array_size.h>
11+
#include <ccan/noerr/noerr.h>
1112
#include <ccan/tal/grab_file/grab_file.h>
1213
#include <ccan/tal/str/str.h>
1314
#include <common/clock_time.h>
@@ -24,7 +25,8 @@
2425
#include <math.h>
2526
#include <plugins/askrene/askrene.h>
2627
#include <plugins/askrene/child/additional_costs.h>
27-
#include <plugins/askrene/child/entry.h>
28+
#include <plugins/askrene/child/child.h>
29+
#include <plugins/askrene/child/child_log.h>
2830
#include <plugins/askrene/layer.h>
2931
#include <plugins/askrene/reserve.h>
3032
#include <sys/wait.h>
@@ -517,12 +519,11 @@ static struct command_result *do_getroutes(struct command *cmd,
517519
struct askrene *askrene = get_askrene(cmd->plugin);
518520
const char *err;
519521
struct timemono deadline;
520-
int child_fd, log_fd;
522+
int replyfds[2], logfds[2];
521523
struct router_child *child;
522524
const struct layer **layers;
523525
s8 *biases;
524526
fp16_t *capacities;
525-
int ecode;
526527

527528
/* update the gossmap */
528529
if (gossmap_refresh(askrene->gossmap)) {
@@ -594,30 +595,55 @@ static struct command_result *do_getroutes(struct command *cmd,
594595
child->start = time_mono();
595596
deadline = timemono_add(child->start,
596597
time_from_sec(askrene->route_seconds));
597-
child_fd = fork_router_child(askrene->gossmap,
598-
layers,
599-
biases,
600-
info->additional_costs,
601-
askrene->reserved,
602-
take(capacities),
603-
info->dev_algo == ALGO_SINGLE_PATH,
604-
deadline, srcnode, dstnode, info->amount,
605-
info->maxfee, info->finalcltv, info->maxdelay,
606-
info->maxparts, cmd->id, cmd->filter, &log_fd, &child->pid);
607-
/* Save this, as remove_localmods won't preserve it. */
608-
ecode = errno;
609-
/* We don't need this any more. */
610-
gossmap_remove_localmods(askrene->gossmap, localmods);
611598

612-
if (child_fd == -1) {
613-
err = tal_fmt(tmpctx, "failed to fork: %s", strerror(ecode));
614-
gossmap_remove_localmods(askrene->gossmap, localmods);
599+
if (pipe(replyfds) != 0) {
600+
err = tal_fmt(tmpctx, "failed to create pipes: %s", strerror(errno));
601+
goto fail_broken;
602+
}
603+
if (pipe(logfds) != 0) {
604+
err = tal_fmt(tmpctx, "failed to create pipes: %s", strerror(errno));
605+
close_noerr(replyfds[0]);
606+
close_noerr(replyfds[1]);
607+
goto fail_broken;
608+
}
609+
child->pid = fork();
610+
if (child->pid < 0) {
611+
err = tal_fmt(tmpctx, "failed to fork: %s", strerror(errno));
612+
close_noerr(replyfds[0]);
613+
close_noerr(replyfds[1]);
614+
close_noerr(logfds[0]);
615+
close_noerr(logfds[1]);
615616
goto fail_broken;
616617
}
617618

618-
child->reply_conn = io_new_conn(child, child_fd,
619+
if (child->pid == 0) {
620+
/* We are the child. Run the algo */
621+
close(logfds[0]);
622+
close(replyfds[0]);
623+
set_child_log_fd(logfds[1]);
624+
625+
/* Does not return! */
626+
run_child(askrene->gossmap,
627+
layers,
628+
biases,
629+
info->additional_costs,
630+
askrene->reserved,
631+
take(capacities),
632+
info->dev_algo == ALGO_SINGLE_PATH,
633+
deadline, srcnode, dstnode, info->amount,
634+
info->maxfee, info->finalcltv, info->maxdelay,
635+
info->maxparts, cmd->id, cmd->filter, replyfds[1]);
636+
abort();
637+
}
638+
639+
close(logfds[1]);
640+
close(replyfds[1]);
641+
642+
/* We don't need this any more. */
643+
gossmap_remove_localmods(askrene->gossmap, localmods);
644+
child->reply_conn = io_new_conn(child, replyfds[0],
619645
child_reply_init, child);
620-
child->log_conn = io_new_conn(child, log_fd, child_log_init, child);
646+
child->log_conn = io_new_conn(child, logfds[0], child_log_init, child);
621647
child->cmd = cmd;
622648

623649
list_add_tail(&askrene->children, &child->list);
Lines changed: 18 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
#include "config.h"
22
#include <assert.h>
33
#include <ccan/json_out/json_out.h>
4-
#include <ccan/noerr/noerr.h>
54
#include <ccan/read_write_all/read_write_all.h>
65
#include <ccan/tal/str/str.h>
76
#include <common/json_stream.h>
87
#include <common/route.h>
98
#include <common/utils.h>
9+
#include <plugins/askrene/child/child.h>
1010
#include <plugins/askrene/child/child_log.h>
11-
#include <plugins/askrene/child/entry.h>
1211
#include <plugins/askrene/child/flow.h>
1312
#include <plugins/askrene/child/mcf.h>
1413
#include <plugins/askrene/child/route_query.h>
15-
#include <unistd.h>
1614

1715
/* A single route. */
1816
struct route {
@@ -152,25 +150,22 @@ static struct route_query *new_route_query(const tal_t *ctx,
152150
return rq;
153151
}
154152

155-
/* Returns fd to child */
156-
int fork_router_child(const struct gossmap *gossmap,
157-
const struct layer **layers,
158-
const s8 *biases,
159-
const struct additional_cost_htable *additional_costs,
160-
struct reserve_htable *reserved,
161-
fp16_t *capacities TAKES,
162-
bool single_path,
163-
struct timemono deadline,
164-
const struct gossmap_node *srcnode,
165-
const struct gossmap_node *dstnode,
166-
struct amount_msat amount, struct amount_msat maxfee,
167-
u32 finalcltv, u32 maxdelay, size_t maxparts,
168-
const char *cmd_id,
169-
struct json_filter *cmd_filter,
170-
int *log_fd,
171-
int *child_pid)
153+
void run_child(const struct gossmap *gossmap,
154+
const struct layer **layers,
155+
const s8 *biases,
156+
const struct additional_cost_htable *additional_costs,
157+
struct reserve_htable *reserved,
158+
fp16_t *capacities TAKES,
159+
bool single_path,
160+
struct timemono deadline,
161+
const struct gossmap_node *srcnode,
162+
const struct gossmap_node *dstnode,
163+
struct amount_msat amount, struct amount_msat maxfee,
164+
u32 finalcltv, u32 maxdelay, size_t maxparts,
165+
const char *cmd_id,
166+
struct json_filter *cmd_filter,
167+
int replyfd)
172168
{
173-
int replyfds[2], logfds[2];
174169
double probability;
175170
struct flow **flows;
176171
struct route **routes;
@@ -179,35 +174,6 @@ int fork_router_child(const struct gossmap *gossmap,
179174
size_t len;
180175
struct route_query *rq;
181176

182-
if (pipe(replyfds) != 0)
183-
goto parent_fail;
184-
if (pipe(logfds) != 0) {
185-
close_noerr(replyfds[0]);
186-
close_noerr(replyfds[1]);
187-
goto parent_fail;
188-
}
189-
*child_pid = fork();
190-
if (*child_pid < 0) {
191-
close_noerr(replyfds[0]);
192-
close_noerr(replyfds[1]);
193-
close_noerr(logfds[0]);
194-
close_noerr(logfds[1]);
195-
goto parent_fail;
196-
}
197-
if (*child_pid != 0) {
198-
close(logfds[1]);
199-
close(replyfds[1]);
200-
*log_fd = logfds[0];
201-
if (taken(capacities))
202-
tal_free(capacities);
203-
return replyfds[0];
204-
}
205-
206-
/* We are the child. Run the algo */
207-
close(logfds[0]);
208-
close(replyfds[0]);
209-
set_child_log_fd(logfds[1]);
210-
211177
/* We exit below, so we don't bother freeing this */
212178
rq = new_route_query(NULL, gossmap, cmd_id, layers,
213179
biases, additional_costs,
@@ -222,7 +188,7 @@ int fork_router_child(const struct gossmap *gossmap,
222188
maxparts, &flows, &probability);
223189
}
224190
if (err) {
225-
write_all(replyfds[1], err, strlen(err));
191+
write_all(replyfd, err, strlen(err));
226192
/* Non-zero exit tells parent this is an error string. */
227193
exit(1);
228194
}
@@ -261,13 +227,8 @@ int fork_router_child(const struct gossmap *gossmap,
261227
json_stream_close(js, NULL);
262228

263229
p = json_out_contents(js->jout, &len);
264-
if (!write_all(replyfds[1], p, len))
230+
if (!write_all(replyfd, p, len))
265231
abort();
266232
exit(0);
267-
268-
parent_fail:
269-
if (taken(capacities))
270-
tal_free(capacities);
271-
return -1;
272233
}
273234

plugins/askrene/child/child.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#ifndef LIGHTNING_PLUGINS_ASKRENE_CHILD_CHILD_H
2+
#define LIGHTNING_PLUGINS_ASKRENE_CHILD_CHILD_H
3+
#include "config.h"
4+
#include <ccan/compiler/compiler.h>
5+
#include <ccan/short_types/short_types.h>
6+
#include <ccan/time/time.h>
7+
#include <common/amount.h>
8+
#include <common/fp16.h>
9+
#include <stdbool.h>
10+
11+
struct additional_cost_htable;
12+
struct gossmap;
13+
struct json_filter;
14+
struct layer;
15+
struct reserve_htable;
16+
17+
/* This is the child. Do the thing. */
18+
void run_child(const struct gossmap *gossmap,
19+
const struct layer **layers,
20+
const s8 *biases,
21+
const struct additional_cost_htable *additional_costs,
22+
struct reserve_htable *reserved,
23+
fp16_t *capacities TAKES,
24+
bool single_path,
25+
struct timemono deadline,
26+
const struct gossmap_node *srcnode,
27+
const struct gossmap_node *dstnode,
28+
struct amount_msat amount, struct amount_msat maxfee,
29+
u32 finalcltv, u32 maxdelay, size_t maxparts,
30+
const char *cmd_id,
31+
struct json_filter *cmd_filter,
32+
int reply_fd) NORETURN;
33+
34+
#endif /* LIGHTNING_PLUGINS_ASKRENE_CHILD_CHILD_H */
35+

plugins/askrene/child/entry.h

Lines changed: 0 additions & 34 deletions
This file was deleted.

0 commit comments

Comments
 (0)