Convert receivers to lopsub.
[paraslash.git] / sync_filter.c
index 8c3570f..82e86e9 100644 (file)
@@ -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.
         */