From aa234b7afe223879a7bd7274ce05a3a315a2ec49 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Tue, 5 Jan 2010 03:50:07 +0100 Subject: [PATCH] [btr] Split btr_del_node() into two functions. Also, close filter/receiver nodes in filter.c/recv.c instead of in each post_select(). --- aacdec_filter.c | 3 +-- amp_filter.c | 3 +-- buffer_tree.c | 16 ++++++++++------ buffer_tree.h | 3 ++- compress_filter.c | 3 +-- error.h | 2 +- filter.c | 21 ++++++++++++++++++--- http_recv.c | 5 +---- mp3dec_filter.c | 4 ++-- oggdec_filter.c | 3 +-- recv.c | 2 ++ stdin.c | 9 +-------- stdout.c | 4 ++-- wav_filter.c | 3 +-- wmadec_filter.c | 3 +-- write.c | 4 ++-- 16 files changed, 47 insertions(+), 41 deletions(-) diff --git a/aacdec_filter.c b/aacdec_filter.c index ad1c06a0..602df63e 100644 --- a/aacdec_filter.c +++ b/aacdec_filter.c @@ -326,9 +326,8 @@ out: } err: assert(ret < 0); - aacdec_close(fn); t->error = ret; - btr_del_node(btrn); + btr_remove_node(btrn); } /** diff --git a/amp_filter.c b/amp_filter.c index 10122464..3154735e 100644 --- a/amp_filter.c +++ b/amp_filter.c @@ -153,8 +153,7 @@ next_buffer: err: assert(ret < 0); t->error = ret; - btr_del_node(btrn); - amp_close(fn); + btr_remove_node(btrn); } /** diff --git a/buffer_tree.c b/buffer_tree.c index 3b001541..022a4118 100644 --- a/buffer_tree.c +++ b/buffer_tree.c @@ -216,20 +216,26 @@ static void flush_input_queue(struct btr_node *btrn) btr_drop_buffer_reference(br); } -void btr_del_node(struct btr_node *btrn) +void btr_free_node(struct btr_node *btrn) +{ + if (!btrn) + return; + free(btrn->name); + free(btrn); +} + +void btr_remove_node(struct btr_node *btrn) { struct btr_node *ch; if (!btrn) return; - PARA_NOTICE_LOG("deleting %s\n", btrn->name); + PARA_NOTICE_LOG("removing btr node %s from buffer tree\n", btrn->name); FOR_EACH_CHILD(ch, btrn) ch->parent = NULL; flush_input_queue(btrn); if (btrn->parent) list_del(&btrn->node); - free(btrn->name); - free(btrn); } size_t btr_get_input_queue_size(struct btr_node *btrn) @@ -261,8 +267,6 @@ void btr_splice_out_node(struct btr_node *btrn) list_move(&ch->node, &btrn->parent->children); } assert(list_empty(&btrn->children)); - free(btrn->name); - free(btrn); } /** diff --git a/buffer_tree.h b/buffer_tree.h index a95d1671..d02eefc6 100644 --- a/buffer_tree.h +++ b/buffer_tree.h @@ -6,7 +6,8 @@ typedef int (*btr_command_handler)(struct btr_node *btrn, struct btr_node *btr_new_node(const char *name, struct btr_node *parent, btr_command_handler handler, void *context); -void btr_del_node(struct btr_node *btrn); +void btr_remove_node(struct btr_node *btrn); +void btr_free_node(struct btr_node *btrn); void btr_add_output(char *buf, size_t size, struct btr_node *btrn); bool btr_no_children(struct btr_node *btrn); size_t btr_bytes_pending(struct btr_node *btrn); diff --git a/compress_filter.c b/compress_filter.c index 142ad899..7c392746 100644 --- a/compress_filter.c +++ b/compress_filter.c @@ -150,9 +150,8 @@ next_buffer: goto next_buffer; err: assert(ret < 0); - close_compress(fn); t->error = ret; - btr_del_node(btrn); + btr_remove_node(btrn); } /** TODO: Add sanity checks */ diff --git a/error.h b/error.h index 739eb6c1..5854dd37 100644 --- a/error.h +++ b/error.h @@ -41,7 +41,7 @@ extern const char **para_errlist[]; PARA_ERROR(BTR_EOF, "buffer tree: end of file"), \ #define STDOUT_ERRORS \ - PARA_ERROR(ORPHAN, "orphaned (EOF)"), \ + PARA_ERROR(STDOUT_EOF, "stdout: end of file"), \ #define BITSTREAM_ERRORS \ diff --git a/filter.c b/filter.c index ed8cde41..832ca22b 100644 --- a/filter.c +++ b/filter.c @@ -161,19 +161,22 @@ static int __noreturn main_btr(void) int i, ret; struct filter *f; struct btr_node *parent; + struct filter_node **fns; sit->btrn = btr_new_node("stdin", NULL, NULL, NULL); stdin_set_defaults(sit); register_task(&sit->task); + fns = para_malloc(conf.filter_given * sizeof(*fns)); for (i = 0, parent = sit->btrn; i < conf.filter_given; i++) { char *fa = conf.filter_arg[i]; - struct filter_node *fn = para_calloc(sizeof(*fn)); + struct filter_node *fn; + fn = fns[i] = para_calloc(sizeof(*fn)); ret = check_filter_arg(fa, &fn->conf); if (ret < 0) { free(fn); - goto err; + goto out; } fn->filter_num = ret; f = filters + fn->filter_num; @@ -194,7 +197,19 @@ static int __noreturn main_btr(void) s.default_timeout.tv_usec = 0; btr_log_tree(sit->btrn, LL_INFO); ret = schedule(&s); -err: +out: + for (i--; i >= 0; i--) { + struct filter_node *fn = fns[i]; + + f = filters + fn->filter_num; + f->close(fn); + btr_free_node(fn->btrn); + free(fn->conf); + free(fn); + } + free(fns); + btr_free_node(sit->btrn); + btr_free_node(sot->btrn); if (ret < 0) PARA_EMERG_LOG("%s\n", para_strerror(-ret)); exit(ret < 0? EXIT_FAILURE : EXIT_SUCCESS); diff --git a/http_recv.c b/http_recv.c index cf93076d..8f4ca2b5 100644 --- a/http_recv.c +++ b/http_recv.c @@ -168,7 +168,7 @@ static void http_recv_post_select(struct sched *s, struct task *t) return; err: if (conf->buffer_tree_given) { - btr_del_node(rn->btrn); + btr_remove_node(rn->btrn); rn->btrn = NULL; } } @@ -176,10 +176,7 @@ err: static void http_recv_close(struct receiver_node *rn) { struct private_http_recv_data *phd = rn->private_data; - struct http_recv_args_info *conf = rn->conf; - if (conf->buffer_tree_given) - btr_del_node(rn->btrn); close(phd->fd); free(rn->buf); free(rn->private_data); diff --git a/mp3dec_filter.c b/mp3dec_filter.c index a6a628ec..2383fba6 100644 --- a/mp3dec_filter.c +++ b/mp3dec_filter.c @@ -179,6 +179,7 @@ static void mp3dec_close(struct filter_node *fn) free(fn->buf); fn->buf = NULL; + mp3dec_cmdline_parser_free(fn->conf); free(pmd); fn->private_data = NULL; } @@ -257,9 +258,8 @@ next_frame: goto next_frame; err: assert(ret < 0); - mp3dec_close(fn); t->error = ret; - btr_del_node(btrn); + btr_remove_node(btrn); } static void mp3dec_open(struct filter_node *fn) diff --git a/oggdec_filter.c b/oggdec_filter.c index 34a04dbc..956af852 100644 --- a/oggdec_filter.c +++ b/oggdec_filter.c @@ -260,9 +260,8 @@ static void ogg_post_select(__a_unused struct sched *s, struct task *t) err: assert(ret < 0); - ogg_close(fn); t->error = ret; - btr_del_node(btrn); + btr_remove_node(btrn); } static ssize_t ogg_convert(char *inbuffer, size_t len, struct filter_node *fn) diff --git a/recv.c b/recv.c index 6f05c47f..c8edb593 100644 --- a/recv.c +++ b/recv.c @@ -113,6 +113,8 @@ int main(int argc, char *argv[]) ret = schedule(&s); out: + if (conf.buffer_tree_given) + btr_free_node(sot.btrn); if (r_opened) r->close(&rn); if (r) diff --git a/stdin.c b/stdin.c index c8ee808f..079865f7 100644 --- a/stdin.c +++ b/stdin.c @@ -52,12 +52,6 @@ static void stdin_pre_select_btr(struct sched *s, struct task *t) { struct stdin_task *sit = container_of(t, struct stdin_task, task); - if (btr_no_children(sit->btrn)) { /* TODO: defer node deletion to post select */ - t->error = -E_STDIN_NO_CHILD; - btr_del_node(sit->btrn); - sit->btrn = NULL; - return; - } t->error = 0; if (btr_bytes_pending(sit->btrn) > STDIN_MAX_PENDING) sit->check_fd = 0; @@ -131,8 +125,7 @@ static void stdin_post_select_btr(struct sched *s, struct task *t) return; err: free(buf); - btr_del_node(sit->btrn); - sit->btrn = NULL; + btr_remove_node(sit->btrn); } /** diff --git a/stdout.c b/stdout.c index d167cd14..bf4a923d 100644 --- a/stdout.c +++ b/stdout.c @@ -107,7 +107,7 @@ static void stdout_post_select_btr(struct sched *s, struct task *t) t->error = 0; if (!sot->check_fd) { if (sz == 0 && btr_no_parent(sot->btrn)) { - t->error = -E_ORPHAN; + t->error = -E_STDOUT_EOF; goto err; } return; @@ -125,7 +125,7 @@ static void stdout_post_select_btr(struct sched *s, struct task *t) btr_consume(sot->btrn, ret); return; err: - btr_del_node(sot->btrn); + btr_remove_node(sot->btrn); } /** * Initialize a stdout task structure with default values. diff --git a/wav_filter.c b/wav_filter.c index 91d87e7a..1acbfde6 100644 --- a/wav_filter.c +++ b/wav_filter.c @@ -150,11 +150,10 @@ static void wav_post_select(__a_unused struct sched *s, struct task *t) ret = -E_WAV_SUCCESS; err: t->error = ret; - wav_close(fn); if (ret == -E_WAV_SUCCESS) btr_splice_out_node(btrn); else { - btr_del_node(btrn); + btr_remove_node(btrn); PARA_ERROR_LOG("%s\n", para_strerror(-ret)); } } diff --git a/wmadec_filter.c b/wmadec_filter.c index d214b421..8d6af40b 100644 --- a/wmadec_filter.c +++ b/wmadec_filter.c @@ -1282,9 +1282,8 @@ success: goto next_buffer; err: assert(ret < 0); - wmadec_close(fn); t->error = ret; - btr_del_node(btrn); + btr_remove_node(btrn); } static ssize_t wmadec_convert(char *inbuffer, size_t len, diff --git a/write.c b/write.c index 9577f040..f79daf23 100644 --- a/write.c +++ b/write.c @@ -194,7 +194,7 @@ out: } err: if (t->error < 0) - btr_del_node(cwt->btrn); + btr_remove_node(cwt->btrn); } static void initial_delay_pre_select(struct sched *s, struct task *t) @@ -326,7 +326,7 @@ out: struct writer *w = writers + wn->writer_num; w->close(wn); - btr_del_node(wn->btrn); + btr_free_node(wn->btrn); free(wn->conf); free(wn); } -- 2.39.5