X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=sync_filter.c;h=82e86e90cf50c4bf77faac44183286c536caab26;hp=fceb1d1cc8bbfe64c7aefe4eb9175d69560b14c8;hb=2b12fc963d15219721dd23eb7947bf516f2ad574;hpb=8aa9d0cddfefb882cfd8e7cadbeea5cce31b731f diff --git a/sync_filter.c b/sync_filter.c index fceb1d1c..82e86e90 100644 --- a/sync_filter.c +++ b/sync_filter.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Andre Noll + * Copyright (C) 2013 Andre Noll * * Licensed under the GPL v2. For licencing details see COPYING. */ @@ -34,7 +34,7 @@ struct sync_buddy_info { bool disabled; }; -/* per open/close data */ +/* One active buddy */ struct sync_buddy { int fd; struct sync_buddy_info *sbi; @@ -42,6 +42,7 @@ struct sync_buddy { struct list_head node; }; +/* Allocated in ->open() */ struct sync_filter_context { int listen_fd; struct list_head buddies; @@ -49,6 +50,7 @@ struct sync_filter_context { bool ping_sent; }; +/* Allocated and freed in ->parse_config() and ->free_config(). */ struct sync_filter_config { struct sync_filter_args_info *conf; struct sync_buddy_info *buddy_info; @@ -61,18 +63,17 @@ struct sync_filter_config { static void sync_close_buddy(struct sync_buddy *buddy) { - if (buddy->fd < 0) - return; - PARA_DEBUG_LOG("closing %s\n", buddy->sbi->url); + PARA_DEBUG_LOG("closing %s, fd %d\n", buddy->sbi->url, buddy->fd); close(buddy->fd); - buddy->fd = -1; + list_del(&buddy->node); + free(buddy); } static void sync_close_buddies(struct sync_filter_context *ctx) { - struct sync_buddy *buddy; + struct sync_buddy *buddy, *tmp; - FOR_EACH_BUDDY(buddy, &ctx->buddies) + FOR_EACH_BUDDY_SAFE(buddy, tmp, &ctx->buddies) sync_close_buddy(buddy); } @@ -170,6 +171,13 @@ fail: } } +/* + * At parse config time, we build an array of struct sync_buddy_info with one + * entry for each buddy given in the arguments. This array is not affected by + * sync_close(), so information stored there can be used for multiple instances + * (para_audiod). We store the resolved url and the ->disabled bit in this + * array. + */ static int sync_parse_config(int argc, char **argv, void **result) { int i, ret, n; @@ -222,7 +230,7 @@ fail: } /* - * True if we sent a packet to all budies and received a packet from each + * True if we sent a packet to all buddies and received a packet from each * enabled buddy. */ static bool sync_complete(struct sync_filter_context *ctx) @@ -244,6 +252,8 @@ static void sync_disable_active_buddies(struct sync_filter_context *ctx) FOR_EACH_BUDDY(buddy, &ctx->buddies) { if (buddy->sbi->disabled) continue; + if (buddy->ping_received == true) + continue; PARA_NOTICE_LOG("disabling %s\n", buddy->sbi->url); buddy->sbi->disabled = true; } @@ -328,11 +338,10 @@ static int sync_post_select(__a_unused struct sched *s, void *context) buddy->sbi->url, buddy->sbi->disabled? "disabled" : "enabled"); ret = xwrite(buddy->fd, &c, 1); - sync_close_buddy(buddy); if (ret < 0) { PARA_WARNING_LOG("failed to write to %s: %s\n", buddy->sbi->url, para_strerror(-ret)); - list_del(&buddy->node); + sync_close_buddy(buddy); } } ctx->ping_sent = true; @@ -361,14 +370,14 @@ static int sync_post_select(__a_unused struct sched *s, void *context) buddy->sbi->url); buddy->sbi->disabled = false; } - list_del(&buddy->node); + buddy->ping_received = true; } } if (!sync_complete(ctx)) return 1; /* * Although all enabled buddies are in sync we do not splice out - * ourselves immediately. We rather wait until the timout expires, + * ourselves immediately. We rather wait until the timeout expires, * or the buddy list has become empty. This opens a time window * for disabled buddies to become enabled by sending us a packet. */