call[fs]cgi: Handle serialized child connections asynchronously. master
authorFredrik Tolf <fredrik@dolda2000.com>
Tue, 13 May 2025 01:16:55 +0000 (03:16 +0200)
committerFredrik Tolf <fredrik@dolda2000.com>
Tue, 13 May 2025 01:16:55 +0000 (03:16 +0200)
src/callfcgi.c
src/callscgi.c

index 8ff0eff..100788c 100644 (file)
@@ -246,14 +246,30 @@ static void startnolisten(void)
 static int sconnect(void)
 {
     int fd;
+    int err;
+    socklen_t errlen;
 
     fd = socket(cafamily, SOCK_STREAM, 0);
-    if(connect(fd, curaddr, caddrlen)) {
+    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
+    while(1) {
+       if(!connect(fd, curaddr, caddrlen))
+           return(fd);
+       if(errno == EAGAIN) {
+           block(-1, 0, 1);
+           continue;
+       }
+       if(errno == EINPROGRESS) {
+           block(fd, EV_WRITE, 30);
+           errlen = sizeof(err);
+           if(getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &errlen) || ((errno = err) != 0)) {
+               close(fd);
+               return(-1);
+           }
+           return(fd);
+       }
        close(fd);
        return(-1);
     }
-    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
-    return(fd);
 }
 
 static int econnect(void)
@@ -676,7 +692,6 @@ static void serve(struct muth *muth, va_list args)
     size_t read;
     char buf[8192];
     
-    sfd = reconn();
     is = mtstdopen(fd, 1, 60, "r+", NULL);
     os = mtstdopen(sfd, 1, 600, "r+", NULL);
     
@@ -730,7 +745,7 @@ out:
 static void listenloop(struct muth *muth, va_list args)
 {
     vavar(int, lfd);
-    int fd;
+    int fd, sfd;
     struct hthead *req;
     
     while(1) {
@@ -740,7 +755,12 @@ static void listenloop(struct muth *muth, va_list args)
                flog(LOG_ERR, "recvreq: %s", strerror(errno));
            break;
        }
-       mustart(serve, req, fd);
+       if((sfd = reconn()) < 0) {
+           close(fd);
+           freehthead(req);
+           continue;
+       }
+       mustart(serve, req, fd, sfd);
     }
 }
 
index ee46ac1..ef31c4c 100644 (file)
@@ -233,14 +233,30 @@ static void startnolisten(void)
 static int sconnect(void)
 {
     int fd;
+    int err;
+    socklen_t errlen;
 
     fd = socket(cafamily, SOCK_STREAM, 0);
-    if(connect(fd, curaddr, caddrlen)) {
+    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
+    while(1) {
+       if(!connect(fd, curaddr, caddrlen))
+           return(fd);
+       if(errno == EAGAIN) {
+           block(-1, 0, 1);
+           continue;
+       }
+       if(errno == EINPROGRESS) {
+           block(fd, EV_WRITE, 30);
+           errlen = sizeof(err);
+           if(getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &errlen) || ((errno = err) != 0)) {
+               close(fd);
+               return(-1);
+           }
+           return(fd);
+       }
        close(fd);
        return(-1);
     }
-    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
-    return(fd);
 }
 
 static int econnect(void)
@@ -507,7 +523,6 @@ static void serve(struct muth *muth, va_list args)
     struct charbuf head;
     struct hthead *resp;
     
-    sfd = reconn();
     is = mtstdopen(fd, 1, 60, "r+", NULL);
     os = mtstdopen(sfd, 1, 600, "r+", NULL);
     
@@ -537,7 +552,7 @@ out:
 static void listenloop(struct muth *muth, va_list args)
 {
     vavar(int, lfd);
-    int fd;
+    int fd, sfd;
     struct hthead *req;
     
     while(1) {
@@ -547,7 +562,12 @@ static void listenloop(struct muth *muth, va_list args)
                flog(LOG_ERR, "recvreq: %s", strerror(errno));
            break;
        }
-       mustart(serve, req, fd);
+       if((sfd = reconn()) < 0) {
+           close(fd);
+           freehthead(req);
+           continue;
+       }
+       mustart(serve, req, fd, sfd);
     }
 }