]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MEDIUM] got rid of event_{cli,srv}_write() in favor of stream_sock_write()
authorWilly Tarreau <willy@wtap.(none)>
Sat, 29 Jul 2006 17:01:31 +0000 (19:01 +0200)
committerWilly Tarreau <willy@wtap.(none)>
Sat, 29 Jul 2006 17:01:31 +0000 (19:01 +0200)
The timeouts, expiration timers and results are now stored in the buffers.
The timers will have to change a bit to become more flexible, and when the
I/O completion functions will be written, the connect_complete() will have
to be extracted from the write() function.

include/proto/stream_sock.h
src/backend.c
src/client.c
src/fd.c
src/stream_sock.c

index 9cd4a162d9ab853aacd8845a4ec6180e19d01cfb..5619e60dcacba4ba64346b407511f1377b408402 100644 (file)
 #include <common/config.h>
 
 
+/* main event functions used to move data between sockets and buffers */
 int stream_sock_read(int fd);
-
-/* FIXME: merge those ones together */
-int event_cli_write(int fd);
-int event_srv_write(int fd);
+int stream_sock_write(int fd);
 
 
 /* This either returns the sockname or the original destination address. Code
index 9c36b7b10efdb23dacc2f16ca21f118bcda2ee6d..cda40337ce2f38bd4328dede3efb164f6716d3c4 100644 (file)
@@ -429,7 +429,7 @@ int connect_server(struct session *s)
        fdtab[fd].state = FD_STCONN; /* connection in progress */
        fdtab[fd].cb[DIR_RD].f = &stream_sock_read;
        fdtab[fd].cb[DIR_RD].b = s->rep;
-       fdtab[fd].cb[DIR_WR].f = &event_srv_write;
+       fdtab[fd].cb[DIR_WR].f = &stream_sock_write;
        fdtab[fd].cb[DIR_WR].b = s->req;
     
        FD_SET(fd, StaticWriteEvent);  /* for connect status */
index f08149b62d1cae57c40d453b13a64b7f9d54f72b..c723ca1beb829a643ed97b1a482c1886d5580164 100644 (file)
@@ -340,7 +340,7 @@ int event_accept(int fd) {
                fdtab[cfd].state = FD_STREADY;
                fdtab[cfd].cb[DIR_RD].f = &stream_sock_read;
                fdtab[cfd].cb[DIR_RD].b = s->req;
-               fdtab[cfd].cb[DIR_WR].f = &event_cli_write;
+               fdtab[cfd].cb[DIR_WR].f = &stream_sock_write;
                fdtab[cfd].cb[DIR_WR].b = s->rep;
 
                if ((p->mode == PR_MODE_HTTP && (s->flags & SN_MONITOR)) ||
index bbf076d71acd74159bd0229c072f7fbc7d040008..66d963a4cb170cb5e8c5b8e44418786a21ba4178 100644 (file)
--- a/src/fd.c
+++ b/src/fd.c
  * - we still use 'listeners' to check whether we want to stop or not.
  * - the various pollers should be moved to other external files, possibly
  *   dynamic libs.
- * - stream_sock_read() : It may be called from event_accept().
- * - extract the connect code from event_srv_write()
- *   => event_tcp_connect(). It must then call event_write().
- * - merge the remaining event_cli_write() and event_srv_write()
- *   => single event_tcp_write(). Check buffer, fd_state, res*, and timeouts.
- *
  */
 
 #include <unistd.h>
index 99bf0bfd573b689b5a8fced330f106c636281f9c..cece0a2092eeeb51f624c7cdb4043ddf6015a25f 100644 (file)
@@ -144,21 +144,19 @@ int stream_sock_read(int fd) {
 
 
 /*
- * this function is called on a write event from a client socket.
+ * this function is called on a write event from a stream socket.
  * It returns 0.
  */
-int event_cli_write(int fd) {
-       struct task *t = fdtab[fd].owner;
+int stream_sock_write(int fd) {
        struct buffer *b = fdtab[fd].cb[DIR_WR].b;
        int ret, max;
 
 #ifdef DEBUG_FULL
-       fprintf(stderr,"event_cli_write : fd=%d, owner=%p\n", fd, fdtab[fd].owner);
+       fprintf(stderr,"stream_sock_write : fd=%d, owner=%p\n", fd, fdtab[fd].owner);
 #endif
 
        if (b->l == 0) { /* let's realign the buffer to optimize I/O */
                b->r = b->w = b->h = b->lr  = b->data;
-               //      max = BUFSIZE;          BUG !!!!
                max = 0;
        }
        else if (b->r > b->w) {
@@ -169,8 +167,24 @@ int event_cli_write(int fd) {
     
        if (fdtab[fd].state != FD_STERROR) {
                if (max == 0) {
+                       /* may be we have received a connection acknowledgement in TCP mode without data */
+                       if (fdtab[fd].state == FD_STCONN) {
+                               int skerr;
+                               socklen_t lskerr = sizeof(skerr);
+                               getsockopt(fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr);
+                               if (skerr) {
+                                       b->flags |= BF_WRITE_ERROR;
+                                       fdtab[fd].state = FD_STERROR;
+                                       task_wakeup(&rq, fdtab[fd].owner);
+                                       tv_eternity(&b->wex);
+                                       FD_CLR(fd, StaticWriteEvent);
+                                       return 0;
+                               }
+                       }
+
                        b->flags |= BF_WRITE_NULL;
-                       task_wakeup(&rq, t);
+                       task_wakeup(&rq, fdtab[fd].owner);
+                       fdtab[fd].state = FD_STREADY;
                        tv_eternity(&b->wex);
                        FD_CLR(fd, StaticWriteEvent);
                        return 0;
@@ -202,7 +216,7 @@ int event_cli_write(int fd) {
                        }
                }
                else if (ret == 0) {
-                       /* nothing written, just make as if we were never called */
+                       /* nothing written, just pretend we were never called */
                        // b->flags |= BF_WRITE_NULL;
                        return 0;
                }
@@ -229,125 +243,12 @@ int event_cli_write(int fd) {
        else
                tv_eternity(&b->wex);
 
-       task_wakeup(&rq, t);
+       task_wakeup(&rq, fdtab[fd].owner);
        return 0;
 }
 
 
 
-
-/*
- * this function is called on a write event from a server socket.
- * It returns 0.
- */
-int event_srv_write(int fd) {
-    struct task *t = fdtab[fd].owner;
-    struct buffer *b = fdtab[fd].cb[DIR_WR].b;
-    struct session *s = t->context;
-    int ret, max;
-
-#ifdef DEBUG_FULL
-    fprintf(stderr,"event_srv_write : fd=%d, s=%p\n", fd, s);
-#endif
-
-    if (b->l == 0) { /* let's realign the buffer to optimize I/O */
-       b->r = b->w = b->h = b->lr = b->data;
-       //      max = BUFSIZE;          BUG !!!!
-       max = 0;
-    }
-    else if (b->r > b->w) {
-       max = b->r - b->w;
-    }
-    else
-       max = b->data + BUFSIZE - b->w;
-    
-    if (fdtab[fd].state != FD_STERROR) {
-       if (max == 0) {
-           /* may be we have received a connection acknowledgement in TCP mode without data */
-           if (s->srv_state == SV_STCONN) {
-               int skerr;
-               socklen_t lskerr = sizeof(skerr);
-               getsockopt(fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr);
-               if (skerr) {
-                   b->flags |= BF_WRITE_ERROR;
-                   fdtab[fd].state = FD_STERROR;
-                   task_wakeup(&rq, t);
-                   tv_eternity(&b->wex);
-                   FD_CLR(fd, StaticWriteEvent);
-                   return 0;
-               }
-           }
-
-           b->flags |= BF_WRITE_NULL;
-           task_wakeup(&rq, t);
-           fdtab[fd].state = FD_STREADY;
-           tv_eternity(&b->wex);
-           FD_CLR(fd, StaticWriteEvent);
-           return 0;
-       }
-
-#ifndef MSG_NOSIGNAL
-       {
-           int skerr;
-           socklen_t lskerr = sizeof(skerr);
-           getsockopt(fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr);
-           if (skerr)
-               ret = -1;
-           else
-               ret = send(fd, b->w, max, MSG_DONTWAIT);
-       }
-#else
-       ret = send(fd, b->w, max, MSG_DONTWAIT | MSG_NOSIGNAL);
-#endif
-       fdtab[fd].state = FD_STREADY;
-       if (ret > 0) {
-           b->l -= ret;
-           b->w += ret;
-           
-           b->flags |= BF_PARTIAL_WRITE;
-           
-           if (b->w == b->data + BUFSIZE) {
-               b->w = b->data; /* wrap around the buffer */
-           }
-       }
-       else if (ret == 0) {
-           /* nothing written, just make as if we were never called */
-           // b->flags |= BF_WRITE_NULL;
-           return 0;
-       }
-       else if (errno == EAGAIN) /* ignore EAGAIN */
-           return 0;
-       else {
-           b->flags |= BF_WRITE_ERROR;
-           fdtab[fd].state = FD_STERROR;
-       }
-    }
-    else {
-        b->flags |= BF_WRITE_ERROR;
-       fdtab[fd].state = FD_STERROR;
-    }
-
-    /* We don't want to re-arm read/write timeouts if we're trying to connect,
-     * otherwise it could loop indefinitely !
-     */
-    if (s->srv_state != SV_STCONN) {
-       if (b->wto) {
-               tv_delayfrom(&b->wex, &now, b->wto);
-               /* FIXME: to prevent the client from expiring read timeouts during writes,
-                * we refresh it. A solution would be to merge read+write timeouts into a
-                * unique one, although that needs some study particularly on full-duplex
-                * TCP connections. */
-               b->rex = b->wex;
-       }
-       else
-               tv_eternity(&b->wex);
-    }
-
-    task_wakeup(&rq, t);
-    return 0;
-}
-
-
 /*
  * Local variables:
  *  c-indent-level: 8