summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorChia-I Wu <olvaffe@gmail.com>2021-12-21 15:52:11 -0800
committerChia-I Wu <olvaffe@gmail.com>2022-01-07 14:10:21 -0800
commite6ec33dd87d5d0839ef9ecaf838a886f8142bf27 (patch)
tree5c7ed89e3050f4c05a2b9f65419b371a4ef73491 /server
parent72cc20303f4108b2c99246d23e787262dec8032e (diff)
server: destroy context records soon after fork
Add render_client_detach_all_records to "detach" context records from the child process before returning from render_client_create_context. "Detaching" means destroying records without killing nor reaping the workers. This makes it clearer how context records are destroyed in subprocesses. Signed-off-by: Chia-I Wu <olvaffe@gmail.com> Reviewed-by: Yiwei Zhang <zzyiwei@chromium.org> Reviewed-by: Ryan Neph <ryanneph@google.com>
Diffstat (limited to 'server')
-rw-r--r--server/render_client.c41
1 files changed, 26 insertions, 15 deletions
diff --git a/server/render_client.c b/server/render_client.c
index 36cfbdd..ee75095 100644
--- a/server/render_client.c
+++ b/server/render_client.c
@@ -43,6 +43,24 @@ render_client_find_record(struct render_client *client, uint32_t ctx_id)
}
static void
+render_client_detach_all_records(struct render_client *client)
+{
+ struct render_server *srv = client->server;
+
+ /* destroy all records without killing nor reaping */
+ list_splicetail(&client->context_records, &client->reap_records);
+ list_for_each_entry_safe (struct render_context_record, rec, &client->reap_records,
+ head) {
+ render_worker_destroy(rec->worker);
+ free(rec);
+ srv->current_worker_count--;
+ }
+
+ list_inithead(&client->context_records);
+ list_inithead(&client->reap_records);
+}
+
+static void
render_client_kill_one_record(struct render_client *client,
struct render_context_record *rec)
{
@@ -151,14 +169,17 @@ render_client_create_context(struct render_client *client,
return false;
}
+ rec->ctx_id = req->ctx_id;
+ list_addtail(&rec->head, &client->context_records);
+ srv->current_worker_count++;
+
if (!render_worker_is_record(rec->worker)) {
/* this is the child process */
- render_worker_destroy(rec->worker);
- free(rec);
-
srv->state = RENDER_SERVER_STATE_SUBPROCESS;
*srv->context_args = ctx_args;
+ render_client_detach_all_records(client);
+
/* ctx_fd ownership transferred */
assert(srv->context_args->ctx_fd == ctx_fd);
@@ -169,10 +190,6 @@ render_client_create_context(struct render_client *client,
}
/* this is the parent process */
- rec->ctx_id = req->ctx_id;
- list_addtail(&rec->head, &client->context_records);
- srv->current_worker_count++;
-
if (ctx_fd >= 0)
close(ctx_fd);
*out_remote_fd = remote_fd;
@@ -312,14 +329,8 @@ render_client_destroy(struct render_client *client)
struct render_server *srv = client->server;
if (srv->state == RENDER_SERVER_STATE_SUBPROCESS) {
- /* destroy all records without killing nor reaping */
- list_splicetail(&client->context_records, &client->reap_records);
- list_for_each_entry_safe (struct render_context_record, rec, &client->reap_records,
- head) {
- render_worker_destroy(rec->worker);
- free(rec);
- srv->current_worker_count--;
- }
+ assert(list_is_empty(&client->context_records) &&
+ list_is_empty(&client->reap_records));
} else {
render_client_kill_all_records(client);
render_client_reap_all_records(client, true /* wait */);