chiark / gitweb /
fwd: Improve `source' and `target' lifecycle management.
[fwd] / socket.c
index a1a9a55026b6475f1a95045f374c200c5a19f1c8..36e58eac8c4c5b0b12892f8e8e605f44a2da6fa8 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -170,7 +170,7 @@ static void ssept_close(endpt *e)
 {
   ssept *ee = (ssept *)e;
 
-  if (ee->s->o.opt == SOCKOPT_LIMIT) {
+  if ((ee->s->s.f&SF_ACTIVE) && ee->s->o.opt == SOCKOPT_LIMIT) {
     ee->s->o.conn++;
     if (ee->s->o.conn == 1)
       ss_listen(ee->s);
@@ -351,6 +351,8 @@ static source *ssource_read(scanner *sc)
   (void)(conf_prefix(sc, "socket") || conf_prefix(sc, "sk"));
   ss = CREATE(ssource);
   ss->s.ops = &ssource_ops;
+  ss->s.ref = 1;
+  ss->s.f = 0;
   ss->s.desc = 0;
   ss->t = 0;
   ss->a = getaddr(sc, ADDR_SRC);
@@ -447,7 +449,7 @@ static void ss_accept(int fd, unsigned mode, void *p)
        close(ss->r.fd);
        if (ss->a->ops->unbind)
          ss->a->ops->unbind(ss->a);
-       ssource_destroy(&ss->s);
+       source_dec(&ss->s);
        acceptp = 0;
        break;
     }
@@ -511,7 +513,7 @@ fail_1:
   close(fd);
 fail_0:
   ss->o.conn = 0;
-  ssource_destroy(&ss->s);
+  source_dec(&ss->s);
 }
 
 /* --- @attach@ --- */
@@ -522,7 +524,7 @@ static void ssource_attach(source *s, scanner *sc, target *t)
   int fd;
   int opt = 1;
 
-  ss->t = t;
+  ss->t = t; target_inc(t);
 
   /* --- Initialize the description string --- */
 
@@ -563,9 +565,9 @@ static void ssource_attach(source *s, scanner *sc, target *t)
   fw_inc();
 }
 
-/* --- @destroy@ --- */
+/* --- @shutdown@ --- */
 
-static void ssource_destroy(source *s)
+static void ssource_shutdown(source *s)
 {
   ssource *ss = (ssource *)s;
 
@@ -579,10 +581,19 @@ static void ssource_destroy(source *s)
     ss->a->ops->freesrcopts(ss->ao);
   else
     DESTROY(ss->ao);
-  xfree(ss->s.desc);
   ss->a->ops->destroy(ss->a);
-  ss->t->ops->destroy(ss->t);
   source_remove(&ss->s);
+  target_dec(ss->t);
+  fw_dec();
+}
+
+/* --- @destroy@ --- */
+
+static void ssource_destroy(source *s)
+{
+  ssource *ss = (ssource *)s;
+
+  xfree(ss->s.desc);
   DESTROY(ss);
   fw_dec();
 }
@@ -591,7 +602,7 @@ static void ssource_destroy(source *s)
 
 source_ops ssource_ops = {
   "socket",
-  ssource_option, ssource_read, ssource_attach, ssource_destroy
+  ssource_option, ssource_read, ssource_attach, ssource_shutdown, ssource_destroy
 };
 
 /*----- Target definition -------------------------------------------------*/
@@ -627,6 +638,7 @@ static target *starget_read(scanner *sc)
   (void)(conf_prefix(sc, "socket") || conf_prefix(sc, "sk"));
   st = CREATE(starget);
   st->t.ops = &starget_ops;
+  st->t.ref = 1;
   st->a = getaddr(sc, ADDR_DEST);
   if (st->a->ops->inittargopts)
     st->ao = st->a->ops->inittargopts();