fix wrong kqueue usage: split ws events into multiple kevent filters webdav

Thu, 03 Dec 2020 12:38:46 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 03 Dec 2020 12:38:46 +0100
branch
webdav
changeset 265
59f99038a576
parent 264
81f202caea5b
child 266
783467806e2d

fix wrong kqueue usage: split ws events into multiple kevent filters

src/server/daemon/event_bsd.c file | annotate | diff | comparison | revisions
--- a/src/server/daemon/event_bsd.c	Thu Dec 03 11:47:49 2020 +0100
+++ b/src/server/daemon/event_bsd.c	Thu Dec 03 12:38:46 2020 +0100
@@ -67,7 +67,7 @@
     timeout.tv_sec = 600;
     
     struct kevent events[64];
-    struct kevent changes[64];
+    struct kevent changes[128];
     int numchanges = 0;
     
     for(;;) {
@@ -75,7 +75,7 @@
         int nev = kevent(ev->kqueue, changes, numchanges, events, 64, &timeout);  
         if(nev == -1) {
             // TODO: check for error
-            perror("kevent");
+            log_ereport(LOG_FAILURE, "kevent: %s", strerror(errno));
             continue;
         }
         
@@ -88,25 +88,29 @@
             }
             
             if(event->fn) {
-                u_short kev_flag = 0;
                 int saved_ev = event->events;
                 if(!event->fn(ev, event)) {
                     // ret 0 => remove event
-                    kev_flag = EV_DELETE;     
+                    
                     if(event->finish) {
                         event->finish(ev, event);
                     }
-                } else if(saved_ev != event->events) {
-                    // events changed
-                    kev_flag = EV_ADD;
-                    events[i].filter = ev_convert2sys_events(event->events);
+                    
+                    event->events = 0;
                 }
                 
-                if(kev_flag) {
-                    // copy current event to changelist
-                    changes[numchanges] = events[i];
-                    changes[numchanges].flags = kev_flag;
-                    numchanges++;
+                // if events have changed, we need to add/remove filters
+                if(saved_ev != event->events) {
+                    int e = event->events;
+                    int e_fd = events[i].ident;
+                    if((e & EVENT_POLLIN) != (saved_ev & EVENT_POLLIN)) {
+                        int f = (e & EVENT_POLLIN) == EVENT_POLLIN ? EV_ADD : EV_DELETE;
+                        EV_SET(&changes[numchanges++], e_fd, EVFILT_READ, f, 0, 0, event);
+                    }
+                    if((e & EVENT_POLLOUT) != (saved_ev & EVENT_POLLOUT)) {
+                        int f = (e & EVENT_POLLOUT) == EVENT_POLLOUT ? EV_ADD : EV_DELETE;
+                        EV_SET(&changes[numchanges++], e_fd, EVFILT_WRITE, f, 0, 0, event);
+                    }
                 }
             }
         }

mercurial