]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
tvhpoll: Fixed tvhpoll_add kqueue implementation.
authormacrule <562520+macrule@users.noreply.github.com>
Wed, 29 Nov 2017 17:18:53 +0000 (18:18 +0100)
committerJaroslav Kysela <perex@perex.cz>
Wed, 29 Nov 2017 19:55:06 +0000 (20:55 +0100)
The semantics of tvhpoll_add() in the epoll implementation is to set exactly the specified filters, and not add to any previously added ones. The kqueue implementation only added filters, and never removed those that were not set anymore.

This caused busy-polling in satip_frontend on FreeBSD and Darwin, because tvhpoll_wait() always returned immediately. This happened because the receiving socket was always ready to accept data for writing. The following recv() call was called repeatedly without any delay and caused high CPU utilization.

src/tvhpoll.c

index a12dcfd07b23cff4aa334a24e4e3e6a1bbc49086..7d7116d67c974323a92317920f9a8df8b034d7f7 100644 (file)
@@ -131,6 +131,9 @@ int tvhpoll_add
            evs[i].fd, rc);
         return -1;
       }
+    } else {
+      EV_SET(tp->ev+i, evs[i].fd, EVFILT_WRITE,  EV_DELETE, 0, 0, NULL);
+      kevent(tp->fd, tp->ev+i, 1, NULL, 0, NULL);
     }
     if (evs[i].events & TVHPOLL_IN){
       EV_SET(tp->ev+i, evs[i].fd, EVFILT_READ, EV_ADD, 0, 0, (intptr_t*)evs[i].data.u64);
@@ -139,6 +142,9 @@ int tvhpoll_add
         tvherror(LS_TVHPOLL, "failed to add kqueue READ filter [%d|%d]", evs[i].fd, rc);
         return -1;
       }
+    } else {
+      EV_SET(tp->ev+i, evs[i].fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
+      kevent(tp->fd, tp->ev+i, 1, NULL, 0, NULL);
     }
   }
   return 0;