]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] stream-interface: add a ->release callback
authorWilly Tarreau <w@1wt.eu>
Fri, 2 Jul 2010 09:18:03 +0000 (11:18 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 13 Jul 2010 14:06:23 +0000 (16:06 +0200)
When a connection is closed on a stream interface, some iohandlers
will need to be informed in order to release some resources. This
normally happens upon a shutr+shutw. It is the equivalent of the
fd_delete() call which is done for real sockets, except that this
time we release internal resources.

It can also be used with real sockets because it does not cost
anything else and might one day be useful.

include/types/stream_interface.h
src/session.c
src/stream_interface.c
src/stream_sock.c

index db166c9b24cddb4d81d10eeb499959d4758e87f8..cfba687351a8d2004dcfa65b9be68cd1831fc2ef 100644 (file)
@@ -100,6 +100,7 @@ struct stream_interface {
        void (*chk_snd)(struct stream_interface *);/* chk_snd function */
        int (*connect)(struct stream_interface *, struct proxy *, struct server *,
                       struct sockaddr *, struct sockaddr *); /* connect function if any */
+       void (*release)(struct stream_interface *); /* handler to call after the last close() */
        void (*iohandler)(struct stream_interface *);  /* internal I/O handler when embedded */
        struct buffer *ib, *ob; /* input and output buffers */
        int conn_retries;       /* number of connect retries left */
index 556fffefcbf5986a8fa68ad3a6c34d647647dee8..10c7f13d613a52576ca1a3a2f135717d01e1ebc6 100644 (file)
@@ -139,6 +139,7 @@ int session_accept(struct listener *l, int cfd, struct sockaddr_storage *addr)
        s->si[0].err_loc   = NULL;
        s->si[0].connect   = NULL;
        s->si[0].iohandler = NULL;
+       s->si[0].release   = NULL;
        s->si[0].exp       = TICK_ETERNITY;
        s->si[0].flags     = SI_FL_NONE;
 
@@ -161,6 +162,7 @@ int session_accept(struct listener *l, int cfd, struct sockaddr_storage *addr)
        s->si[1].err_loc   = NULL;
        s->si[1].connect   = NULL;
        s->si[1].iohandler = NULL;
+       s->si[1].release   = NULL;
        s->si[1].shutr     = stream_int_shutr;
        s->si[1].shutw     = stream_int_shutw;
        s->si[1].exp       = TICK_ETERNITY;
@@ -434,6 +436,9 @@ int sess_update_st_con_tcp(struct session *s, struct stream_interface *si)
                si->flags &= ~SI_FL_CAP_SPLICE;
                fd_delete(si->fd);
 
+               if (si->release)
+                       si->release(si);
+
                if (si->err_type)
                        return 0;
 
index c45abdbe829b98d640ff0b2e70d3b886f6e3bf6f..113f01c65d032a8cb3c3b4e3b92ea143afddd7c3 100644 (file)
@@ -178,6 +178,9 @@ void stream_int_shutr(struct stream_interface *si)
                si->exp = TICK_ETERNITY;
        }
 
+       if (si->release)
+               si->release(si);
+
        /* note that if the task exist, it must unregister itself once it runs */
        if (!(si->flags & SI_FL_DONT_WAKE) && si->owner)
                task_wakeup(si->owner, TASK_WOKEN_IO);
@@ -214,6 +217,9 @@ void stream_int_shutw(struct stream_interface *si)
                si->exp = TICK_ETERNITY;
        }
 
+       if (si->release)
+               si->release(si);
+
        /* note that if the task exist, it must unregister itself once it runs */
        if (!(si->flags & SI_FL_DONT_WAKE) && si->owner)
                task_wakeup(si->owner, TASK_WOKEN_IO);
@@ -289,6 +295,7 @@ struct task *stream_int_register_handler(struct stream_interface *si,
        si->chk_snd = stream_int_chk_snd;
        si->connect = NULL;
        si->iohandler = fct;
+       si->release   = NULL;
        si->flags |= SI_FL_WAIT_DATA;
        return si->owner;
 }
@@ -312,6 +319,7 @@ struct task *stream_int_register_handler_task(struct stream_interface *si,
        si->chk_snd = stream_int_chk_snd;
        si->connect = NULL;
        si->iohandler = NULL; /* not used when running as an external task */
+       si->release   = NULL;
        si->flags |= SI_FL_WAIT_DATA;
 
        t = task_new();
@@ -337,6 +345,7 @@ void stream_int_unregister_handler(struct stream_interface *si)
                task_free(si->owner);
        }
        si->iohandler = NULL;
+       si->release   = NULL;
        si->owner = NULL;
 }
 
index 2d5ef6d704cd1f1af9838ad27cb4700d6ec2c511..8cd721ea7ef1e8597ecea019887ed6e9ff3ce620 100644 (file)
@@ -875,6 +875,9 @@ void stream_sock_shutw(struct stream_interface *si)
                si->exp = TICK_ETERNITY;
                return;
        }
+
+       if (si->release)
+               si->release(si);
 }
 
 /*
@@ -899,6 +902,9 @@ void stream_sock_shutr(struct stream_interface *si)
                fd_delete(si->fd);
                si->state = SI_ST_DIS;
                si->exp = TICK_ETERNITY;
+
+               if (si->release)
+                       si->release(si);
                return;
        }
        EV_FD_CLR(si->fd, DIR_RD);