]> PatchyGit - patchyircd.git/commitdiff
recvProc: never block
authorEgor <egor@patchysicp.xyz>
Wed, 18 Oct 2023 18:55:29 +0000 (21:55 +0300)
committerEgor <egor@patchysicp.xyz>
Wed, 18 Oct 2023 18:58:10 +0000 (21:58 +0300)
common.h
main.c
net.c

index 2649905..3c5243b 100644 (file)
--- a/common.h
+++ b/common.h
@@ -51,6 +51,7 @@ struct client_data {
        time_t signon;
        time_t lastactivity;
        unsigned int caps;
+       char   want_write_for_read;
 };
 struct channel {
        char *key;
diff --git a/main.c b/main.c
index 3c13823..b7f1743 100644 (file)
--- a/main.c
+++ b/main.c
@@ -70,7 +70,7 @@ err:
 // Client linked list
 struct client_data *clients = NULL;
 // FDSET List
-fd_set readfds;
+fd_set readfds, writefds;
 
 FILE *fchanlog = NULL;
 
@@ -310,7 +310,8 @@ int main(int argc, char *argv[])
 
        // Main loop
        while(is_running){
-               FD_ZERO(&readfds); 
+               FD_ZERO(&readfds);
+               FD_ZERO(&writefds);
                // Add listening SOCKETS to FDSET
                for (int i = 0; i < listener_count; i++)
                        FD_SET(listeners[i].sock, &readfds);
@@ -318,8 +319,11 @@ int main(int argc, char *argv[])
                if (self_sock != INVALID_SOCKET)
                        FD_SET(self_sock, &readfds);
 #endif
-               for (struct client_data *cl = clients; cl; cl = cl->next)
+               for (struct client_data *cl = clients; cl; cl = cl->next) {
                        FD_SET(cl->FD, &readfds);
+                       if (cl->want_write_for_read)
+                               FD_SET(cl->FD, &writefds);
+               }
 
                // Set highestFD
 #ifdef _WIN32
@@ -334,7 +338,7 @@ int main(int argc, char *argv[])
                                highestFD = cl->FD;
 #endif
                // Wait until activity on sockets
-               if(select(highestFD+1,&readfds,NULL,NULL,NULL) == -1) {
+               if(select(highestFD+1,&readfds,&writefds,NULL,NULL) == -1) {
 #ifndef _WIN32
                        if (errno == EINTR)
                                continue;
@@ -356,7 +360,7 @@ int main(int argc, char *argv[])
                // Respond to already connected clients
                for (struct client_data *cl = clients; cl;) {
                        struct client_data *next = cl->next;
-                       if (FD_ISSET(cl->FD, &readfds))
+                       if (FD_ISSET(cl->FD, &readfds) || (cl->want_write_for_read && FD_ISSET(cl->FD, &writefds)))
                                recvProc(cl);
                        cl = next;
                }
diff --git a/net.c b/net.c
index e333c89..76c91e6 100644 (file)
--- a/net.c
+++ b/net.c
@@ -100,6 +100,7 @@ void recvProc(struct client_data *cl) {
        ssize_t bytesRead;
        char *x;
        int packetReturn;
+       cl->want_write_for_read = 0;
        while(1){
                // I hate you
                if(cl->bufLen == sizeof(cl->buf)) { killConnection(cl, false); return; }
@@ -118,9 +119,9 @@ void recvProc(struct client_data *cl) {
                                        return;
                                case TLS_WANT_POLLIN:
                                        return;
-                               case TLS_WANT_POLLOUT: // FIXME: this blocks
-                                       block(cl, 1);
-                                       continue;
+                               case TLS_WANT_POLLOUT:
+                                       cl->want_write_for_read = 1;
+                                       return;
                        }
                }
                else